User prompt
ekrandan çıkmasına gerek yoktu benim belirlediğim yere gelince kaybolmasını istemiştim ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
yazı sona gelince bir anda hızlanıyor ben bunu istemedim sona gelince harf harf yok olsun baştan başlasın gibi demek istedim ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
bu yazının başlangıç ve bitiş yerlerinide ayarladım ancak bittiği yerde yavaş yavaş ekrandan gitmeli ve tekrar baştan gelmeli sanki sınırsız bir döngü gibi göstermek istiyorum. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (5 edits merged)
Please save this source code
User prompt
yerleşimi manuel olarak yaptım ama kayarak yazmıyor sabir duruyor.
Code edit (1 edits merged)
Please save this source code
User prompt
şuanda çok aşağıda biraz daha fazla yukarı alalım
User prompt
yazıyı dahada yukarı alalım
User prompt
yazıyı daha da yukarı alalım ayrıca yazı kayma efekti durdu onuda kontrol edelim. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
çok aşağıya geldi yazı yukarı alalım biraz
User prompt
double tap shpis to rotate gibi bilgilerin verildiği kısım biraz daha aşşağıya alınmalı ve monitör assettinin önünde yazmalı ayrıca kayan yazı şeklince gözükmeli. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
waves sesi intodan sonra başlasın
User prompt
radardaki yeşil çubuk saat yönünde dönmeli ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
oyun alanı monitörün assetinin içine sığacak şekilde olmalı. Radar çemberi çalışıyor gibi gözükmeli. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var DraggableShip = Container.expand(function (length, id) { var self = Container.call(this); self.length = length; self.shipId = id; self.isHorizontal = true; self.isBeingDragged = false; self.isPlaced = false; self.shipCells = []; self.smallScale = 0.5; // Scale for when ship is waiting // Create visual representation of ship for (var i = 0; i < length; i++) { var shipCell = self.attachAsset('ship', { anchorX: 0, anchorY: 0 }); shipCell.x = i * CELL_SIZE; shipCell.y = 0; self.shipCells.push(shipCell); } // Start ships at smaller scale self.scaleX = self.smallScale; self.scaleY = self.smallScale; self.rotate = function () { self.isHorizontal = !self.isHorizontal; for (var i = 0; i < self.shipCells.length; i++) { if (self.isHorizontal) { self.shipCells[i].x = i * CELL_SIZE; self.shipCells[i].y = 0; } else { self.shipCells[i].x = 0; self.shipCells[i].y = i * CELL_SIZE; } } }; self.canBePlacedAt = function (gridX, gridY) { for (var i = 0; i < self.length; i++) { var x = self.isHorizontal ? gridX + i : gridX; var y = self.isHorizontal ? gridY : gridY + i; if (x >= GRID_SIZE || y >= GRID_SIZE || x < 0 || y < 0) { return false; } if (playerGrid[x][y].hasShip) { return false; } } return true; }; self.placeOnGrid = function (gridX, gridY) { if (self.canBePlacedAt(gridX, gridY)) { for (var i = 0; i < self.length; i++) { var x = self.isHorizontal ? gridX + i : gridX; var y = self.isHorizontal ? gridY : gridY + i; playerGrid[x][y].setShip(self.shipId); } self.isPlaced = true; self.visible = false; return true; } return false; }; self.down = function (x, y, obj) { if (gameState === 'placement') { if (self.isPlaced) { // Remove ship from grid for repositioning removeShipFromGrid(self); self.isPlaced = false; self.visible = true; placedShipsCount--; statusText.setText('Place remaining ships (' + (shipLengths.length - placedShipsCount) + ' left)'); startButton.visible = false; // Position ship at current grid location for smooth dragging var currentGridX = -1, currentGridY = -1; for (var gx = 0; gx < GRID_SIZE; gx++) { for (var gy = 0; gy < GRID_SIZE; gy++) { if (playerGrid[gx][gy].shipId === self.shipId) { currentGridX = gx; currentGridY = gy; break; } } if (currentGridX !== -1) { break; } } if (currentGridX !== -1) { self.x = CENTER_GRID_X + currentGridX * CELL_SIZE; self.y = CENTER_GRID_Y + currentGridY * CELL_SIZE; } } self.isBeingDragged = true; draggedShip = self; // Scale up to full size when dragging tween(self, { alpha: 0.7, scaleX: 1, scaleY: 1 }, { duration: 200 }); } }; self.up = function (x, y, obj) { if (self.isBeingDragged && !self.isPlaced) { self.isBeingDragged = false; // Try to place ship on grid with better snapping var gridX = Math.round((self.x - CENTER_GRID_X) / CELL_SIZE); var gridY = Math.round((self.y - CENTER_GRID_Y) / CELL_SIZE); // Snap to grid position var snapX = CENTER_GRID_X + gridX * CELL_SIZE; var snapY = CENTER_GRID_Y + gridY * CELL_SIZE; if (self.placeOnGrid(gridX, gridY)) { // Snap ship to exact grid position before hiding self.x = snapX; self.y = snapY; tween(self, { alpha: 1 }, { duration: 200 }); placedShipsCount++; if (placedShipsCount >= shipLengths.length) { statusText.setText('All ships placed! Press START GAME to begin'); startButton.visible = true; } else { statusText.setText('Place remaining ships (' + (shipLengths.length - placedShipsCount) + ' left)'); } } else { // Return to original position and scale down if can't place tween(self, { x: self.originalX, y: self.originalY, alpha: 1, scaleX: self.smallScale, scaleY: self.smallScale }, { duration: 300, easing: tween.easeOut }); } } }; return self; }); var GridCell = Container.expand(function (x, y, isPlayer) { var self = Container.call(this); self.gridX = x; self.gridY = y; self.isPlayer = isPlayer; self.hasShip = false; self.isHit = false; self.isMiss = false; self.shipId = -1; var cellGraphics = self.attachAsset('gridBox', { anchorX: 0, anchorY: 0 }); self.setShip = function (shipId) { self.hasShip = true; self.shipId = shipId; if (self.isPlayer) { cellGraphics.tint = 0x808080; if (self.shipAsset) { self.shipAsset.alpha = 1; } } }; self.markHit = function () { self.isHit = true; cellGraphics.tint = 0xFF0000; // Add hit marker asset on top of the cell if (!self.hitMarkerAsset) { self.hitMarkerAsset = self.attachAsset('hitMarker', { anchorX: 0, anchorY: 0 }); // Position hit marker at the correct cell position self.hitMarkerAsset.x = 0; self.hitMarkerAsset.y = 0; } }; self.markMiss = function (isEnemyMiss) { self.isMiss = true; if (isEnemyMiss) { // Enemy missed on player's grid - use orange color cellGraphics.tint = 0xffaa00; } else { // Player missed on enemy's grid - use green color cellGraphics.tint = 0x00FF00; } }; self.markSunk = function () { cellGraphics.tint = 0x2F2F2F; }; self.down = function (x, y, obj) { if (gameState === 'playing' && !self.isPlayer && !self.isHit && !self.isMiss) { playerShoot(self.gridX, self.gridY); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var Ship = function Ship(length, id) { this.length = length; this.id = id; this.hits = 0; this.cells = []; this.isSunk = false; this.addCell = function (x, y) { this.cells.push({ x: x, y: y }); }; this.hit = function () { this.hits++; if (this.hits >= this.length) { this.isSunk = true; return true; } return false; }; }; var GRID_SIZE = 10; var CELL_SIZE = 150; // Increased to 150 for larger game area var GRID_OFFSET_X = 200; var PLAYER_GRID_Y = 1200; var AI_GRID_Y = 200; // Calculate center positions for single grid display var CENTER_GRID_X = (2048 - GRID_SIZE * CELL_SIZE) / 2; var CENTER_GRID_Y = (2732 - GRID_SIZE * CELL_SIZE) / 2 - 100; // Move grid up slightly var GRID_SPACING = 1000; // Distance between the two grids var playerGrid = []; var aiGrid = []; var playerShips = []; var aiShips = []; var gameState = 'intro'; // 'intro', 'placement', 'playing', 'gameOver' var introScreen = null; var currentPlayer = 'player'; // 'player', 'ai' var selectedX = -1; var selectedY = -1; var currentShipToPlace = 0; var isHorizontalPlacement = true; var shipLengths = [5, 4, 3, 3, 2]; var draggableShips = []; var placedShipsCount = 0; var draggedShip = null; // AI hunting variables var aiLastHitX = -1; var aiLastHitY = -1; var aiHuntingDirections = []; var aiCurrentDirection = 0; var aiHuntingMode = false; // Timer and effect variables var turnTimer = null; var turnTimeRemaining = 30; var isWaitingAfterShot = false; // Timer text var timerText = new Text2('30', { size: 50, fill: 0xFF0000 }); timerText.anchor.set(1, 0); LK.gui.topRight.addChild(timerText); var playerGridContainer = new Container(); var aiGridContainer = new Container(); // UI Elements var statusText = new Text2('Drag ships to your grid', { size: 60, fill: 0x000000 }); statusText.anchor.set(0.5, 0); LK.gui.top.addChild(statusText); var instructionText = new Text2('Double tap ships to rotate, drag to reposition', { size: 40, fill: 0x00FF00 }); instructionText.anchor.set(0.5, 0); instructionText.y = 200; instructionText.x = 0; // Starting position for scrolling // Add to game instead of GUI so it appears in front of monitor game.addChild(instructionText); // Position in front of monitor instructionText.x = 2048 / 2 - instructionText.width / 2; instructionText.y = CENTER_GRID_Y + GRID_SIZE * CELL_SIZE + 150; // Create scrolling text effect function scrollInstructionText() { if (gameState === 'placement') { var startX = -instructionText.width; var endX = 2048; instructionText.x = startX; tween(instructionText, { x: endX }, { duration: 8000, easing: tween.linear, onFinish: function onFinish() { LK.setTimeout(scrollInstructionText, 2000); } }); } } // Start scrolling after placement begins LK.setTimeout(function () { if (gameState === 'placement') { scrollInstructionText(); } }, 3000); var startButton = new Text2('START GAME', { size: 60, fill: 0x00FF00 }); startButton.anchor.set(0.5, 0.5); startButton.x = 2048 / 2; startButton.y = 300; // Move button lower startButton.visible = false; game.addChild(startButton); startButton.down = function (x, y, obj) { if (gameState === 'placement' && placedShipsCount >= shipLengths.length) { gameState = 'playing'; statusText.setText('Fire at enemy positions!'); instructionText.setText('Tap enemy grid to shoot'); startButton.visible = false; placeAIShips(); // Switch to AI grid for player's turn to attack with transition effect tween(playerGridContainer, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { playerGridContainer.visible = false; aiGridContainer.visible = true; myCommanderContainer.visible = false; enemyCommanderContainer.visible = true; aiGridContainer.alpha = 0; tween(aiGridContainer, { alpha: 1 }, { duration: 300 }); } }); } }; // Initialize grids function initializeGrids() { // Add containers to game - computer monitor first for background layering game.addChild(playerGridContainer); game.addChild(aiGridContainer); // Move computer monitor to back if it exists if (computerMonitorContainer) { game.removeChild(computerMonitorContainer); game.addChildAt(computerMonitorContainer, 0); } // Player grid (center during placement, left side during game) for (var x = 0; x < GRID_SIZE; x++) { playerGrid[x] = []; for (var y = 0; y < GRID_SIZE; y++) { var cell = new GridCell(x, y, true); cell.x = CENTER_GRID_X + x * CELL_SIZE; cell.y = CENTER_GRID_Y + y * CELL_SIZE; playerGrid[x][y] = cell; playerGridContainer.addChild(cell); } } // AI grid (center during game) for (var x = 0; x < GRID_SIZE; x++) { aiGrid[x] = []; for (var y = 0; y < GRID_SIZE; y++) { var cell = new GridCell(x, y, false); cell.x = CENTER_GRID_X + x * CELL_SIZE; cell.y = CENTER_GRID_Y + y * CELL_SIZE; aiGrid[x][y] = cell; aiGridContainer.addChild(cell); } } // Initialize grid visibility - show player grid during placement phase playerGridContainer.visible = true; aiGridContainer.visible = false; // Add grid labels var playerLabel = new Text2('Your Fleet', { size: 40, fill: 0x000000 }); playerLabel.anchor.set(0.5, 0.5); playerLabel.x = CENTER_GRID_X + GRID_SIZE * CELL_SIZE / 2; playerLabel.y = CENTER_GRID_Y - 50; playerGridContainer.addChild(playerLabel); var aiLabel = new Text2('Enemy Waters', { size: 40, fill: 0x000000 }); aiLabel.anchor.set(0.5, 0.5); aiLabel.x = CENTER_GRID_X + GRID_SIZE * CELL_SIZE / 2; aiLabel.y = CENTER_GRID_Y - 50; aiGridContainer.addChild(aiLabel); // Add coordinate labels for player grid for (var i = 0; i < GRID_SIZE; i++) { // Letters A-J on the left side var letterLabel = new Text2(String.fromCharCode(65 + i), { size: 20, fill: 0x000000 }); letterLabel.anchor.set(0.5, 0.5); letterLabel.x = CENTER_GRID_X - 30; letterLabel.y = CENTER_GRID_Y + i * CELL_SIZE + CELL_SIZE / 2; playerGridContainer.addChild(letterLabel); // Numbers 1-10 on the top var numberLabel = new Text2((i + 1).toString(), { size: 20, fill: 0x000000 }); numberLabel.anchor.set(0.5, 0.5); numberLabel.x = CENTER_GRID_X + i * CELL_SIZE + CELL_SIZE / 2; numberLabel.y = CENTER_GRID_Y - 60; playerGridContainer.addChild(numberLabel); } // Add coordinate labels for AI grid for (var i = 0; i < GRID_SIZE; i++) { // Letters A-J on the left side var letterLabel = new Text2(String.fromCharCode(65 + i), { size: 20, fill: 0x000000 }); letterLabel.anchor.set(0.5, 0.5); letterLabel.x = CENTER_GRID_X - 30; letterLabel.y = CENTER_GRID_Y + i * CELL_SIZE + CELL_SIZE / 2; aiGridContainer.addChild(letterLabel); // Numbers 1-10 on the top var numberLabel = new Text2((i + 1).toString(), { size: 20, fill: 0x000000 }); numberLabel.anchor.set(0.5, 0.5); numberLabel.x = CENTER_GRID_X + i * CELL_SIZE + CELL_SIZE / 2; numberLabel.y = CENTER_GRID_Y - 60; aiGridContainer.addChild(numberLabel); } // Create ship visual assets for player grid for (var x = 0; x < GRID_SIZE; x++) { for (var y = 0; y < GRID_SIZE; y++) { var shipAsset = LK.getAsset('ship', { anchorX: 0, anchorY: 0, alpha: 0 }); shipAsset.x = CENTER_GRID_X + x * CELL_SIZE; shipAsset.y = CENTER_GRID_Y + y * CELL_SIZE; playerGrid[x][y].shipAsset = shipAsset; playerGridContainer.addChild(shipAsset); } } // Create draggable ships in a grid layout at bottom of screen, avoiding commander area var shipStartY = 2400; // Move ships lower to avoid commander assets var shipStartX = 600; // Start further right to avoid commander assets var shipsPerRow = 3; // Maximum ships per row var shipSpacingX = 400; // Horizontal spacing between ships var shipSpacingY = 250; // Vertical spacing between rows for (var i = 0; i < shipLengths.length; i++) { var ship = new DraggableShip(shipLengths[i], i); // Calculate grid position for ship var row = Math.floor(i / shipsPerRow); var col = i % shipsPerRow; ship.x = shipStartX + col * shipSpacingX; ship.y = shipStartY + row * shipSpacingY; ship.originalX = ship.x; ship.originalY = ship.y; draggableShips.push(ship); game.addChild(ship); } } function selectCellForPlacement(x, y) { selectedX = x; selectedY = y; if (canPlaceShip(x, y, shipLengths[currentShipToPlace], isHorizontalPlacement, true)) { placeShip(x, y, shipLengths[currentShipToPlace], isHorizontalPlacement, true, currentShipToPlace); currentShipToPlace++; if (currentShipToPlace >= shipLengths.length) { gameState = 'playing'; statusText.setText('Fire at enemy positions!'); instructionText.setText('Tap enemy grid to shoot'); placeAIShips(); } else { statusText.setText('Place ship ' + (currentShipToPlace + 1) + ' (length: ' + shipLengths[currentShipToPlace] + ')'); } } } function canPlaceShip(startX, startY, length, horizontal, isPlayer) { var grid = isPlayer ? playerGrid : aiGrid; for (var i = 0; i < length; i++) { var x = horizontal ? startX + i : startX; var y = horizontal ? startY : startY + i; if (x >= GRID_SIZE || y >= GRID_SIZE || x < 0 || y < 0) { return false; } if (grid[x][y].hasShip) { return false; } } return true; } function placeShip(startX, startY, length, horizontal, isPlayer, shipId) { var grid = isPlayer ? playerGrid : aiGrid; var ships = isPlayer ? playerShips : aiShips; var ship = new Ship(length, shipId); for (var i = 0; i < length; i++) { var x = horizontal ? startX + i : startX; var y = horizontal ? startY : startY + i; grid[x][y].setShip(shipId); ship.addCell(x, y); } ships.push(ship); } function placeAIShips() { for (var i = 0; i < shipLengths.length; i++) { var placed = false; var attempts = 0; while (!placed && attempts < 100) { var x = Math.floor(Math.random() * GRID_SIZE); var y = Math.floor(Math.random() * GRID_SIZE); var horizontal = Math.random() < 0.5; if (canPlaceShip(x, y, shipLengths[i], horizontal, false)) { placeShip(x, y, shipLengths[i], horizontal, false, i); placed = true; } attempts++; } } } function playerShoot(x, y) { if (currentPlayer !== 'player' || isWaitingAfterShot) { return; } // Stop the timer if (turnTimer) { LK.clearInterval(turnTimer); turnTimer = null; } // Play shooting sound when firing LK.getSound('shoot').play(); var cell = aiGrid[x][y]; var hit = cell.hasShip; // Create visual effect var effectAsset = hit ? 'hit' : 'miss'; var effect = LK.getAsset(effectAsset, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.1, scaleY: 0.1 }); effect.x = CENTER_GRID_X + x * CELL_SIZE + CELL_SIZE / 2; effect.y = CENTER_GRID_Y + y * CELL_SIZE + CELL_SIZE / 2; aiGridContainer.addChild(effect); if (cell.hasShip) { cell.markHit(); hit = true; LK.getSound('explosion').play(); // Explosion effect for hit tween(effect, { scaleX: 2, scaleY: 2, alpha: 0.8 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(effect, { scaleX: 0.1, scaleY: 0.1, alpha: 0 }, { duration: 500, onFinish: function onFinish() { effect.destroy(); } }); } }); var ship = null; // Find the ship by ID in the aiShips array for (var i = 0; i < aiShips.length; i++) { if (aiShips[i].id === cell.shipId) { ship = aiShips[i]; break; } } if (ship) { var sunk = ship.hit(); if (sunk) { LK.getSound('sunk').play(); markShipAsSunk(ship, false); // Enemy commander reacts to ship being sunk showCommanderSpeech(getRandomSpeech(myCommanderSpeech.sunk), false); if (checkVictory(false)) { gameState = 'gameOver'; statusText.setText('Victory! You sank all enemy ships!'); instructionText.setText(''); LK.showYouWin(); return; } } else { // Enemy commander reacts to being hit showCommanderSpeech(getRandomSpeech(myCommanderSpeech.hit), false); } } statusText.setText('Hit! Fire again!'); // No delay for hits - player can continue shooting immediately startPlayerTurn(); } else { cell.markMiss(false); LK.getSound('waterSplash').play(); // Enemy commander reacts to player missing showCommanderSpeech(getRandomSpeech(myCommanderSpeech.miss), false); // Water splash effect for miss effect.tint = 0x00FF00; // Green color to match miss cell tint tween(effect, { scaleX: 1.5, scaleY: 1.5, alpha: 0.6 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { tween(effect, { scaleX: 0.1, scaleY: 0.1, alpha: 0 }, { duration: 600, onFinish: function onFinish() { effect.destroy(); } }); } }); currentPlayer = 'ai'; statusText.setText('Miss! Enemy is thinking...'); // 5-second delay before AI turn isWaitingAfterShot = true; LK.setTimeout(function () { isWaitingAfterShot = false; // Switch to player grid when AI attacks with transition effect tween(aiGridContainer, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { aiGridContainer.visible = false; playerGridContainer.visible = true; enemyCommanderContainer.visible = false; myCommanderContainer.visible = true; playerGridContainer.alpha = 0; tween(playerGridContainer, { alpha: 1 }, { duration: 300 }); } }); startAiTurn(); }, 5000); } } function aiTurn() { if (currentPlayer !== 'ai' || isWaitingAfterShot) { return; } // Stop the timer if (turnTimer) { LK.clearInterval(turnTimer); turnTimer = null; } var x, y; var attempts = 0; // Smart AI: If in hunting mode, try adjacent cells to last hit if (aiHuntingMode && aiLastHitX !== -1 && aiLastHitY !== -1) { var found = false; // Try directions: up, right, down, left var directions = [{ x: 0, y: -1 }, // up { x: 1, y: 0 }, // right { x: 0, y: 1 }, // down { x: -1, y: 0 } // left ]; // Try each direction from the last hit for (var d = 0; d < directions.length && !found; d++) { var testX = aiLastHitX + directions[d].x; var testY = aiLastHitY + directions[d].y; // Check if position is valid and not already attacked if (testX >= 0 && testX < GRID_SIZE && testY >= 0 && testY < GRID_SIZE && !playerGrid[testX][testY].isHit && !playerGrid[testX][testY].isMiss) { x = testX; y = testY; found = true; } } // If no adjacent cells available, exit hunting mode if (!found) { aiHuntingMode = false; aiLastHitX = -1; aiLastHitY = -1; } } // If not in hunting mode or no valid adjacent cells, shoot randomly if (!aiHuntingMode || aiLastHitX === -1 && aiLastHitY === -1) { do { x = Math.floor(Math.random() * GRID_SIZE); y = Math.floor(Math.random() * GRID_SIZE); attempts++; } while ((playerGrid[x][y].isHit || playerGrid[x][y].isMiss) && attempts < 100); } // Play shooting sound when AI fires LK.getSound('shoot').play(); var cell = playerGrid[x][y]; var hit = cell.hasShip; // Create visual effect var effectAsset = hit ? 'hit' : 'miss'; var effect = LK.getAsset(effectAsset, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.1, scaleY: 0.1 }); effect.x = CENTER_GRID_X + x * CELL_SIZE + CELL_SIZE / 2; effect.y = CENTER_GRID_Y + y * CELL_SIZE + CELL_SIZE / 2; playerGridContainer.addChild(effect); if (cell.hasShip) { cell.markHit(); LK.getSound('explosion').play(); // Explosion effect for hit tween(effect, { scaleX: 2, scaleY: 2, alpha: 0.8 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(effect, { scaleX: 0.1, scaleY: 0.1, alpha: 0 }, { duration: 500, onFinish: function onFinish() { effect.destroy(); } }); } }); // Enter hunting mode and remember this hit position aiHuntingMode = true; aiLastHitX = x; aiLastHitY = y; var ship = null; // Find the ship by ID in the playerShips array for (var i = 0; i < playerShips.length; i++) { if (playerShips[i].id === cell.shipId) { ship = playerShips[i]; break; } } if (ship) { var sunk = ship.hit(); if (sunk) { LK.getSound('sunk').play(); markShipAsSunk(ship, true); // Exit hunting mode when ship is sunk aiHuntingMode = false; aiLastHitX = -1; aiLastHitY = -1; // Enemy commander celebrates sinking player's ship showCommanderSpeech(getRandomSpeech(enemyCommanderSpeech.sunk), true); if (checkVictory(true)) { gameState = 'gameOver'; statusText.setText('Defeat! Enemy sank all your ships!'); instructionText.setText(''); LK.showGameOver(); return; } } else { // Enemy commander celebrates hitting player's ship showCommanderSpeech(getRandomSpeech(enemyCommanderSpeech.hit), true); } } statusText.setText('Enemy hit your ship!'); // 5-second delay before AI continues isWaitingAfterShot = true; LK.setTimeout(function () { isWaitingAfterShot = false; startAiTurn(); }, 5000); } else { cell.markMiss(true); LK.getSound('waterSplash').play(); // Enemy commander reacts to missing showCommanderSpeech(getRandomSpeech(enemyCommanderSpeech.miss), true); // Water splash effect for miss effect.tint = 0xFFAA00; tween(effect, { scaleX: 1.5, scaleY: 1.5, alpha: 0.6 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { tween(effect, { scaleX: 0.1, scaleY: 0.1, alpha: 0 }, { duration: 600, onFinish: function onFinish() { effect.destroy(); } }); } }); currentPlayer = 'player'; statusText.setText('Enemy missed! Your turn!'); // 5-second delay before player turn isWaitingAfterShot = true; LK.setTimeout(function () { isWaitingAfterShot = false; // Switch to AI grid for player's turn to attack with transition effect tween(playerGridContainer, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { playerGridContainer.visible = false; aiGridContainer.visible = true; myCommanderContainer.visible = false; enemyCommanderContainer.visible = true; aiGridContainer.alpha = 0; tween(aiGridContainer, { alpha: 1 }, { duration: 300 }); } }); startPlayerTurn(); }, 5000); } } function markShipAsSunk(ship, isPlayer) { var grid = isPlayer ? playerGrid : aiGrid; for (var i = 0; i < ship.cells.length; i++) { var cellPos = ship.cells[i]; grid[cellPos.x][cellPos.y].markSunk(); // Darken hit markers on sunk ship cells if (grid[cellPos.x][cellPos.y].hitMarkerAsset) { tween(grid[cellPos.x][cellPos.y].hitMarkerAsset, { alpha: 0.4 }, { duration: 500, easing: tween.easeOut }); } } } function removeShipFromGrid(ship) { for (var x = 0; x < GRID_SIZE; x++) { for (var y = 0; y < GRID_SIZE; y++) { if (playerGrid[x][y].shipId === ship.shipId) { playerGrid[x][y].hasShip = false; playerGrid[x][y].shipId = -1; var cellGraphics = playerGrid[x][y].children[0]; cellGraphics.tint = 0xFFFFFF; if (playerGrid[x][y].shipAsset) { playerGrid[x][y].shipAsset.alpha = 0; } } } } } function checkVictory(playerLost) { var ships = playerLost ? playerShips : aiShips; for (var i = 0; i < ships.length; i++) { if (!ships[i].isSunk) { return false; } } return true; } // Double tap to rotate ship during placement var lastTapTime = 0; game.down = function (x, y, obj) { if (gameState === 'placement') { var currentTime = Date.now(); if (currentTime - lastTapTime < 300) { // Find ship being rotated - check both unplaced and placed ships for (var i = 0; i < draggableShips.length; i++) { var ship = draggableShips[i]; var shipBounds = { x: ship.x, y: ship.y, width: ship.isHorizontal ? ship.length * CELL_SIZE : CELL_SIZE, height: ship.isHorizontal ? CELL_SIZE : ship.length * CELL_SIZE }; if (x >= shipBounds.x && x <= shipBounds.x + shipBounds.width && y >= shipBounds.y && y <= shipBounds.y + shipBounds.height) { if (ship.isPlaced) { // Remove ship from grid removeShipFromGrid(ship); ship.isPlaced = false; ship.visible = true; placedShipsCount--; } ship.rotate(); break; } } instructionText.setText('Double tap ships to rotate, drag to reposition'); } lastTapTime = currentTime; } }; game.move = function (x, y, obj) { if (gameState === 'placement' && draggedShip) { draggedShip.x = x - draggedShip.width / 2; draggedShip.y = y - draggedShip.height / 2; } }; game.up = function (x, y, obj) { draggedShip = null; }; function startPlayerTurn() { currentPlayer = 'player'; turnTimeRemaining = 30; timerText.setText(turnTimeRemaining.toString()); timerText.visible = true; // Clear any existing timer first if (turnTimer) { LK.clearInterval(turnTimer); turnTimer = null; } turnTimer = LK.setInterval(function () { turnTimeRemaining--; timerText.setText(turnTimeRemaining.toString()); if (turnTimeRemaining <= 0) { LK.clearInterval(turnTimer); turnTimer = null; timerText.visible = false; // Auto-switch to AI turn on timeout currentPlayer = 'ai'; statusText.setText('Time up! Enemy is thinking...'); tween(aiGridContainer, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { aiGridContainer.visible = false; playerGridContainer.visible = true; enemyCommanderContainer.visible = false; myCommanderContainer.visible = true; playerGridContainer.alpha = 0; tween(playerGridContainer, { alpha: 1 }, { duration: 300 }); } }); startAiTurn(); } }, 1000); } function startAiTurn() { currentPlayer = 'ai'; turnTimeRemaining = 30; timerText.setText(turnTimeRemaining.toString()); timerText.visible = true; // Clear any existing timer first if (turnTimer) { LK.clearInterval(turnTimer); turnTimer = null; } // AI thinks for 2-5 seconds before shooting var thinkTime = 2000 + Math.random() * 3000; turnTimer = LK.setInterval(function () { turnTimeRemaining--; timerText.setText(turnTimeRemaining.toString()); if (turnTimeRemaining <= 0) { LK.clearInterval(turnTimer); turnTimer = null; timerText.visible = false; aiTurn(); } }, 1000); LK.setTimeout(function () { if (currentPlayer === 'ai' && !isWaitingAfterShot) { aiTurn(); } }, thinkTime); } // Create commander assets var myCommanderContainer = new Container(); var enemyCommanderContainer = new Container(); // Position commanders higher and at bottom left corner myCommanderContainer.x = 50; myCommanderContainer.y = 2732 - 500; // Moved even higher up enemyCommanderContainer.x = 50; enemyCommanderContainer.y = 2732 - 500; // Same position as my commander // Create shadow assets first (positioned slightly offset) var myCommanderShadow = myCommanderContainer.attachAsset('myCommander', { anchorX: 0, anchorY: 0, scaleX: 2.2, scaleY: 2.2, alpha: 0.3, tint: 0x000000 }); myCommanderShadow.x = 8; myCommanderShadow.y = 8; var enemyCommanderShadow = enemyCommanderContainer.attachAsset('enemyCommander', { anchorX: 0, anchorY: 0, scaleX: 2.2, scaleY: 2.2, alpha: 0.3, tint: 0x000000 }); enemyCommanderShadow.x = 8; enemyCommanderShadow.y = 8; // Create main commander assets (larger size) var myCommanderAsset = myCommanderContainer.attachAsset('myCommander', { anchorX: 0, anchorY: 0, scaleX: 2.2, scaleY: 2.2 }); var enemyCommanderAsset = enemyCommanderContainer.attachAsset('enemyCommander', { anchorX: 0, anchorY: 0, scaleX: 2.2, scaleY: 2.2 }); // Add commanders to game game.addChild(myCommanderContainer); game.addChild(enemyCommanderContainer); // Initialize commander visibility - show my commander during placement phase myCommanderContainer.visible = true; enemyCommanderContainer.visible = false; // Commander speech arrays var myCommanderSpeech = { hit: ["Lanet olsun! Nasıl buldun?", "Bu olamaz! Şanslı atış!", "Beni buldun ama savaş henüz bitmedi!", "İyi atış... ama son olmayacak!"], miss: ["Hah! Ordumu bulmak kolay değil!", "Boşa atış! Denemeye devam et!", "Su sıçradı ama gemim yerinde!", "Yaklaştın ama yeterli değil!"], sunk: ["Gemimi batırdın... ama intikam alacağım!", "Bu savaşı kaybettim ama onur hala benimle!", "İyi savaştın... şimdilik kazandın"] }; var enemyCommanderSpeech = { hit: ["Mükemmel atış! Hedefi bulduk!", "Doğrudan isabet! Böyle devam!", "Ateş! Düşman gemisini yakaladık!", "Harika! Bu şekilde kazanacağız!"], miss: ["Lanet! Hedefi kaçırdık!", "Su sıçradı! Tekrar dene!", "Bu sefer olmadı ama pes etmem!", "Yakında hedefimi bulacağım!"], sunk: ["Bir gemi daha battı! Zafer yakın!", "Düşman filosu eriyor!", "Mükemmel! Böyle devam edersek kazanırız!"] }; // Current speech display var currentSpeechText = null; var speechTimeout = null; function showCommanderSpeech(text, isEnemyCommander) { // Clear existing speech if (currentSpeechText) { currentSpeechText.destroy(); currentSpeechText = null; } if (speechTimeout) { LK.clearTimeout(speechTimeout); speechTimeout = null; } // Create speech bubble container currentSpeechText = new Container(); // Create speech bubble background var speechBubble = currentSpeechText.attachAsset('speechBubble', { anchorX: 0, anchorY: 0 }); // Create speech bubble text var speechText = new Text2(text, { size: 36, fill: 0x000000 }); speechText.anchor.set(0.5, 0.5); speechText.x = 350; // Move text further to the right in bubble speechText.y = 75; // Center in bubble currentSpeechText.addChild(speechText); // Add speech bubble directly to game instead of commander container game.addChild(currentSpeechText); // Position speech bubble next to appropriate commander if (isEnemyCommander && enemyCommanderContainer.visible) { currentSpeechText.x = enemyCommanderContainer.x + 440; // Position to the right of commander currentSpeechText.y = enemyCommanderContainer.y + 50; // Align with top of commander } else if (!isEnemyCommander && myCommanderContainer.visible) { currentSpeechText.x = myCommanderContainer.x + 440; // Position to the right of commander currentSpeechText.y = myCommanderContainer.y + 50; // Align with top of commander } else { // Fallback positioning if no commander is visible currentSpeechText.x = 50 + 440; currentSpeechText.y = 2732 - 500 + 50; } // Animate speech appearance currentSpeechText.alpha = 0; tween(currentSpeechText, { alpha: 1 }, { duration: 300 }); // Remove speech after 3 seconds speechTimeout = LK.setTimeout(function () { if (currentSpeechText) { tween(currentSpeechText, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { if (currentSpeechText) { currentSpeechText.destroy(); currentSpeechText = null; } } }); } }, 3000); } function getRandomSpeech(speechArray) { return speechArray[Math.floor(Math.random() * speechArray.length)]; } // Initialize the game function createIntroScreen() { introScreen = new Container(); game.addChild(introScreen); // Create television frame var tvFrame = LK.getAsset('tvFrame', { anchorX: 0.5, anchorY: 0.5 }); tvFrame.x = 2048 / 2; tvFrame.y = 2732 / 2; introScreen.addChild(tvFrame); // Create TV stand var tvStand = LK.getAsset('tvStand', { anchorX: 0.5, anchorY: 0 }); tvStand.x = 2048 / 2; tvStand.y = 2732 / 2 + 1450; introScreen.addChild(tvStand); // Create TV buttons and speakers var powerButton = LK.getAsset('tvButton', { anchorX: 0.5, anchorY: 0.5, tint: 0xFF4444 }); powerButton.x = 2048 / 2 + 1200; powerButton.y = 2732 / 2 - 1200; introScreen.addChild(powerButton); var volumeButton = LK.getAsset('tvButton', { anchorX: 0.5, anchorY: 0.5, tint: 0x4444FF }); volumeButton.x = 2048 / 2 + 1200; volumeButton.y = 2732 / 2 - 1100; introScreen.addChild(volumeButton); // Create speakers for (var s = 0; s < 6; s++) { var speaker = LK.getAsset('tvSpeaker', { anchorX: 0.5, anchorY: 0.5 }); speaker.x = 2048 / 2 + 1200; speaker.y = 2732 / 2 - 800 + s * 60; introScreen.addChild(speaker); } // Create TV screen (black background) var tvScreen = LK.getAsset('tvScreen', { anchorX: 0.5, anchorY: 0.5 }); tvScreen.x = 2048 / 2; tvScreen.y = 2732 / 2; introScreen.addChild(tvScreen); // Create container for all TV content var tvContent = new Container(); tvContent.x = 2048 / 2 - 950; // Center content in TV screen tvContent.y = 2732 / 2 - 1300; introScreen.addChild(tvContent); // Create gradient background layers for depth (now inside TV) var bgLayer1 = LK.getAsset('gridBox', { anchorX: 0, anchorY: 0, scaleX: 16, scaleY: 21, tint: 0x001A33, alpha: 1 }); tvContent.addChild(bgLayer1); var bgLayer2 = LK.getAsset('gridBox', { anchorX: 0, anchorY: 0, scaleX: 15, scaleY: 19, tint: 0x003D66, alpha: 0.7 }); bgLayer2.x = 80; bgLayer2.y = 80; tvContent.addChild(bgLayer2); // Create multiple water layers for depth var waterLayer1 = LK.getAsset('water', { anchorX: 0, anchorY: 0, scaleX: 24, scaleY: 28, alpha: 0.08, tint: 0x1B4F72 }); tvContent.addChild(waterLayer1); var waterLayer2 = LK.getAsset('water', { anchorX: 0, anchorY: 0, scaleX: 20, scaleY: 24, alpha: 0.15, tint: 0x2E86AB }); tvContent.addChild(waterLayer2); var waterLayer3 = LK.getAsset('water', { anchorX: 0, anchorY: 0, scaleX: 16, scaleY: 20, alpha: 0.12, tint: 0x5DADE2 }); tvContent.addChild(waterLayer3); // Create floating water particles var waterParticles = []; for (var p = 0; p < 8; p++) { var particle = LK.getAsset('water', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3 + Math.random() * 0.2, scaleY: 0.3 + Math.random() * 0.2, alpha: 0.2 + Math.random() * 0.1, tint: 0x87CEEB }); particle.x = Math.random() * 1900; particle.y = Math.random() * 2600; waterParticles.push(particle); tvContent.addChild(particle); } // Animate water layers with wave motion tween(waterLayer1, { alpha: 0.12, x: -50 }, { duration: 4000, easing: tween.easeInOut, onFinish: function onFinish() { tween(waterLayer1, { alpha: 0.08, x: 0 }, { duration: 4000, easing: tween.easeInOut, onFinish: function onFinish() { tween(waterLayer1, { alpha: 0.12, x: -50 }, { duration: 4000, easing: tween.easeInOut, onFinish: arguments.callee }); } }); } }); tween(waterLayer2, { alpha: 0.22, x: 30 }, { duration: 3500, easing: tween.easeInOut, onFinish: function onFinish() { tween(waterLayer2, { alpha: 0.15, x: -30 }, { duration: 3500, easing: tween.easeInOut, onFinish: function onFinish() { tween(waterLayer2, { alpha: 0.22, x: 30 }, { duration: 3500, easing: tween.easeInOut, onFinish: arguments.callee }); } }); } }); tween(waterLayer3, { alpha: 0.18, y: -20 }, { duration: 3000, easing: tween.easeInOut, onFinish: function onFinish() { tween(waterLayer3, { alpha: 0.12, y: 20 }, { duration: 3000, easing: tween.easeInOut, onFinish: function onFinish() { tween(waterLayer3, { alpha: 0.18, y: -20 }, { duration: 3000, easing: tween.easeInOut, onFinish: arguments.callee }); } }); } }); // Animate water particles for (var p = 0; p < waterParticles.length; p++) { (function (particle, index) { function floatParticle() { if (gameState === 'intro') { var targetX = Math.random() * 1900; var targetY = Math.random() * 2600; tween(particle, { x: targetX, y: targetY, alpha: 0.1 + Math.random() * 0.15, rotation: Math.random() * Math.PI * 2 }, { duration: 8000 + Math.random() * 4000, easing: tween.easeInOut, onFinish: floatParticle }); } } LK.setTimeout(floatParticle, index * 500); })(waterParticles[p], p); } // Main title with shadow effect var titleShadow = new Text2('NAVAL COMBAT', { size: 100, fill: 0x000000 }); titleShadow.anchor.set(0.5, 0.5); titleShadow.x = 950 + 6; titleShadow.y = 406; titleShadow.alpha = 0; tvContent.addChild(titleShadow); var titleText = new Text2('NAVAL COMBAT', { size: 100, fill: 0xFFD700 }); titleText.anchor.set(0.5, 0.5); titleText.x = 950; titleText.y = 400; titleText.alpha = 0; tvContent.addChild(titleText); // Subtitle with glow effect var subtitleGlow = new Text2('Strategic Fleet Warfare', { size: 42, fill: 0x87CEEB }); subtitleGlow.anchor.set(0.5, 0.5); subtitleGlow.x = 950; subtitleGlow.y = 550; subtitleGlow.alpha = 0; tvContent.addChild(subtitleGlow); var subtitleText = new Text2('Strategic Fleet Warfare', { size: 42, fill: 0xFFFFFF }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 950; subtitleText.y = 550; subtitleText.alpha = 0; tvContent.addChild(subtitleText); // Create naval battle themed decorative elements var navyElements = []; var shipColors = [0x2C3E50, 0x34495E, 0x566573, 0x7F8C8D, 0x95A5A6]; var enemyColors = [0x8B0000, 0xA52A2A, 0xB22222, 0xDC143C, 0xFF4500]; // Create allied fleet formation (left side) for (var i = 0; i < 4; i++) { var allyShip = LK.getAsset('ship', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0 + i * 0.2, scaleY: 2.0 + i * 0.2, tint: shipColors[i] }); allyShip.x = 120 + i * 50; allyShip.y = 750 + i * 70; allyShip.alpha = 0; allyShip.rotation = Math.PI / 8 + i * 0.05; navyElements.push(allyShip); tvContent.addChild(allyShip); } // Create enemy fleet formation (right side) for (var i = 0; i < 4; i++) { var enemyShip = LK.getAsset('ship', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0 + i * 0.2, scaleY: 2.0 + i * 0.2, tint: enemyColors[i] }); enemyShip.x = 1780 - i * 50; enemyShip.y = 750 + i * 70; enemyShip.alpha = 0; enemyShip.rotation = -Math.PI / 8 - i * 0.05; navyElements.push(enemyShip); tvContent.addChild(enemyShip); } // Add naval commander silhouettes var allyCommander = LK.getAsset('myCommander', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, alpha: 0, tint: 0x2C3E50 }); allyCommander.x = 250; allyCommander.y = 1100; navyElements.push(allyCommander); tvContent.addChild(allyCommander); var enemyCommander = LK.getAsset('enemyCommander', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, alpha: 0, tint: 0x8B0000 }); enemyCommander.x = 1650; enemyCommander.y = 1100; navyElements.push(enemyCommander); tvContent.addChild(enemyCommander); // Add strategic grid overlay effects for (var i = 0; i < 6; i++) { var gridElement = LK.getAsset('gridBox', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.4, scaleY: 0.4, alpha: 0, tint: 0x3498DB }); gridElement.x = 950 + (i % 3 - 1) * 160; gridElement.y = 900 + Math.floor(i / 3) * 120; navyElements.push(gridElement); tvContent.addChild(gridElement); } // Replace shipFormation reference with navyElements var shipFormation = navyElements; // Enhanced start button with frame var buttonFrame = LK.getAsset('gridBox', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.2, scaleY: 1.0, tint: 0xFFD700, alpha: 0 }); buttonFrame.x = 950; buttonFrame.y = 1300; tvContent.addChild(buttonFrame); var startGameButton = new Text2('⚓ START BATTLE ⚓', { size: 58, fill: 0x000000 }); startGameButton.anchor.set(0.5, 0.5); startGameButton.x = 950; startGameButton.y = 1300; startGameButton.alpha = 0; tvContent.addChild(startGameButton); // Additional UI elements var versionText = new Text2('Admiral Edition v1.0', { size: 25, fill: 0x808080 }); versionText.anchor.set(0.5, 0.5); versionText.x = 950; versionText.y = 1450; versionText.alpha = 0; tvContent.addChild(versionText); var instructionsText = new Text2('Deploy your fleet strategically and command the seas!', { size: 36, fill: 0xE0E0E0 }); instructionsText.anchor.set(0.5, 0.5); instructionsText.x = 950; instructionsText.y = 1600; instructionsText.alpha = 0; tvContent.addChild(instructionsText); // Professional animation sequence // Title entrance with dramatic effect tween(titleShadow, { alpha: 0.6, y: 500, scaleX: 1.05, scaleY: 1.05 }, { duration: 1200, easing: tween.elasticOut }); tween(titleText, { alpha: 1, y: 500, scaleX: 1.1, scaleY: 1.1 }, { duration: 1200, easing: tween.elasticOut }); // Subtitle with sequential glow effect LK.setTimeout(function () { tween(subtitleGlow, { alpha: 0.4, scaleX: 1.05, scaleY: 1.05 }, { duration: 800, easing: tween.easeOut }); tween(subtitleText, { alpha: 1 }, { duration: 800, easing: tween.easeOut }); }, 400); // Naval fleet formation entrance with battle positioning LK.setTimeout(function () { for (var i = 0; i < navyElements.length; i++) { (function (element, delay) { LK.setTimeout(function () { // Different entrance effects based on element type var isShip = element.x < 1024; // Left side elements are allied ships var entranceEffect = isShip ? { alpha: 0.85, scaleX: element.scaleX * 1.2, scaleY: element.scaleY * 1.2, x: element.x + (isShip ? 50 : -50) } : { alpha: 0.7, scaleX: element.scaleX * 1.1, scaleY: element.scaleY * 1.1 }; tween(element, entranceEffect, { duration: 1200, easing: tween.elasticOut }); // Add naval movement patterns function navalMovement() { if (gameState === 'intro') { var movementPattern = isShip ? { y: element.y + (10 + Math.random() * 8), rotation: element.rotation + (Math.random() - 0.5) * 0.1, alpha: element.alpha * (0.9 + Math.random() * 0.2) } : { scaleX: element.scaleX * (0.95 + Math.random() * 0.1), scaleY: element.scaleY * (0.95 + Math.random() * 0.1), alpha: element.alpha * (0.8 + Math.random() * 0.4) }; tween(element, movementPattern, { duration: 2500 + Math.random() * 1500, easing: tween.easeInOut, onFinish: function onFinish() { var returnPattern = isShip ? { y: element.y - (10 + Math.random() * 8), rotation: element.rotation - (Math.random() - 0.5) * 0.1, alpha: element.alpha / (0.9 + Math.random() * 0.2) } : { scaleX: element.scaleX / (0.95 + Math.random() * 0.1), scaleY: element.scaleY / (0.95 + Math.random() * 0.1), alpha: element.alpha / (0.8 + Math.random() * 0.4) }; tween(element, returnPattern, { duration: 2500 + Math.random() * 1500, easing: tween.easeInOut, onFinish: navalMovement }); } }); } } LK.setTimeout(navalMovement, 1500 + Math.random() * 1000); }, delay * 120); })(navyElements[i], i); } }, 800); // Button entrance with frame LK.setTimeout(function () { tween(buttonFrame, { alpha: 0.8, scaleX: 4.2, scaleY: 1.3 }, { duration: 600, easing: tween.easeOut }); tween(startGameButton, { alpha: 1, scaleX: 1.0, scaleY: 1.0 }, { duration: 600, easing: tween.bounceOut }); tween(versionText, { alpha: 1 }, { duration: 600, easing: tween.easeOut }); tween(instructionsText, { alpha: 1 }, { duration: 600, easing: tween.easeOut }); }, 1400); // Enhanced pulsing effect for start button LK.setTimeout(function () { function pulseButton() { if (gameState === 'intro') { tween(startGameButton, { scaleX: 1.15, scaleY: 1.15, tint: 0x00FF00 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(startGameButton, { scaleX: 1.0, scaleY: 1.0, tint: 0xFFFFFF }, { duration: 1000, easing: tween.easeInOut, onFinish: pulseButton }); } }); tween(buttonFrame, { alpha: 1, scaleX: 4.4, scaleY: 1.4 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(buttonFrame, { alpha: 0.8, scaleX: 4.2, scaleY: 1.3 }, { duration: 1000, easing: tween.easeInOut }); } }); } } pulseButton(); }, 2000); // Add TV static overlay effect var tvStatic = LK.getAsset('gridBox', { anchorX: 0.5, anchorY: 0.5, scaleX: 16, scaleY: 21, alpha: 0.02, tint: 0xFFFFFF }); tvStatic.x = 950; tvStatic.y = 1300; tvContent.addChild(tvStatic); // Animate TV static function animateStatic() { if (gameState === 'intro') { tween(tvStatic, { alpha: 0.05 + Math.random() * 0.03, scaleX: 16 + Math.random() * 0.2, scaleY: 21 + Math.random() * 0.2 }, { duration: 100 + Math.random() * 200, onFinish: animateStatic }); } } animateStatic(); // Add TV screen glow effect var screenGlow = LK.getAsset('tvScreen', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.05, scaleY: 1.05, tint: 0x4A90E2, alpha: 0.1 }); screenGlow.x = 2048 / 2; screenGlow.y = 2732 / 2; introScreen.addChild(screenGlow); // Animate screen glow function animateGlow() { if (gameState === 'intro') { tween(screenGlow, { alpha: 0.15, scaleX: 1.08, scaleY: 1.08 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(screenGlow, { alpha: 0.1, scaleX: 1.05, scaleY: 1.05 }, { duration: 2000, easing: tween.easeInOut, onFinish: animateGlow }); } }); } } animateGlow(); // Click handler for start button with effect startGameButton.down = function (x, y, obj) { if (gameState === 'intro') { // Button press effect tween(startGameButton, { scaleX: 0.95, scaleY: 0.95, alpha: 0.8 }, { duration: 100, onFinish: function onFinish() { tween(startGameButton, { scaleX: 1.0, scaleY: 1.0, alpha: 1 }, { duration: 100 }); } }); // Fade out intro screen with dramatic effect tween(introScreen, { alpha: 0, scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeIn, onFinish: function onFinish() { introScreen.destroy(); introScreen = null; gameState = 'placement'; statusText.setText('Drag ships to your grid'); // Start ocean waves music after intro ends LK.playMusic('oceanWaves'); // Show computer monitor and radar system computerMonitorContainer.visible = true; computerMonitorContainer.alpha = 0; tween(computerMonitorContainer, { alpha: 1 }, { duration: 1000, easing: tween.easeOut }); initializeGrids(); } }); } }; } createIntroScreen(); // Create computer monitor frame around game area var computerMonitorContainer = new Container(); computerMonitorContainer.visible = false; // Hide during intro game.addChild(computerMonitorContainer); // Position computer monitor behind the game grids var monitorFrame = computerMonitorContainer.attachAsset('computerMonitor', { anchorX: 0.5, anchorY: 0.5 }); monitorFrame.x = 2048 / 2; monitorFrame.y = CENTER_GRID_Y + GRID_SIZE * CELL_SIZE / 2; // Computer screen background var computerScreen = computerMonitorContainer.attachAsset('computerScreen', { anchorX: 0.5, anchorY: 0.5 }); computerScreen.x = 2048 / 2; computerScreen.y = CENTER_GRID_Y + GRID_SIZE * CELL_SIZE / 2; // Computer base var computerBase = computerMonitorContainer.attachAsset('computerBase', { anchorX: 0.5, anchorY: 0 }); computerBase.x = 2048 / 2; computerBase.y = CENTER_GRID_Y + GRID_SIZE * CELL_SIZE + 50; // Create rotating radar system in background var radarContainer = new Container(); computerMonitorContainer.addChild(radarContainer); radarContainer.x = 2048 / 2; radarContainer.y = CENTER_GRID_Y + GRID_SIZE * CELL_SIZE / 2; // Radar circles (concentric) for (var i = 1; i <= 3; i++) { var radarCircle = radarContainer.attachAsset('radarCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: i * 0.4, scaleY: i * 0.4, alpha: 0.15 }); radarCircle.x = 0; radarCircle.y = 0; } // Radar center dot var radarCenter = radarContainer.attachAsset('radarCenter', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); radarCenter.x = 0; radarCenter.y = 0; // Rotating radar sweep line var radarSweep = radarContainer.attachAsset('radarSweep', { anchorX: 0, anchorY: 0.5, alpha: 0.6 }); radarSweep.x = 0; radarSweep.y = 0; // Start radar sweep rotation function rotateRadarSweep() { if (gameState === 'playing' || gameState === 'placement') { tween(radarSweep, { rotation: radarSweep.rotation + Math.PI * 2 }, { duration: 3000, easing: tween.linear, onFinish: rotateRadarSweep }); } } // Start radar sweep after placement phase begins LK.setTimeout(function () { if (gameState === 'placement') { rotateRadarSweep(); } }, 1500); // Start radar sweep after initialization LK.setTimeout(function () { rotateRadarSweep(); }, 500); // Add computer-style grid overlay var computerGrid = new Container(); computerMonitorContainer.addChild(computerGrid); computerGrid.x = 2048 / 2 - 950; computerGrid.y = CENTER_GRID_Y - 750; // Create computer grid lines for (var i = 0; i <= 20; i++) { // Vertical lines var vLine = LK.getAsset('gridLine', { anchorX: 0.5, anchorY: 0, scaleX: 0.5, scaleY: 1.2, alpha: 0.08, tint: 0x00FF00 }); vLine.x = i * 95; vLine.y = 0; computerGrid.addChild(vLine); // Horizontal lines var hLine = LK.getAsset('gridLine', { anchorX: 0, anchorY: 0.5, scaleX: 1.0, scaleY: 0.5, alpha: 0.08, tint: 0x00FF00, rotation: Math.PI / 2 }); hLine.x = 0; hLine.y = i * 75; computerGrid.addChild(hLine); } // Add ocean movement to game containers function addOceanMovement() { if (gameState === 'playing' || gameState === 'placement') { // Gentle rocking motion for player grid tween(playerGridContainer, { x: playerGridContainer.x + (Math.random() - 0.5) * 8, y: playerGridContainer.y + (Math.random() - 0.5) * 6, rotation: playerGridContainer.rotation + (Math.random() - 0.5) * 0.008 }, { duration: 2000 + Math.random() * 1000, easing: tween.easeInOut, onFinish: function onFinish() { // Return to original position with slight variation tween(playerGridContainer, { x: game.children.indexOf(playerGridContainer) >= 0 ? playerGridContainer.x - (Math.random() - 0.5) * 8 : playerGridContainer.x, y: game.children.indexOf(playerGridContainer) >= 0 ? playerGridContainer.y - (Math.random() - 0.5) * 6 : playerGridContainer.y, rotation: playerGridContainer.rotation - (Math.random() - 0.5) * 0.008 }, { duration: 2000 + Math.random() * 1000, easing: tween.easeInOut, onFinish: addOceanMovement }); } }); // Similar motion for AI grid tween(aiGridContainer, { x: aiGridContainer.x + (Math.random() - 0.5) * 8, y: aiGridContainer.y + (Math.random() - 0.5) * 6, rotation: aiGridContainer.rotation + (Math.random() - 0.5) * 0.008 }, { duration: 2200 + Math.random() * 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(aiGridContainer, { x: game.children.indexOf(aiGridContainer) >= 0 ? aiGridContainer.x - (Math.random() - 0.5) * 8 : aiGridContainer.x, y: game.children.indexOf(aiGridContainer) >= 0 ? aiGridContainer.y - (Math.random() - 0.5) * 6 : aiGridContainer.y, rotation: aiGridContainer.rotation - (Math.random() - 0.5) * 0.008 }, { duration: 2200 + Math.random() * 800, easing: tween.easeInOut }); } }); // Gentle movement for commander containers tween(myCommanderContainer, { x: myCommanderContainer.x + (Math.random() - 0.5) * 4, y: myCommanderContainer.y + (Math.random() - 0.5) * 3 }, { duration: 3000 + Math.random() * 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(myCommanderContainer, { x: 50 + (Math.random() - 0.5) * 4, y: 2732 - 500 + (Math.random() - 0.5) * 3 }, { duration: 3000 + Math.random() * 1000, easing: tween.easeInOut }); } }); tween(enemyCommanderContainer, { x: enemyCommanderContainer.x + (Math.random() - 0.5) * 4, y: enemyCommanderContainer.y + (Math.random() - 0.5) * 3 }, { duration: 2800 + Math.random() * 1200, easing: tween.easeInOut, onFinish: function onFinish() { tween(enemyCommanderContainer, { x: 50 + (Math.random() - 0.5) * 4, y: 2732 - 500 + (Math.random() - 0.5) * 3 }, { duration: 2800 + Math.random() * 1200, easing: tween.easeInOut }); } }); } } // Add computer screen effects function addComputerEffects() { if (gameState === 'playing' || gameState === 'placement') { // Screen flicker effect if (computerScreen) { var flickerAlpha = 0.95 + Math.random() * 0.05; tween(computerScreen, { alpha: flickerAlpha, tint: 0x001100 + Math.floor(Math.random() * 0x001100) }, { duration: 100 + Math.random() * 200, onFinish: addComputerEffects }); } } } // Start computer effects LK.setTimeout(function () { addComputerEffects(); }, 2000); // Start ocean movement after a short delay LK.setTimeout(function () { addOceanMovement(); }, 1000); // Ocean waves music will start after intro ends // Game code saved successfully - Naval Combat Game Complete;
===================================================================
--- original.js
+++ change.js
@@ -290,13 +290,41 @@
statusText.anchor.set(0.5, 0);
LK.gui.top.addChild(statusText);
var instructionText = new Text2('Double tap ships to rotate, drag to reposition', {
size: 40,
- fill: 0x000000
+ fill: 0x00FF00
});
instructionText.anchor.set(0.5, 0);
-instructionText.y = 100;
-LK.gui.top.addChild(instructionText);
+instructionText.y = 200;
+instructionText.x = 0; // Starting position for scrolling
+// Add to game instead of GUI so it appears in front of monitor
+game.addChild(instructionText);
+// Position in front of monitor
+instructionText.x = 2048 / 2 - instructionText.width / 2;
+instructionText.y = CENTER_GRID_Y + GRID_SIZE * CELL_SIZE + 150;
+// Create scrolling text effect
+function scrollInstructionText() {
+ if (gameState === 'placement') {
+ var startX = -instructionText.width;
+ var endX = 2048;
+ instructionText.x = startX;
+ tween(instructionText, {
+ x: endX
+ }, {
+ duration: 8000,
+ easing: tween.linear,
+ onFinish: function onFinish() {
+ LK.setTimeout(scrollInstructionText, 2000);
+ }
+ });
+ }
+}
+// Start scrolling after placement begins
+LK.setTimeout(function () {
+ if (gameState === 'placement') {
+ scrollInstructionText();
+ }
+}, 3000);
var startButton = new Text2('START GAME', {
size: 60,
fill: 0x00FF00
});
water look on top. In-Game asset. 2d. High contrast. No shadows
white location icon look on top. In-Game asset. 2d. High contrast. No shadows
explosion look on top. In-Game asset. 2d. High contrast. No shadows
white smoke look on top. In-Game asset. 2d. High contrast. No shadows
red point icon. In-Game asset. 2d. High contrast. No shadows
2d sea mine In-Game asset. 2d. High contrast. No shadows
warship commander head looking right in game asset. In-Game asset. 2d. High contrast. No shadows
warship commander head looking left in game asset. In-Game asset. 2d. High contrast. No shadows
speech bubble 2d. In-Game asset. 2d. High contrast. No shadows
metal border. In-Game asset. 2d. High contrast. No shadows
metal line. In-Game asset. 2d. High contrast. No shadows