User prompt
radar sistemi ve monitör introdan sonra gözüksün radar arka planda kalmalı ve hareket etmeli görsellik açısından iyi olur. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
oyun alanı bir bilgisayar içinde gibi gözükmeli arka planda bir radar dönüyor efekti eklemek istiyorum. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
oyun alanı sanki okyanusta gibi ufak ufak hareket etse olduğu yerde sanki deniz imajı vermek istiyorum ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
save the code
User prompt
find and fix all bugs
User prompt
bu introyu sanki bir televizyonun içindeymiş gibiyapalım. bir televizyon olsun bu intro içinde olsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
oyun temasına uygun bir şekilde polishle bu intro ekranını ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
bu intro screen daha profesyonel olmalı polishle biraz ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
oyuna bir giriş ekranı yapabilirmiyiz güzel gözüken elit bir giriş ekranı olmalı ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ses assetleride eklemek istiyorum deniz sesi oyunda hep olmalı atış sesi olmalı miss vurursak suya gülle düşme sesi eğer gemiyi vurursak patlama sesi ve gemi batıınca gemi batma sesi
Code edit (1 edits merged)
Please save this source code
User prompt
yazılar dahada sağdan başlamalı
User prompt
speech içindeki yazılar biraz daha sağdan başlamalı
User prompt
konuşma içinde çıkan yazılar daha büyük fontta olmalı ve asset için güzel gözükmeli
User prompt
şuanda ekrana geliyor ama sol üst köşede gözüküyor commander konuşyor gibi olması için o bölgeye yakın olmalı
User prompt
konuşma balonu hiç çıkmıyor
User prompt
konuşma balonu hiç gözükmüyor commander asettinin sağına almalıyız.
User prompt
speech buble commander resminin yanında çıkmalı şuanda sol üst köşede duruyor.
User prompt
commanderların konuşmaları gözükmüyor start game tuşuna bastıktan sonra commander asettinin yan tarafında bir konuşma bulutu asseti olmalı ve içerisinde yazmalı.
User prompt
koyduğumuz commanderlar yaptığımız hareketlere göre konuşmalı mesala miss vurduysak karşı tarafın commanderı ordumu bulmak kolay değil gibi sözler söyleyebilir. Vuruncada Lanet olsun nasıl buldun gibi sözler söylemeli.
User prompt
gemilerin oyun alanına koymadan önceki yerlerinde aralarında biraz mesafe olmalı
User prompt
yan yana durmak zorunda değiller alt alta ve yan yana koyabiliriz.
User prompt
gemilerin oyun alanına koymadan önceki yerlerini commander asettini ütüne gelmeyecek şekilde ayarlayalım.
User prompt
commander assetlerini biraz daha yukarı alalım
User prompt
commander assetlerini biraz daha büyütüp yukarı alalım ve shadow ekleyelim. ↪💡 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 = 'placement'; // 'placement', 'playing', 'gameOver' 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: 0x000000 }); instructionText.anchor.set(0.5, 0); instructionText.y = 100; LK.gui.top.addChild(instructionText); 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 game.addChild(playerGridContainer); game.addChild(aiGridContainer); // 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; } 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('hit').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('miss').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); } 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('hit').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('miss').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! Ordum 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: 30, fill: 0x000000 }); speechText.anchor.set(0.5, 0.5); speechText.x = 200; // Center in bubble speechText.y = 75; // Center in bubble currentSpeechText.addChild(speechText); // Position speech bubble next to commander if (isEnemyCommander && enemyCommanderContainer.visible) { enemyCommanderContainer.addChild(currentSpeechText); currentSpeechText.x = 500; // Relative to commander container currentSpeechText.y = 150; // Relative to commander container } else if (!isEnemyCommander && myCommanderContainer.visible) { myCommanderContainer.addChild(currentSpeechText); currentSpeechText.x = 500; // Relative to commander container currentSpeechText.y = 150; // Relative to commander container } // 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 initializeGrids(); ;
===================================================================
--- original.js
+++ change.js
@@ -1071,15 +1071,16 @@
speechText.y = 75; // Center in bubble
currentSpeechText.addChild(speechText);
// Position speech bubble next to commander
if (isEnemyCommander && enemyCommanderContainer.visible) {
- currentSpeechText.x = enemyCommanderContainer.x + 500;
- currentSpeechText.y = enemyCommanderContainer.y + 150;
+ enemyCommanderContainer.addChild(currentSpeechText);
+ currentSpeechText.x = 500; // Relative to commander container
+ currentSpeechText.y = 150; // Relative to commander container
} else if (!isEnemyCommander && myCommanderContainer.visible) {
- currentSpeechText.x = myCommanderContainer.x + 500;
- currentSpeechText.y = myCommanderContainer.y + 150;
+ myCommanderContainer.addChild(currentSpeechText);
+ currentSpeechText.x = 500; // Relative to commander container
+ currentSpeechText.y = 150; // Relative to commander container
}
- game.addChild(currentSpeechText);
// Animate speech appearance
currentSpeechText.alpha = 0;
tween(currentSpeechText, {
alpha: 1
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