User prompt
Daha da sağa
User prompt
Ateşi padin sağına taşı
User prompt
Özel saldırılar basılı tutunca çalışsın
User prompt
Özel saldırıları ve düz atak saldırısını padin etrafına yerleştir ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Padin hedef seçme olayı bozuldu optimize et
User prompt
Pad saldırı için progress bar olarak çalışsın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Padin ortası basılı tuttuğunda dolan saldırı butonu olsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Padin hassasiyetini default ayara getir
User prompt
Padin hassasiyetini optimize et
User prompt
Padi 2 kat büyüt ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Padin hassasiyetini düşür
User prompt
İmlec sadece bulunduğu hücreye etki edebilsin boyutunu buna göre ayarla ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
İmleçlerş optimize et sade düşman alanında hedef belirlemek için kullanacağım ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
2. İmleci kaldır
User prompt
Optimize et düşman alanında hedefleme yapmayı iyileştir ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
2. İmleci pasif yap ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
1. Ana imleci pasif yap
User prompt
İmleci küçült ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Kontrol padini büyüt biraz yukarı taşı ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
İmleç sadece düşman alanında gezebilsin
User prompt
İmleç sadece düşman alanının içinde gezinebilsin
User prompt
Düşman alanında belli olmuyor imleç alanın önünde olsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Düşman alanındaki seçili hücreyi gösteren imleç ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Hedef seçiciyi kaldır
User prompt
Hedef seçiçiyi ortaya taşı ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var GameGrid = Container.expand(function (isPlayerGrid) { var self = Container.call(this); self.isPlayerGrid = isPlayerGrid; self.cells = []; self.ships = []; var currentGridSize = gridSize; // Use global gridSize variable var cellSize = 60; // Initialize grid cells for (var row = 0; row < currentGridSize; row++) { self.cells[row] = []; for (var col = 0; col < currentGridSize; col++) { var cell = new GridCell(row, col, isPlayerGrid); cell.x = col * cellSize; cell.y = row * cellSize; self.cells[row][col] = cell; self.addChild(cell); } } // Draw grid lines for (var i = 0; i <= currentGridSize; i++) { // Vertical lines var vLine = self.attachAsset('gridLine', { width: 2, height: currentGridSize * cellSize, x: i * cellSize, y: 0 }); // Horizontal lines var hLine = self.attachAsset('gridLine', { width: currentGridSize * cellSize, height: 2, x: 0, y: i * cellSize }); } self.placeShip = function (startRow, startCol, length, isHorizontal, shipType) { var shipCells = []; // Check if placement is valid for (var i = 0; i < length; i++) { var row = isHorizontal ? startRow : startRow + i; var col = isHorizontal ? startCol + i : startCol; if (row >= currentGridSize || col >= currentGridSize || self.cells[row][col].hasShip) { return false; } shipCells.push({ row: row, col: col }); } // Place ship var ship = { cells: shipCells, hits: 0, sunk: false, type: shipType || 'cruiser', length: length, isHorizontal: isHorizontal, shipGraphic: null }; // Create unified ship graphic that spans all cells if (self.isPlayerGrid) { var cellSize = 60; var shipWidth = isHorizontal ? length * cellSize - 8 : cellSize - 8; var shipHeight = isHorizontal ? cellSize - 8 : length * cellSize - 8; var shipX = startCol * cellSize + 4; var shipY = startRow * cellSize + 4; ship.shipGraphic = self.attachAsset(shipType || 'cruiser', { width: shipWidth, height: shipHeight, x: shipX, y: shipY }); } // Mark cells as having ship but don't create individual graphics for (var j = 0; j < shipCells.length; j++) { var cellPos = shipCells[j]; var cell = self.cells[cellPos.row][cellPos.col]; cell.hasShip = true; } self.ships.push(ship); return true; }; self.checkHit = function (row, col) { var cell = self.cells[row][col]; if (cell.hasShip) { cell.markHit(); // Find which ship was hit for (var i = 0; i < self.ships.length; i++) { var ship = self.ships[i]; for (var j = 0; j < ship.cells.length; j++) { if (ship.cells[j].row === row && ship.cells[j].col === col) { ship.hits++; if (ship.hits === ship.cells.length && !ship.sunk) { ship.sunk = true; LK.getSound('sunk').play(); // Add fireworks effect for sunk ship self.createFireworks(ship.cells); updateFleetStatus(); return 'sunk'; } return 'hit'; } } } } else { cell.markMiss(); return 'miss'; } }; self.allShipsSunk = function () { for (var i = 0; i < self.ships.length; i++) { if (!self.ships[i].sunk) { return false; } } return true; }; self.createFireworks = function (shipCells) { var cellSize = 60; for (var i = 0; i < shipCells.length; i++) { var cellPos = shipCells[i]; var centerX = cellPos.col * cellSize + cellSize / 2; var centerY = cellPos.row * cellSize + cellSize / 2; // Create multiple firework particles for (var f = 0; f < 5; f++) { var firework = self.attachAsset('firework', { anchorX: 0.5, anchorY: 0.5, x: centerX, y: centerY, alpha: 1, scaleX: 0.5, scaleY: 0.5 }); var angle = f / 5 * Math.PI * 2; var distance = 50 + Math.random() * 30; var targetX = centerX + Math.cos(angle) * distance; var targetY = centerY + Math.sin(angle) * distance; tween(firework, { x: targetX, y: targetY, scaleX: 1.2, scaleY: 1.2, alpha: 0 }, { duration: 800 + Math.random() * 400, easing: tween.easeOut, onFinish: function onFinish() { firework.destroy(); } }); } } }; return self; }); var GridCell = Container.expand(function (row, col, isPlayerGrid) { var self = Container.call(this); self.row = row; self.col = col; self.isPlayerGrid = isPlayerGrid; self.hasShip = false; self.isHit = false; self.isMiss = false; var cellSize = 60; var waterTile = self.attachAsset('water', { width: cellSize, height: cellSize, x: 0, y: 0, color: 0xffffff }); var shipGraphic = null; var hitMarker = null; var missMarker = null; self.placeShip = function (shipType, segmentIndex, totalLength, isHorizontal) { // Only show ship graphics on player's own grid, hide enemy ships if (!shipGraphic && self.isPlayerGrid) { shipType = shipType || 'cruiser'; // Create single unified ship graphic that spans the entire ship length var shipWidth = isHorizontal ? totalLength * cellSize - 8 : cellSize - 8; var shipHeight = isHorizontal ? cellSize - 8 : totalLength * cellSize - 8; // Calculate position to center the ship across all its cells var shipX = isHorizontal ? segmentIndex * cellSize + 4 - segmentIndex * cellSize : 4; var shipY = isHorizontal ? 4 : segmentIndex * cellSize + 4 - segmentIndex * cellSize; // Only create the ship graphic on the first segment (bow) if (segmentIndex === 0) { shipGraphic = self.attachAsset(shipType, { width: shipWidth, height: shipHeight, x: shipX, y: shipY }); } } self.hasShip = true; }; self.removeShip = function () { // Ship graphics are now handled at the GameGrid level // Just mark the cell as not having a ship self.hasShip = false; }; self.markHit = function () { if (!self.isHit) { hitMarker = self.attachAsset('hit', { anchorX: 0.5, anchorY: 0.5, x: cellSize / 2, y: cellSize / 2 }); self.isHit = true; LK.getSound('hit').play(); LK.getSound('shoot').play(); // Add explosion effect var explosion = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: cellSize / 2, y: cellSize / 2, alpha: 0 }); tween(explosion, { alpha: 1, scaleX: 1.5, scaleY: 1.5 }, { duration: 300, onFinish: function onFinish() { tween(explosion, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { explosion.destroy(); } }); } }); } }; self.markMiss = function () { if (!self.isMiss) { missMarker = self.attachAsset('miss', { anchorX: 0.5, anchorY: 0.5, x: cellSize / 2, y: cellSize / 2 }); self.isMiss = true; LK.getSound('miss').play(); // Add missile effect for miss var missile = self.attachAsset('missile', { anchorX: 0.5, anchorY: 1, x: cellSize / 2, y: -50, alpha: 0.8 }); LK.getSound('shoot').play(); tween(missile, { y: cellSize / 2, alpha: 0.3 }, { duration: 400, onFinish: function onFinish() { missile.destroy(); } }); } }; self.down = function (x, y, obj) { if (gamePhase === 'placement' && self.isPlayerGrid) { handleShipPlacement(self.row, self.col); } else if (gamePhase === 'battle' && !self.isPlayerGrid && !self.isHit && !self.isMiss) { handlePlayerShot(self.row, self.col); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x001122 }); /**** * Game Code ****/ // Game state // Aircraft Carrier - long and wide // Battleship - large // Cruiser - medium // Destroyer - smaller // Submarine - smallest // Hull details // Deck details // Gun turrets var gamePhase = 'placement'; // 'placement', 'battle', 'gameOver' var currentShipIndex = 0; var isHorizontal = true; var playerTurn = true; var aiTargets = []; var aiLastHit = null; var aiHuntMode = false; var airBombardmentUsed = false; var airBombardmentInProgress = false; var submarineAttackUsed = false; var submarineAttackInProgress = false; var sihaAttackUsed = false; var sihaAttackInProgress = false; var lastAttackType = null; // Track the last attack type to prevent consecutive use var aiAttackOptions = ['air', 'submarine', 'siha']; // Available AI attack options var aiLastAttackType = null; // Track AI's last attack type var aiAttackCooldowns = { air: false, submarine: false, siha: false }; // Track which AI attacks have been used // Attack rights tracking var playerAttackRights = { air: 2, submarine: 2, siha: 2 }; var aiAttackRights = { air: 2, submarine: 2, siha: 2 }; // Ship sizes to place - realistic naval fleet var shipSizes = [5, 4, 3, 3, 2]; // Carrier, Battleship, Cruiser, Cruiser, Destroyer var shipTypes = ['Uçak Gemisi', 'Savaş Gemisi', 'Kruvazör', 'Kruvazör', 'Muhrip']; var shipAssets = ['carrier', 'battleship', 'cruiser', 'cruiser', 'destroyer']; // Create grids var playerGrid = new GameGrid(true); var enemyGrid = new GameGrid(false); // Scale up grids for better visibility - increased for closer view playerGrid.scaleX = 2.0; playerGrid.scaleY = 2.0; enemyGrid.scaleX = 2.0; enemyGrid.scaleY = 2.0; // Center grids on screen var gridWidth = 8 * 60 * 2.0; // 8 cells * 60px * scale var screenCenterX = 2048 / 2; var gridCenterX = gridWidth / 2; playerGrid.x = screenCenterX - gridCenterX; playerGrid.y = 1300; enemyGrid.x = screenCenterX - gridCenterX; enemyGrid.y = 300; game.addChild(playerGrid); game.addChild(enemyGrid); // Hide enemy grid during placement phase enemyGrid.visible = false; // UI Elements var statusText = new Text2('Gemilerinizi yerleştirin. ' + shipSizes[0] + ' uzunluğunda gemi yerleştirmek için dokunun', { size: 40, fill: 0xFFFFFF }); statusText.anchor.set(0.5, 0); LK.gui.top.addChild(statusText); var turnText = new Text2('', { size: 35, fill: 0xFFFF00 }); turnText.anchor.set(0.5, 0); turnText.y = 80; LK.gui.top.addChild(turnText); // Labels for grids var enemyLabel = new Text2('Düşman Suları', { size: 45, fill: 0xFF6666 }); enemyLabel.anchor.set(0.5, 0.5); enemyLabel.x = enemyGrid.x + 8 * 60 * 1.5 / 2; enemyLabel.y = enemyGrid.y - 60; game.addChild(enemyLabel); var playerLabel = new Text2('Filonuz', { size: 45, fill: 0x66FF66 }); playerLabel.anchor.set(0.5, 0.5); playerLabel.x = playerGrid.x + 8 * 60 * 1.5 / 2; playerLabel.y = playerGrid.y - 60; game.addChild(playerLabel); // Rotation button for ship placement var rotateButton = new Text2('Gemiyi Çevir', { size: 60, fill: 0xFFFF00 }); rotateButton.anchor.set(0.5, 0.5); rotateButton.x = 300; rotateButton.y = 1200; game.addChild(rotateButton); rotateButton.down = function (x, y, obj) { if (gamePhase === 'placement') { isHorizontal = !isHorizontal; updateStatusText(); updateShipPreview(); } }; // Auto-placement button var autoPlaceButton = new Text2('Otomatik Yerleştir', { size: 60, fill: 0x00FF00 }); autoPlaceButton.anchor.set(0.5, 0.5); autoPlaceButton.x = 300; autoPlaceButton.y = 1300; game.addChild(autoPlaceButton); autoPlaceButton.down = function (x, y, obj) { if (gamePhase === 'placement') { autoPlacePlayerShips(); } }; // Start battle button var startBattleButton = new Text2('Savaşı Başlat', { size: 60, fill: 0xFF0000 }); startBattleButton.anchor.set(0.5, 0.5); startBattleButton.x = 300; startBattleButton.y = 1400; game.addChild(startBattleButton); startBattleButton.down = function (x, y, obj) { if (gamePhase === 'placement' && currentShipIndex >= shipSizes.length) { placeAIShips(); gamePhase = 'battle'; rotateButton.visible = false; autoPlaceButton.visible = false; startBattleButton.visible = false; enemyGrid.visible = true; airBombardmentButton.visible = true; submarineAttackButton.visible = true; sihaAttackButton.visible = true; // Move and scale down player grid to bottom left tween(playerGrid, { x: 50, y: 2150, scaleX: playerGrid.originalScaleX * 0.6, scaleY: playerGrid.originalScaleY * 0.6 }, { duration: 1000, easing: tween.easeInOut }); // Update player label position tween(playerLabel, { x: 50 + gridSize * 60 * playerGrid.originalScaleX * 0.6 / 2, y: 2150 - 60 }, { duration: 1000, easing: tween.easeInOut }); updateStatusText(); } }; // Air bombardment button var airBombardmentButton = new Container(); airBombardmentButton.x = 50; airBombardmentButton.y = 700; airBombardmentButton.visible = false; game.addChild(airBombardmentButton); // Button background var airButtonBg = airBombardmentButton.attachAsset('water', { width: 420, height: 90, x: -10, y: -45, color: 0xFF6600 }); airButtonBg.alpha = 0.9; // Button border var airButtonBorder = airBombardmentButton.attachAsset('gridLine', { width: 424, height: 94, x: -12, y: -47, color: 0xFFFFFF }); airButtonBorder.alpha = 0.8; // Button text var airButtonText = new Text2('🚁 Hava Bombardımanı', { size: 42, fill: 0xFFFFFF }); airButtonText.anchor.set(0, 0.5); airButtonText.x = 15; airButtonText.y = 0; airBombardmentButton.addChild(airButtonText); // Button press effect airBombardmentButton.down = function (x, y, obj) { if (gamePhase === 'battle' && playerTurn && !airBombardmentUsed && !airBombardmentInProgress && lastAttackType !== 'air') { // Press effect tween(airBombardmentButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, onFinish: function onFinish() { tween(airBombardmentButton, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); executeAirBombardment(); } }; // Submarine attack button var submarineAttackButton = new Container(); submarineAttackButton.x = 50; submarineAttackButton.y = 1000; submarineAttackButton.visible = false; game.addChild(submarineAttackButton); // Button background var subButtonBg = submarineAttackButton.attachAsset('water', { width: 420, height: 90, x: -10, y: -45, color: 0x0066CC }); subButtonBg.alpha = 0.9; // Button border var subButtonBorder = submarineAttackButton.attachAsset('gridLine', { width: 424, height: 94, x: -12, y: -47, color: 0xFFFFFF }); subButtonBorder.alpha = 0.8; // Button text var subButtonText = new Text2('🚢 Denizaltı Saldırısı', { size: 42, fill: 0xFFFFFF }); subButtonText.anchor.set(0, 0.5); subButtonText.x = 15; subButtonText.y = 0; submarineAttackButton.addChild(subButtonText); // Button press effect submarineAttackButton.down = function (x, y, obj) { if (gamePhase === 'battle' && playerTurn && !submarineAttackUsed && !submarineAttackInProgress && lastAttackType !== 'submarine') { // Press effect tween(submarineAttackButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, onFinish: function onFinish() { tween(submarineAttackButton, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); executeSubmarineAttack(); } }; // SIHA attack button var sihaAttackButton = new Container(); sihaAttackButton.x = 50; sihaAttackButton.y = 1300; sihaAttackButton.visible = false; game.addChild(sihaAttackButton); // Button background var sihaButtonBg = sihaAttackButton.attachAsset('water', { width: 420, height: 90, x: -10, y: -45, color: 0x9900FF }); sihaButtonBg.alpha = 0.9; // Button border var sihaButtonBorder = sihaAttackButton.attachAsset('gridLine', { width: 424, height: 94, x: -12, y: -47, color: 0xFFFFFF }); sihaButtonBorder.alpha = 0.8; // Button text var sihaButtonText = new Text2('🛩️ SİHA Saldırısı', { size: 42, fill: 0xFFFFFF }); sihaButtonText.anchor.set(0, 0.5); sihaButtonText.x = 15; sihaButtonText.y = 0; sihaAttackButton.addChild(sihaButtonText); // Button press effect sihaAttackButton.down = function (x, y, obj) { if (gamePhase === 'battle' && playerTurn && !sihaAttackUsed && !sihaAttackInProgress && lastAttackType !== 'siha') { // Press effect tween(sihaAttackButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, onFinish: function onFinish() { tween(sihaAttackButton, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); executeSihaAttack(); } }; // Attack rights display var attackRightsContainer = new Container(); attackRightsContainer.x = 50; attackRightsContainer.y = playerGrid.y + 200; game.addChild(attackRightsContainer); var attackRightsTitle = new Text2('Saldırı Hakları', { size: 60, fill: 0xFFFFFF }); attackRightsTitle.anchor.set(0, 0); attackRightsTitle.x = 0; attackRightsTitle.y = 0; attackRightsContainer.addChild(attackRightsTitle); // Player attack rights var playerRightsTitle = new Text2('Oyuncu:', { size: 50, fill: 0x00FF00 }); playerRightsTitle.anchor.set(0, 0); playerRightsTitle.x = 0; playerRightsTitle.y = 60; attackRightsContainer.addChild(playerRightsTitle); var playerAirRightsText = new Text2('Hava: 2', { size: 45, fill: 0x00FF00 }); playerAirRightsText.anchor.set(0, 0); playerAirRightsText.x = 0; playerAirRightsText.y = 110; attackRightsContainer.addChild(playerAirRightsText); var playerSubRightsText = new Text2('Denizaltı: 2', { size: 45, fill: 0x00FF00 }); playerSubRightsText.anchor.set(0, 0); playerSubRightsText.x = 0; playerSubRightsText.y = 160; attackRightsContainer.addChild(playerSubRightsText); var playerSihaRightsText = new Text2('SİHA: 2', { size: 45, fill: 0x00FF00 }); playerSihaRightsText.anchor.set(0, 0); playerSihaRightsText.x = 0; playerSihaRightsText.y = 210; attackRightsContainer.addChild(playerSihaRightsText); // AI attack rights var aiRightsTitle = new Text2('Düşman:', { size: 50, fill: 0xFF0000 }); aiRightsTitle.anchor.set(0, 0); aiRightsTitle.x = 0; aiRightsTitle.y = 280; attackRightsContainer.addChild(aiRightsTitle); var aiAirRightsText = new Text2('Hava: 2', { size: 45, fill: 0xFF0000 }); aiAirRightsText.anchor.set(0, 0); aiAirRightsText.x = 0; aiAirRightsText.y = 330; attackRightsContainer.addChild(aiAirRightsText); var aiSubRightsText = new Text2('Denizaltı: 2', { size: 45, fill: 0xFF0000 }); aiSubRightsText.anchor.set(0, 0); aiSubRightsText.x = 0; aiSubRightsText.y = 380; attackRightsContainer.addChild(aiSubRightsText); var aiSihaRightsText = new Text2('SİHA: 2', { size: 45, fill: 0xFF0000 }); aiSihaRightsText.anchor.set(0, 0); aiSihaRightsText.x = 0; aiSihaRightsText.y = 430; attackRightsContainer.addChild(aiSihaRightsText); function updateAttackRightsDisplay() { playerAirRightsText.setText('Hava: ' + playerAttackRights.air); playerSubRightsText.setText('Denizaltı: ' + playerAttackRights.submarine); playerSihaRightsText.setText('SİHA: ' + playerAttackRights.siha); aiAirRightsText.setText('Hava: ' + aiAttackRights.air); aiSubRightsText.setText('Denizaltı: ' + aiAttackRights.submarine); aiSihaRightsText.setText('SİHA: ' + aiAttackRights.siha); // Update button visibility based on available rights if (gamePhase === 'battle') { attackRightsContainer.visible = true; airBombardmentButton.visible = playerAttackRights.air > 0 && lastAttackType !== 'air' && playerTurn; submarineAttackButton.visible = playerAttackRights.submarine > 0 && lastAttackType !== 'submarine' && playerTurn; sihaAttackButton.visible = playerAttackRights.siha > 0 && lastAttackType !== 'siha' && playerTurn; } else { attackRightsContainer.visible = false; } } // Ship preview container for placement phase var shipPreviewContainer = new Container(); shipPreviewContainer.x = 2048 / 2; shipPreviewContainer.y = 1050; // Position above player grid (player grid is at y=1300) game.addChild(shipPreviewContainer); function updateShipPreview() { // Clear existing preview for (var i = shipPreviewContainer.children.length - 1; i >= 0; i--) { shipPreviewContainer.children[i].destroy(); } if (gamePhase === 'placement' && currentShipIndex < shipSizes.length) { var shipLength = shipSizes[currentShipIndex]; var shipType = shipAssets[currentShipIndex]; var cellSize = 60; // Create preview ship graphic var previewWidth = isHorizontal ? shipLength * cellSize - 8 : cellSize - 8; var previewHeight = isHorizontal ? cellSize - 8 : shipLength * cellSize - 8; var previewX = isHorizontal ? -(previewWidth / 2) : -(previewWidth / 2); var previewY = isHorizontal ? -(previewHeight / 2) : -(previewHeight / 2); var shipPreview = shipPreviewContainer.attachAsset(shipType, { width: previewWidth, height: previewHeight, x: previewX, y: previewY, alpha: 0.8 }); // Add ship name label var shipNameText = new Text2(shipTypes[currentShipIndex], { size: 35, fill: 0xFFFFFF }); shipNameText.anchor.set(0.5, 0.5); shipNameText.x = 0; shipNameText.y = previewHeight / 2 + 50; shipPreviewContainer.addChild(shipNameText); // Add orientation label var orientationText = new Text2(isHorizontal ? 'Yatay' : 'Dikey', { size: 30, fill: 0xFFFF00 }); orientationText.anchor.set(0.5, 0.5); orientationText.x = 0; orientationText.y = previewHeight / 2 + 90; shipPreviewContainer.addChild(orientationText); } } function updateStatusText() { if (gamePhase === 'placement') { if (currentShipIndex < shipSizes.length) { var orientation = isHorizontal ? 'yatay' : 'dikey'; var shipName = shipTypes[currentShipIndex]; statusText.setText(shipName + ' yerleştirin (' + shipSizes[currentShipIndex] + ' kare, ' + orientation + ')'); updateShipPreview(); } else { statusText.setText('Tüm gemiler yerleştirildi! Savaşı başlatmak için butona tıklayın.'); shipPreviewContainer.visible = false; } } else if (gamePhase === 'battle') { shipPreviewContainer.visible = false; if (playerTurn && !airBombardmentInProgress && !submarineAttackInProgress && !sihaAttackInProgress) { var bombardmentText = playerAttackRights.air > 0 && lastAttackType !== 'air' ? ' | Hava bombardımanı mevcut!' : ''; var submarineText = playerAttackRights.submarine > 0 && lastAttackType !== 'submarine' ? ' | Denizaltı saldırısı mevcut!' : ''; var sihaText = playerAttackRights.siha > 0 && lastAttackType !== 'siha' ? ' | SİHA saldırısı mevcut!' : ''; statusText.setText('Sıra sizde - Düşman ızgarasına ateş edin!' + bombardmentText + submarineText + sihaText); turnText.setText('SİZİN SIRANIZ'); } else if (airBombardmentInProgress) { statusText.setText('Hava bombardımanı devam ediyor...'); turnText.setText('HAVA SALDIRISI'); airBombardmentButton.visible = false; submarineAttackButton.visible = false; sihaAttackButton.visible = false; } else if (submarineAttackInProgress) { statusText.setText('Denizaltı saldırısı devam ediyor...'); turnText.setText('DENİZALTI SALDIRISI'); airBombardmentButton.visible = false; submarineAttackButton.visible = false; sihaAttackButton.visible = false; } else if (sihaAttackInProgress) { statusText.setText('SİHA saldırısı devam ediyor...'); turnText.setText('SİHA SALDIRISI'); airBombardmentButton.visible = false; submarineAttackButton.visible = false; sihaAttackButton.visible = false; } else { var aiHasAttacks = aiAttackRights.air > 0 || aiAttackRights.submarine > 0 || aiAttackRights.siha > 0; var aiAttackText = aiHasAttacks && aiLastAttackType !== 'regular' ? ' (Özel saldırı hazırlanıyor...)' : ''; statusText.setText('Düşman düşünüyor...' + aiAttackText); turnText.setText('DÜŞMAN SIRASI'); } } updateAttackRightsDisplay(); } function handleShipPlacement(row, col) { if (currentShipIndex >= shipSizes.length) return; var shipLength = shipSizes[currentShipIndex]; var shipType = shipAssets[currentShipIndex]; if (playerGrid.placeShip(row, col, shipLength, isHorizontal, shipType)) { currentShipIndex++; updateFleetStatus(); if (currentShipIndex >= shipSizes.length) { // All ships placed, start AI placement placeAIShips(); gamePhase = 'battle'; rotateButton.visible = false; autoPlaceButton.visible = false; enemyGrid.visible = true; updateStatusText(); } else { updateStatusText(); } } } function autoPlacePlayerShips() { // Clear existing ships and their graphics for (var i = 0; i < playerGrid.ships.length; i++) { var ship = playerGrid.ships[i]; if (ship.shipGraphic) { ship.shipGraphic.destroy(); ship.shipGraphic = null; } for (var j = 0; j < ship.cells.length; j++) { var cellPos = ship.cells[j]; playerGrid.cells[cellPos.row][cellPos.col].removeShip(); } } playerGrid.ships = []; // Clear all hit and miss markers from the board for (var row = 0; row < gridSize; row++) { for (var col = 0; col < gridSize; col++) { var cell = playerGrid.cells[row][col]; cell.isHit = false; cell.isMiss = false; // Remove any visual markers that might exist if (cell.hitMarker) { cell.hitMarker.destroy(); cell.hitMarker = null; } if (cell.missMarker) { cell.missMarker.destroy(); cell.missMarker = null; } } } // Reset ship placement index currentShipIndex = 0; var playerShipSizes = [5, 4, 3, 3, 2]; var playerShipTypes = ['carrier', 'battleship', 'cruiser', 'cruiser', 'destroyer']; for (var i = 0; i < playerShipSizes.length; i++) { var placed = false; var attempts = 0; while (!placed && attempts < 100) { var row = Math.floor(Math.random() * gridSize); var col = Math.floor(Math.random() * gridSize); var horizontal = Math.random() < 0.5; if (playerGrid.placeShip(row, col, playerShipSizes[i], horizontal, playerShipTypes[i])) { placed = true; currentShipIndex++; } attempts++; } } // Update status text to show current placement state updateStatusText(); updateFleetStatus(); } function placeAIShips() { var aiShipSizes = [5, 4, 3, 3, 2]; var aiShipTypes = ['carrier', 'battleship', 'cruiser', 'cruiser', 'destroyer']; for (var i = 0; i < aiShipSizes.length; i++) { var placed = false; var attempts = 0; while (!placed && attempts < 100) { var row = Math.floor(Math.random() * gridSize); var col = Math.floor(Math.random() * gridSize); var horizontal = Math.random() < 0.5; if (enemyGrid.placeShip(row, col, aiShipSizes[i], horizontal, aiShipTypes[i])) { placed = true; } attempts++; } } } updateFleetStatus(); function handlePlayerShot(row, col) { if (!playerTurn) return; lastAttackType = 'regular'; // Set last attack type for regular shots // Clear target selection after firing selectedTarget = null; targetSelectionActive = false; lastSelectedCell = null; targetSelectorActive = false; availableTargets = []; // Play enhanced shooting sound effect with target confirmation LK.getSound('shoot').play(); var result = enemyGrid.checkHit(row, col); if (result === 'hit' || result === 'sunk') { LK.setScore(LK.getScore() + (result === 'sunk' ? 100 : 50)); if (enemyGrid.allShipsSunk()) { gamePhase = 'gameOver'; statusText.setText('Zafer! Tüm düşman gemileri yok edildi!'); turnText.setText('KAZANDINIZ!'); LK.showYouWin(); return; } } playerTurn = false; airBombardmentButton.visible = false; submarineAttackButton.visible = false; sihaAttackButton.visible = false; updateStatusText(); // AI turn after delay LK.setTimeout(function () { aiTurn(); }, 1000); } function executeAirBombardment() { if (playerAttackRights.air <= 0 || airBombardmentInProgress) return; playerAttackRights.air--; airBombardmentInProgress = true; lastAttackType = 'air'; // Set last attack type playerTurn = false; updateAttackRightsDisplay(); statusText.setText('Hava bombardımanı başlatıldı! Uçaklar hedefe yaklaşıyor...'); turnText.setText('HAVA SALDIRISI'); // Generate 5 random target positions var targets = []; var attempts = 0; while (targets.length < 5 && attempts < 100) { var row = Math.floor(Math.random() * gridSize); var col = Math.floor(Math.random() * gridSize); var duplicate = false; for (var i = 0; i < targets.length; i++) { if (targets[i].row === row && targets[i].col === col) { duplicate = true; break; } } if (!duplicate) { targets.push({ row: row, col: col }); } attempts++; } // Create aircraft animation var aircraft = game.attachAsset('missile', { anchorX: 0.5, anchorY: 0.5, x: -100, y: 200, scaleX: 2, scaleY: 2, rotation: Math.PI / 4 }); // Animate aircraft flying across screen tween(aircraft, { x: 2148, y: 300 }, { duration: 2000, easing: tween.linear, onFinish: function onFinish() { aircraft.destroy(); // Execute bombardment hits with delays executeTargetHits(targets, 0); } }); } function executeTargetHits(targets, currentIndex) { if (currentIndex >= targets.length) { // All hits completed LK.setTimeout(function () { airBombardmentInProgress = false; if (enemyGrid.allShipsSunk()) { gamePhase = 'gameOver'; statusText.setText('Zafer! Tüm düşman gemileri yok edildi!'); turnText.setText('KAZANDINIZ!'); LK.showYouWin(); return; } // AI turn after air bombardment aiLastAttackType = null; // Reset AI attack type to allow AI special attacks LK.setTimeout(function () { aiTurn(); }, 1000); }, 1000); return; } var target = targets[currentIndex]; // Create bomb falling animation var bomb = game.attachAsset('missile', { anchorX: 0.5, anchorY: 1, x: enemyGrid.x + target.col * 60 * 1.5 + 30 * 1.5, y: 100, alpha: 0.8 }); tween(bomb, { y: enemyGrid.y + target.row * 60 * 1.5 + 30 * 1.5, alpha: 0.3 }, { duration: 600, onFinish: function onFinish() { bomb.destroy(); // Check hit result var result = enemyGrid.checkHit(target.row, target.col); if (result === 'hit' || result === 'sunk') { LK.setScore(LK.getScore() + (result === 'sunk' ? 100 : 50)); } // Continue with next target after short delay LK.setTimeout(function () { executeTargetHits(targets, currentIndex + 1); }, 300); } }); } function executeSubmarineAttack() { if (playerAttackRights.submarine <= 0 || submarineAttackInProgress) return; playerAttackRights.submarine--; submarineAttackInProgress = true; lastAttackType = 'submarine'; // Set last attack type playerTurn = false; updateAttackRightsDisplay(); statusText.setText('Denizaltı saldırısı başlatıldı! Torpido hazırlanıyor...'); turnText.setText('DENİZALTI SALDIRISI'); // Find all enemy ships that are not yet sunk var availableTargets = []; for (var i = 0; i < enemyGrid.ships.length; i++) { var ship = enemyGrid.ships[i]; if (!ship.sunk) { // Add all unhit cells of this ship as potential targets for (var j = 0; j < ship.cells.length; j++) { var cellPos = ship.cells[j]; var cell = enemyGrid.cells[cellPos.row][cellPos.col]; if (!cell.isHit) { availableTargets.push({ row: cellPos.row, col: cellPos.col }); } } } } // If no available targets (all ships sunk or all remaining cells hit), just end if (availableTargets.length === 0) { submarineAttackInProgress = false; playerTurn = true; updateStatusText(); return; } // Select random target from available unhit ship cells var target = availableTargets[Math.floor(Math.random() * availableTargets.length)]; // Create submarine animation from bottom of screen var submarine = game.attachAsset('submarine', { anchorX: 0.5, anchorY: 0.5, x: enemyGrid.x + target.col * 60 * 1.5 + 30 * 1.5, y: 2732 + 100, scaleX: 2, scaleY: 2, alpha: 0.7 }); // Animate submarine rising tween(submarine, { y: enemyGrid.y + target.row * 60 * 1.5 + 200, alpha: 1 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { // Create torpedo var torpedo = game.attachAsset('missile', { anchorX: 0.5, anchorY: 0.5, x: submarine.x, y: submarine.y, scaleX: 1.5, scaleY: 1.5, rotation: -Math.PI / 2, alpha: 0.9 }); // Animate torpedo to target tween(torpedo, { x: enemyGrid.x + target.col * 60 * 1.5 + 30 * 1.5, y: enemyGrid.y + target.row * 60 * 1.5 + 30 * 1.5, alpha: 0.5 }, { duration: 800, easing: tween.linear, onFinish: function onFinish() { torpedo.destroy(); // Guaranteed hit on ship var result = enemyGrid.checkHit(target.row, target.col); LK.setScore(LK.getScore() + (result === 'sunk' ? 150 : 75)); // Submarine disappears tween(submarine, { y: 2732 + 100, alpha: 0 }, { duration: 1000, easing: tween.easeIn, onFinish: function onFinish() { submarine.destroy(); submarineAttackInProgress = false; if (enemyGrid.allShipsSunk()) { gamePhase = 'gameOver'; statusText.setText('Zafer! Tüm düşman gemileri yok edildi!'); turnText.setText('KAZANDINIZ!'); LK.showYouWin(); return; } // AI turn after submarine attack aiLastAttackType = null; // Reset AI attack type to allow AI special attacks LK.setTimeout(function () { aiTurn(); }, 1000); } }); } }); } }); } function executeSihaAttack() { if (playerAttackRights.siha <= 0 || sihaAttackInProgress) return; playerAttackRights.siha--; sihaAttackInProgress = true; lastAttackType = 'siha'; // Set last attack type playerTurn = false; updateAttackRightsDisplay(); statusText.setText('SİHA saldırısı başlatıldı! Hedef aranıyor...'); turnText.setText('SİHA SALDIRISI'); // Find all enemy ships that are not yet sunk var availableShips = []; for (var i = 0; i < enemyGrid.ships.length; i++) { var ship = enemyGrid.ships[i]; if (!ship.sunk) { availableShips.push(ship); } } // If no available ships, just end if (availableShips.length === 0) { sihaAttackInProgress = false; playerTurn = true; updateStatusText(); return; } // Select random ship to completely destroy var targetShip = availableShips[Math.floor(Math.random() * availableShips.length)]; var targetCells = []; // Get all cells of the target ship for (var j = 0; j < targetShip.cells.length; j++) { targetCells.push(targetShip.cells[j]); } // Create SIHA drone animation from top of screen var siha = game.attachAsset('missile', { anchorX: 0.5, anchorY: 0.5, x: -100, y: -100, scaleX: 1.8, scaleY: 1.8, rotation: Math.PI / 6, alpha: 0.9 }); // Animate SIHA flying to target area var targetCenterX = enemyGrid.x + targetCells[0].col * 60 * 1.5 + 30 * 1.5; var targetCenterY = enemyGrid.y + targetCells[0].row * 60 * 1.5 + 30 * 1.5; tween(siha, { x: targetCenterX, y: targetCenterY - 150, rotation: 0 }, { duration: 2500, easing: tween.easeInOut, onFinish: function onFinish() { // Hover for targeting tween(siha, { y: targetCenterY - 100, alpha: 1 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { // Execute precision strike - hit all cells of the ship executeShipDestruction(targetCells, 0, siha); } }); } }); } function executeShipDestruction(targetCells, currentIndex, siha) { if (currentIndex >= targetCells.length) { // All cells destroyed, SIHA returns tween(siha, { x: 2200, y: -100, alpha: 0.5 }, { duration: 2000, easing: tween.easeIn, onFinish: function onFinish() { siha.destroy(); sihaAttackInProgress = false; if (enemyGrid.allShipsSunk()) { gamePhase = 'gameOver'; statusText.setText('Zafer! Tüm düşman gemileri yok edildi!'); turnText.setText('KAZANDINIZ!'); LK.showYouWin(); return; } // AI turn after SIHA attack aiLastAttackType = null; // Reset AI attack type to allow AI special attacks LK.setTimeout(function () { aiTurn(); }, 1000); } }); return; } var target = targetCells[currentIndex]; // Create precision missile var missile = game.attachAsset('missile', { anchorX: 0.5, anchorY: 1, x: siha.x, y: siha.y, scaleX: 0.8, scaleY: 0.8, alpha: 0.9 }); tween(missile, { x: enemyGrid.x + target.col * 60 * 1.5 + 30 * 1.5, y: enemyGrid.y + target.row * 60 * 1.5 + 30 * 1.5, alpha: 0.4 }, { duration: 400, easing: tween.linear, onFinish: function onFinish() { missile.destroy(); // Guaranteed hit var result = enemyGrid.checkHit(target.row, target.col); if (result === 'hit' || result === 'sunk') { LK.setScore(LK.getScore() + (result === 'sunk' ? 200 : 100)); } // Continue with next target after short delay LK.setTimeout(function () { executeShipDestruction(targetCells, currentIndex + 1, siha); }, 200); } }); } function executeAIAirBombardment() { aiAttackRights.air--; aiLastAttackType = 'air'; updateAttackRightsDisplay(); statusText.setText('Düşman hava bombardımanı başlattı!'); turnText.setText('DÜŞMAN HAVA SALDIRISI'); // Generate 5 random target positions on player grid var targets = []; var attempts = 0; while (targets.length < 5 && attempts < 100) { var row = Math.floor(Math.random() * gridSize); var col = Math.floor(Math.random() * gridSize); var cell = playerGrid.cells[row][col]; // Only target untouched cells if (!cell.isHit && !cell.isMiss) { var duplicate = false; for (var i = 0; i < targets.length; i++) { if (targets[i].row === row && targets[i].col === col) { duplicate = true; break; } } if (!duplicate) { targets.push({ row: row, col: col }); } } attempts++; } // Create AI aircraft animation var aircraft = game.attachAsset('missile', { anchorX: 0.5, anchorY: 0.5, x: 2148, y: 200, scaleX: 2, scaleY: 2, rotation: -Math.PI * 3 / 4, tint: 0xFF0000 }); // Animate aircraft flying across screen tween(aircraft, { x: -100, y: 300 }, { duration: 2000, easing: tween.linear, onFinish: function onFinish() { aircraft.destroy(); executeAITargetHits(targets, 0); } }); } function executeAITargetHits(targets, currentIndex) { if (currentIndex >= targets.length) { // All hits completed LK.setTimeout(function () { if (playerGrid.allShipsSunk()) { gamePhase = 'gameOver'; statusText.setText('Yenilgi! Filonuz yok edildi!'); turnText.setText('KAYBETTİNİZ!'); LK.showGameOver(); return; } playerTurn = true; lastAttackType = null; updateStatusText(); }, 1000); return; } var target = targets[currentIndex]; // Create bomb falling animation var bomb = game.attachAsset('missile', { anchorX: 0.5, anchorY: 1, x: playerGrid.x + target.col * 60 * 1.5 + 30 * 1.5, y: 100, alpha: 0.8, tint: 0xFF0000 }); tween(bomb, { y: playerGrid.y + target.row * 60 * 1.5 + 30 * 1.5, alpha: 0.3 }, { duration: 600, onFinish: function onFinish() { bomb.destroy(); var result = playerGrid.checkHit(target.row, target.col); LK.setTimeout(function () { executeAITargetHits(targets, currentIndex + 1); }, 300); } }); } function executeAISubmarineAttack() { aiAttackRights.submarine--; aiLastAttackType = 'submarine'; updateAttackRightsDisplay(); statusText.setText('Düşman denizaltı saldırısı başlattı!'); turnText.setText('DÜŞMAN DENİZALTI SALDIRISI'); // Find player ships that are not yet sunk var availableTargets = []; for (var i = 0; i < playerGrid.ships.length; i++) { var ship = playerGrid.ships[i]; if (!ship.sunk) { for (var j = 0; j < ship.cells.length; j++) { var cellPos = ship.cells[j]; var cell = playerGrid.cells[cellPos.row][cellPos.col]; if (!cell.isHit) { availableTargets.push({ row: cellPos.row, col: cellPos.col }); } } } } if (availableTargets.length === 0) { playerTurn = true; lastAttackType = null; updateStatusText(); return; } // Select random target from available unhit ship cells var target = availableTargets[Math.floor(Math.random() * availableTargets.length)]; // Create submarine animation var submarine = game.attachAsset('submarine', { anchorX: 0.5, anchorY: 0.5, x: playerGrid.x + target.col * 60 * 1.5 + 30 * 1.5, y: 2732 + 100, scaleX: 2, scaleY: 2, alpha: 0.7, tint: 0xFF0000 }); // Animate submarine rising tween(submarine, { y: playerGrid.y + target.row * 60 * 1.5 + 200, alpha: 1 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { // Create torpedo var torpedo = game.attachAsset('missile', { anchorX: 0.5, anchorY: 0.5, x: submarine.x, y: submarine.y, scaleX: 1.5, scaleY: 1.5, rotation: -Math.PI / 2, alpha: 0.9, tint: 0xFF0000 }); // Animate torpedo to target tween(torpedo, { x: playerGrid.x + target.col * 60 * 1.5 + 30 * 1.5, y: playerGrid.y + target.row * 60 * 1.5 + 30 * 1.5, alpha: 0.5 }, { duration: 800, easing: tween.linear, onFinish: function onFinish() { torpedo.destroy(); var result = playerGrid.checkHit(target.row, target.col); // Submarine disappears tween(submarine, { y: 2732 + 100, alpha: 0 }, { duration: 1000, easing: tween.easeIn, onFinish: function onFinish() { submarine.destroy(); if (playerGrid.allShipsSunk()) { gamePhase = 'gameOver'; statusText.setText('Yenilgi! Filonuz yok edildi!'); turnText.setText('KAYBETTİNİZ!'); LK.showGameOver(); return; } playerTurn = true; lastAttackType = null; updateStatusText(); } }); } }); } }); } function executeAISihaAttack() { aiAttackRights.siha--; aiLastAttackType = 'siha'; updateAttackRightsDisplay(); statusText.setText('Düşman SİHA saldırısı başlattı!'); turnText.setText('DÜŞMAN SİHA SALDIRISI'); // Find all player ships that are not yet sunk var availableShips = []; for (var i = 0; i < playerGrid.ships.length; i++) { var ship = playerGrid.ships[i]; if (!ship.sunk) { availableShips.push(ship); } } if (availableShips.length === 0) { playerTurn = true; lastAttackType = null; updateStatusText(); return; } // Select random ship to completely destroy var targetShip = availableShips[Math.floor(Math.random() * availableShips.length)]; var targetCells = []; for (var j = 0; j < targetShip.cells.length; j++) { targetCells.push(targetShip.cells[j]); } // Create AI SIHA drone animation var siha = game.attachAsset('missile', { anchorX: 0.5, anchorY: 0.5, x: 2148, y: -100, scaleX: 1.8, scaleY: 1.8, rotation: -Math.PI / 6, alpha: 0.9, tint: 0xFF0000 }); // Animate SIHA flying to target area var targetCenterX = playerGrid.x + targetCells[0].col * 60 * 1.5 + 30 * 1.5; var targetCenterY = playerGrid.y + targetCells[0].row * 60 * 1.5 + 30 * 1.5; tween(siha, { x: targetCenterX, y: targetCenterY - 150, rotation: 0 }, { duration: 2500, easing: tween.easeInOut, onFinish: function onFinish() { tween(siha, { y: targetCenterY - 100, alpha: 1 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { executeAIShipDestruction(targetCells, 0, siha); } }); } }); } function executeAIShipDestruction(targetCells, currentIndex, siha) { if (currentIndex >= targetCells.length) { // All cells destroyed, SIHA returns tween(siha, { x: 2200, y: -100, alpha: 0.5 }, { duration: 2000, easing: tween.easeIn, onFinish: function onFinish() { siha.destroy(); if (playerGrid.allShipsSunk()) { gamePhase = 'gameOver'; statusText.setText('Yenilgi! Filonuz yok edildi!'); turnText.setText('KAYBETTİNİZ!'); LK.showGameOver(); return; } playerTurn = true; lastAttackType = null; updateStatusText(); } }); return; } var target = targetCells[currentIndex]; // Create precision missile var missile = game.attachAsset('missile', { anchorX: 0.5, anchorY: 1, x: siha.x, y: siha.y, scaleX: 0.8, scaleY: 0.8, alpha: 0.9, tint: 0xFF0000 }); tween(missile, { x: playerGrid.x + target.col * 60 * 1.5 + 30 * 1.5, y: playerGrid.y + target.row * 60 * 1.5 + 30 * 1.5, alpha: 0.4 }, { duration: 400, easing: tween.linear, onFinish: function onFinish() { missile.destroy(); var result = playerGrid.checkHit(target.row, target.col); LK.setTimeout(function () { executeAIShipDestruction(targetCells, currentIndex + 1, siha); }, 200); } }); } function aiTurn() { // Check if AI should use a special attack (30% chance if available and not consecutive) var shouldUseSpecialAttack = Math.random() < 0.3; var availableAttacks = []; // Check which attacks are available (have rights remaining and not the last attack type) if (aiAttackRights.air > 0 && aiLastAttackType !== 'air') { availableAttacks.push('air'); } if (aiAttackRights.submarine > 0 && aiLastAttackType !== 'submarine') { availableAttacks.push('submarine'); } if (aiAttackRights.siha > 0 && aiLastAttackType !== 'siha') { availableAttacks.push('siha'); } // Use special attack if conditions are met if (shouldUseSpecialAttack && availableAttacks.length > 0) { var selectedAttack = availableAttacks[Math.floor(Math.random() * availableAttacks.length)]; if (selectedAttack === 'air') { executeAIAirBombardment(); return; } else if (selectedAttack === 'submarine') { executeAISubmarineAttack(); return; } else if (selectedAttack === 'siha') { executeAISihaAttack(); return; } } // Regular attack logic var row, col; var attempts = 0; var targetFound = false; if (aiHuntMode && aiLastHit) { // First priority: Try adjacent cells to last hit var adjacents = [{ row: aiLastHit.row - 1, col: aiLastHit.col }, { row: aiLastHit.row + 1, col: aiLastHit.col }, { row: aiLastHit.row, col: aiLastHit.col - 1 }, { row: aiLastHit.row, col: aiLastHit.col + 1 }]; var validTargets = []; for (var i = 0; i < adjacents.length; i++) { var target = adjacents[i]; if (target.row >= 0 && target.row < gridSize && target.col >= 0 && target.col < gridSize) { var cell = playerGrid.cells[target.row][target.col]; if (!cell.isHit && !cell.isMiss) { validTargets.push(target); } } } if (validTargets.length > 0) { var chosen = validTargets[Math.floor(Math.random() * validTargets.length)]; row = chosen.row; col = chosen.col; targetFound = true; } else { // Second priority: Look for any hit cells that still have adjacent untested cells var allHitCells = []; for (var r = 0; r < gridSize; r++) { for (var c = 0; c < gridSize; c++) { var cell = playerGrid.cells[r][c]; if (cell.isHit && cell.hasShip) { // Check if this hit cell's ship is not sunk var shipNotSunk = false; for (var s = 0; s < playerGrid.ships.length; s++) { var ship = playerGrid.ships[s]; if (!ship.sunk) { for (var sc = 0; sc < ship.cells.length; sc++) { if (ship.cells[sc].row === r && ship.cells[sc].col === c) { shipNotSunk = true; break; } } } if (shipNotSunk) break; } if (shipNotSunk) { allHitCells.push({ row: r, col: c }); } } } } // Find hit cells that still have adjacent untested targets var validHitCells = []; for (var h = 0; h < allHitCells.length; h++) { var hitCell = allHitCells[h]; var hitAdjacents = [{ row: hitCell.row - 1, col: hitCell.col }, { row: hitCell.row + 1, col: hitCell.col }, { row: hitCell.row, col: hitCell.col - 1 }, { row: hitCell.row, col: hitCell.col + 1 }]; for (var ha = 0; ha < hitAdjacents.length; ha++) { var adj = hitAdjacents[ha]; if (adj.row >= 0 && adj.row < gridSize && adj.col >= 0 && adj.col < gridSize) { var adjCell = playerGrid.cells[adj.row][adj.col]; if (!adjCell.isHit && !adjCell.isMiss) { validHitCells.push(adj); } } } } if (validHitCells.length > 0) { var chosen = validHitCells[Math.floor(Math.random() * validHitCells.length)]; row = chosen.row; col = chosen.col; targetFound = true; } else { aiHuntMode = false; aiLastHit = null; } } } if (!targetFound) { // Random targeting do { row = Math.floor(Math.random() * gridSize); col = Math.floor(Math.random() * gridSize); attempts++; } while ((playerGrid.cells[row][col].isHit || playerGrid.cells[row][col].isMiss) && attempts < 100); } var result = playerGrid.checkHit(row, col); if (result === 'hit' || result === 'sunk') { aiLastHit = { row: row, col: col }; aiHuntMode = true; if (result === 'sunk') { aiHuntMode = false; aiLastHit = null; } else if (result === 'hit') { // Ship was hit but not sunk, continue attacking surrounding area LK.setTimeout(function () { aiTurn(); // Continue attacking immediately }, 1500); return; } if (playerGrid.allShipsSunk()) { gamePhase = 'gameOver'; statusText.setText('Yenilgi! Filonuz yok edildi!'); turnText.setText('KAYBETTİNİZ!'); LK.showGameOver(); return; } } playerTurn = true; lastAttackType = null; // Reset attack type after AI turn to allow alternating attacks aiLastAttackType = 'regular'; // Set AI's last attack as regular updateStatusText(); } // Fleet status displays var playerFleetStatus = new Container(); playerFleetStatus.x = 1700; playerFleetStatus.y = 1500; game.addChild(playerFleetStatus); var enemyFleetStatus = new Container(); enemyFleetStatus.x = 1700; enemyFleetStatus.y = 900; game.addChild(enemyFleetStatus); // Fleet status title texts var playerFleetTitle = new Text2('Filonuz', { size: 40, fill: 0x66FF66 }); playerFleetTitle.anchor.set(0.5, 0); playerFleetTitle.x = 0; playerFleetTitle.y = -60; playerFleetStatus.addChild(playerFleetTitle); var enemyFleetTitle = new Text2('Düşman Filosu', { size: 40, fill: 0xFF6666 }); enemyFleetTitle.anchor.set(0.5, 0); enemyFleetTitle.x = 0; enemyFleetTitle.y = -60; enemyFleetStatus.addChild(enemyFleetTitle); // Fleet status arrays var playerFleetDisplay = []; var enemyFleetDisplay = []; function updateFleetStatus() { // Initialize arrays if they don't exist if (!playerFleetDisplay) playerFleetDisplay = []; if (!enemyFleetDisplay) enemyFleetDisplay = []; // Clear existing displays for (var i = 0; i < playerFleetDisplay.length; i++) { playerFleetDisplay[i].destroy(); } for (var i = 0; i < enemyFleetDisplay.length; i++) { enemyFleetDisplay[i].destroy(); } playerFleetDisplay = []; enemyFleetDisplay = []; // Create player fleet status createFleetStatusDisplay(playerGrid, playerFleetStatus, playerFleetDisplay, true); // Create enemy fleet status createFleetStatusDisplay(enemyGrid, enemyFleetStatus, enemyFleetDisplay, false); } function createFleetStatusDisplay(grid, statusContainer, displayArray, isPlayerFleet) { for (var i = 0; i < grid.ships.length; i++) { var ship = grid.ships[i]; // Create main ship container var shipContainer = new Container(); shipContainer.x = 0; shipContainer.y = i * 50; // Reduced spacing for text-only statusContainer.addChild(shipContainer); displayArray.push(shipContainer); // Create ship info display (text only) createShipTextDisplay(ship, shipContainer, i, isPlayerFleet); } } function createShipTextDisplay(ship, container, shipIndex, isPlayerFleet) { // Ship name and status var shipName = shipTypes[shipIndex]; var statusText = shipName; var statusColor = 0xCCCCCC; // Determine status and color if (isPlayerFleet) { if (ship.sunk) { statusColor = 0xFF4444; statusText += ' - BATIK (' + ship.hits + '/' + ship.length + ')'; } else if (ship.hits > 0) { statusColor = 0xFFAA00; statusText += ' - Hasarlı (' + ship.hits + '/' + ship.length + ')'; } else { statusColor = 0x66FF99; statusText += ' - Sağlam (' + ship.hits + '/' + ship.length + ')'; } } else { // Enemy fleet - only show detailed status if damaged or sunk if (ship.sunk) { statusColor = 0xFF4444; statusText += ' - BATIK (' + ship.hits + '/' + ship.length + ')'; } else if (ship.hits > 0) { statusColor = 0xFFAA00; statusText += ' - Hasarlı (' + ship.hits + '/' + ship.length + ')'; } else { statusColor = 0x888888; statusText += ' - Bilinmiyor'; } } var nameText = new Text2(statusText, { size: 28, fill: statusColor }); nameText.anchor.set(0, 0); nameText.x = 0; nameText.y = 0; container.addChild(nameText); } // Removed - no longer needed for text-only display // Removed - no longer needed for text-only display // Game info page variables var gameInfoShown = false; var currentInfoPage = 0; var totalInfoPages = 3; // Difficulty selection variables var difficultySelected = false; var selectedDifficulty = 'easy'; // default var gridSize = 8; // will be updated based on difficulty // Game information page UI var gameInfoContainer = new Container(); gameInfoContainer.x = 2048 / 2; gameInfoContainer.y = 2732 / 2; game.addChild(gameInfoContainer); // Info page background var infoBg = LK.getAsset('water', { width: 1800, height: 2400, x: -900, y: -1200, color: 0x001122 }); infoBg.alpha = 0.95; gameInfoContainer.addChild(infoBg); // Info page title var infoTitle = new Text2('AMİRAL BATTI', { size: 80, fill: 0xFFD700 }); infoTitle.anchor.set(0.5, 0.5); infoTitle.x = 0; infoTitle.y = -1000; gameInfoContainer.addChild(infoTitle); // Page indicator var pageIndicator = new Text2('Sayfa 1 / 3', { size: 50, fill: 0xCCCCCC }); pageIndicator.anchor.set(0.5, 0.5); pageIndicator.x = 0; pageIndicator.y = -900; gameInfoContainer.addChild(pageIndicator); // Info content container var infoContentContainer = new Container(); infoContentContainer.x = 0; infoContentContainer.y = -400; gameInfoContainer.addChild(infoContentContainer); // Navigation buttons var prevButton = new Text2('← ÖNCEKİ', { size: 60, fill: 0x888888 }); prevButton.anchor.set(0.5, 0.5); prevButton.x = -300; prevButton.y = 1000; gameInfoContainer.addChild(prevButton); var nextButton = new Text2('SONRAKİ →', { size: 60, fill: 0x00FF00 }); nextButton.anchor.set(0.5, 0.5); nextButton.x = 300; nextButton.y = 1000; gameInfoContainer.addChild(nextButton); var startGameButton = new Text2('OYUNA BAŞLA', { size: 70, fill: 0xFF0000 }); startGameButton.anchor.set(0.5, 0.5); startGameButton.x = 0; startGameButton.y = 900; startGameButton.visible = false; gameInfoContainer.addChild(startGameButton); // Info page content arrays var infoPages = [ // Page 1: Basic Rules ['OYUN KURALLARI', '', '• Deniz savaşı oyununda amacınız düşman', ' filosunu tamamen yok etmektir', '', '• Filonuzda 5 farklı gemi türü bulunur:', ' - Uçak Gemisi (5 kare)', ' - Savaş Gemisi (4 kare)', ' - Kruvazör x2 (3 kare)', ' - Muhrip (2 kare)', '', '• Gemiler yatay veya dikey olarak', ' yerleştirilebilir', '', '• Düşman ızgarasına tıklayarak ateş edin', '• İsabet: Kırmızı, Kaçan: Mavi'], // Page 2: Special Attacks ['ÖZEL SALDIRILAR', '', '🛩️ HAVA BOMBARDIMANI (2 Hak)', '• 5 rastgele hedefe eş zamanlı saldırı', '• Geniş alan hasarı', '• Ardışık kullanılamaz', '', '🚢 DENİZALTI SALDIRISI (2 Hak)', '• Düşman gemisine garantili isabet', '• Hedef otomatik seçilir', '• Yüksek hasar', '', '🛸 SİHA SALDIRISI (2 Hak)', '• Seçilen gemiyi tamamen yok eder', '• Hassas hedefleme', '• En güçlü saldırı türü'], // Page 3: Game Tips ['OYUN İPUÇLARI', '', '⚡ STRATEJİ TAVSİYELERİ:', '', '• Gemilerinizi rastgele yerleştirin', '• Özel saldırıları akıllıca kullanın', '• Düşman vuruşlarından kalıp çıkarın', '• Isabet aldığınız bölgelerin etrafını', ' sistematik olarak tarayın', '', '🎯 ZORLUK SEVİYELERİ:', '• Kolay: Yavaş yapay zeka', '• Orta: Dengeli yapay zeka', '• Zor: Agresif yapay zeka', '', '• Düşman da özel saldırılara sahiptir!', '• Savunmanızı güçlü tutun!']]; // Button event handlers prevButton.down = function (x, y, obj) { if (currentInfoPage > 0) { currentInfoPage--; updateInfoPage(); } }; nextButton.down = function (x, y, obj) { if (currentInfoPage < totalInfoPages - 1) { currentInfoPage++; updateInfoPage(); } }; startGameButton.down = function (x, y, obj) { gameInfoShown = true; gameInfoContainer.visible = false; difficultyContainer.visible = true; }; function updateInfoPage() { // Clear existing content for (var i = infoContentContainer.children.length - 1; i >= 0; i--) { infoContentContainer.children[i].destroy(); } // Update page indicator pageIndicator.setText('Sayfa ' + (currentInfoPage + 1) + ' / ' + totalInfoPages); // Add new content var content = infoPages[currentInfoPage]; for (var i = 0; i < content.length; i++) { var line = content[i]; var isTitle = i === 0; var isEmpty = line === ''; if (!isEmpty) { var textSize = isTitle ? 80 : 55; var textColor = isTitle ? 0xFFD700 : line.startsWith('•') ? 0xCCCCCC : line.startsWith('🛩️') || line.startsWith('🚢') || line.startsWith('🛸') ? 0x00FFFF : line.startsWith('⚡') || line.startsWith('🎯') ? 0xFFAA00 : 0xFFFFFF; var lineText = new Text2(line, { size: textSize, fill: textColor }); lineText.anchor.set(0.5, 0); lineText.x = 0; lineText.y = i * 60 - 200; infoContentContainer.addChild(lineText); } } // Update button visibility prevButton.visible = currentInfoPage > 0; prevButton.fill = currentInfoPage > 0 ? 0xFFFFFF : 0x888888; nextButton.visible = currentInfoPage < totalInfoPages - 1; nextButton.fill = currentInfoPage < totalInfoPages - 1 ? 0x00FF00 : 0x888888; startGameButton.visible = currentInfoPage === totalInfoPages - 1; } // Initialize first page updateInfoPage(); // Difficulty selection UI var difficultyContainer = new Container(); difficultyContainer.x = 2048 / 2; difficultyContainer.y = 2732 / 2; difficultyContainer.visible = false; game.addChild(difficultyContainer); var difficultyTitle = new Text2('Zorluk Seviyesi Seçin', { size: 80, fill: 0xFFFFFF }); difficultyTitle.anchor.set(0.5, 0.5); difficultyTitle.x = 0; difficultyTitle.y = -200; difficultyContainer.addChild(difficultyTitle); // Easy button var easyButton = new Text2('KOLAY (8x8)', { size: 65, fill: 0x00FF00 }); easyButton.anchor.set(0.5, 0.5); easyButton.x = -400; easyButton.y = 0; difficultyContainer.addChild(easyButton); easyButton.down = function (x, y, obj) { selectedDifficulty = 'easy'; gridSize = 8; startGameWithDifficulty(); }; // Medium button var mediumButton = new Text2('ORTA (8x8)', { size: 65, fill: 0xFFFF00 }); mediumButton.anchor.set(0.5, 0.5); mediumButton.x = 0; mediumButton.y = 0; difficultyContainer.addChild(mediumButton); mediumButton.down = function (x, y, obj) { selectedDifficulty = 'medium'; gridSize = 8; startGameWithDifficulty(); }; // Hard button var hardButton = new Text2('ZOR (8x8)', { size: 65, fill: 0xFF0000 }); hardButton.anchor.set(0.5, 0.5); hardButton.x = 400; hardButton.y = 0; difficultyContainer.addChild(hardButton); hardButton.down = function (x, y, obj) { selectedDifficulty = 'hard'; gridSize = 8; startGameWithDifficulty(); }; function startGameWithDifficulty() { difficultySelected = true; difficultyContainer.visible = false; // Recreate grids with new size playerGrid.destroy(); enemyGrid.destroy(); playerGrid = new GameGrid(true); enemyGrid = new GameGrid(false); // Scale grids based on difficulty to fit screen - increased for closer view var baseScale = selectedDifficulty === 'easy' ? 2.0 : selectedDifficulty === 'medium' ? 1.8 : 1.5; playerGrid.scaleX = baseScale; playerGrid.scaleY = baseScale; enemyGrid.scaleX = baseScale; enemyGrid.scaleY = baseScale; // Center grids on screen var gridWidth = gridSize * 60 * baseScale; var screenCenterX = 2048 / 2; var gridCenterX = gridWidth / 2; playerGrid.x = screenCenterX - gridCenterX; playerGrid.y = 1400; enemyGrid.x = screenCenterX - gridCenterX; enemyGrid.y = 400; // Store original positions for battle phase repositioning playerGrid.originalX = playerGrid.x; playerGrid.originalY = playerGrid.y; playerGrid.originalScaleX = playerGrid.scaleX; playerGrid.originalScaleY = playerGrid.scaleY; game.addChild(playerGrid); game.addChild(enemyGrid); // Hide enemy grid during placement phase enemyGrid.visible = false; // Update labels position enemyLabel.x = enemyGrid.x + gridSize * 60 * baseScale / 2; enemyLabel.y = enemyGrid.y - 60; playerLabel.x = playerGrid.x + gridSize * 60 * baseScale / 2; playerLabel.y = playerGrid.y - 60; // Add separator line between player and enemy grids var separatorLine = game.attachAsset('gridLine', { width: 2048, height: 4, x: 0, y: (enemyGrid.y + gridSize * 60 * baseScale + playerGrid.y) / 2, color: 0xFFFFFF }); // Reset game state gamePhase = 'placement'; currentShipIndex = 0; // Initial setup updateStatusText(); updateAttackRightsDisplay(); } // Control pad variables var controlPadActive = false; var controlPadContainer = new Container(); var controlPadKnob = null; var controlPadBaseCenter = { x: 0, y: 0 }; var controlPadMaxDistance = 120; var cursorSpeed = 8; var lastControlPadUpdate = 0; // Create cursor/crosshair system var cursorContainer = new Container(); game.addChild(cursorContainer); // Create control pad controlPadContainer.x = 2048 / 2; controlPadContainer.y = 2732 - 550; controlPadContainer.scaleX = 3.6; controlPadContainer.scaleY = 3.6; controlPadContainer.visible = false; game.addChild(controlPadContainer); // Control pad border var controlPadBorder = controlPadContainer.attachAsset('controlPadBorder', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 }); // Control pad base var controlPadBase = controlPadContainer.attachAsset('controlPadBase', { anchorX: 0.5, anchorY: 0.5, alpha: 0.6 }); // Control pad knob controlPadKnob = controlPadContainer.attachAsset('controlPadKnob', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); // Store base center position controlPadBaseCenter.x = 0; controlPadBaseCenter.y = 0; // Create simplified targeting crosshair for enemy area - sized to fit single cell var targetCrosshair = cursorContainer.attachAsset('crosshairH', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8, scaleX: 0.8, scaleY: 0.8 }); var targetCenter = cursorContainer.attachAsset('cursorCenter', { anchorX: 0.5, anchorY: 0.5, alpha: 1.0, scaleX: 1.0, scaleY: 1.0 }); // Initialize cursor position cursorContainer.x = 2048 / 2; cursorContainer.y = 2732 / 2; cursorContainer.visible = false; // Initially hidden // Add subtle pulse animation to cursor ring for better visibility var cursorPulseDirection = 1; var cursorPulseTimer = 0; function updateCursorPulse() { cursorPulseTimer++; if (cursorPulseTimer % 40 === 0) { // Every 0.67 seconds at 60fps for smoother targeting pulse if (cursorPulseDirection === 1) { // Pulse crosshair for precision feedback - sized for single cell tween(targetCenter, { scaleX: 1.3, scaleY: 1.3, alpha: 0.7 }, { duration: 600, easing: tween.easeInOut }); tween(targetCrosshair, { scaleX: 1.0, scaleY: 1.0, alpha: 0.6 }, { duration: 600, easing: tween.easeInOut }); cursorPulseDirection = -1; } else { tween(targetCenter, { scaleX: 1.0, scaleY: 1.0, alpha: 1.0 }, { duration: 600, easing: tween.easeInOut }); tween(targetCrosshair, { scaleX: 0.8, scaleY: 0.8, alpha: 0.8 }, { duration: 600, easing: tween.easeInOut }); cursorPulseDirection = 1; } } } // Hide all game elements initially playerGrid.visible = false; enemyGrid.visible = false; statusText.visible = false; turnText.visible = false; enemyLabel.visible = false; playerLabel.visible = false; rotateButton.visible = false; autoPlaceButton.visible = false; startBattleButton.visible = false; airBombardmentButton.visible = false; submarineAttackButton.visible = false; sihaAttackButton.visible = false; attackRightsContainer.visible = false; playerFleetStatus.visible = false; enemyFleetStatus.visible = false; shipPreviewContainer.visible = false; // Control pad event handlers controlPadContainer.down = function (x, y, obj) { if (gamePhase === 'battle' && playerTurn && !airBombardmentInProgress && !submarineAttackInProgress && !sihaAttackInProgress) { controlPadActive = true; // Use local coordinates for better control var localPos = { x: x, y: y }; // Calculate distance and constrain properly var distance = Math.sqrt(localPos.x * localPos.x + localPos.y * localPos.y); if (distance > controlPadMaxDistance) { var angle = Math.atan2(localPos.y, localPos.x); localPos.x = Math.cos(angle) * controlPadMaxDistance; localPos.y = Math.sin(angle) * controlPadMaxDistance; } controlPadKnob.x = localPos.x; controlPadKnob.y = localPos.y; } }; controlPadContainer.up = function (x, y, obj) { // If this was a quick tap (not a drag), try to fire at selected target if (controlPadActive && gamePhase === 'battle' && playerTurn) { var tapDistance = Math.sqrt(controlPadKnob.x * controlPadKnob.x + controlPadKnob.y * controlPadKnob.y); if (tapDistance < 20) { // Quick tap threshold - fire at selected target if valid if (selectedTarget && targetSelectionActive && !selectedTarget.cell.isHit && !selectedTarget.cell.isMiss) { // Enhanced target confirmation feedback tween(targetCenter, { scaleX: 4.0, scaleY: 4.0, alpha: 0.8 }, { duration: 150, easing: tween.easeIn, onFinish: function onFinish() { // Fire at the selected target handlePlayerShot(selectedTarget.row, selectedTarget.col); } }); // Add visual confirmation flash tween(targetCrosshair, { scaleX: 3.0, scaleY: 3.0, alpha: 0.4 }, { duration: 150, easing: tween.easeIn }); } else { // Try to fire at current cursor position as fallback if (enemyGrid.visible) { var localX = cursorContainer.x - enemyGrid.x; var localY = cursorContainer.y - enemyGrid.y; var cellSize = 60 * enemyGrid.scaleX; if (localX >= 0 && localX < gridSize * cellSize && localY >= 0 && localY < gridSize * cellSize) { var gridCol = Math.floor(localX / cellSize); var gridRow = Math.floor(localY / cellSize); if (gridRow >= 0 && gridRow < gridSize && gridCol >= 0 && gridCol < gridSize) { var targetCell = enemyGrid.cells[gridRow][gridCol]; if (!targetCell.isHit && !targetCell.isMiss) { handlePlayerShot(gridRow, gridCol); } } } } } } } controlPadActive = false; // Animate knob back to center tween(controlPadKnob, { x: 0, y: 0 }, { duration: 200, easing: tween.easeOut }); }; controlPadContainer.move = function (x, y, obj) { if (gamePhase === 'battle' && playerTurn && !airBombardmentInProgress && !submarineAttackInProgress && !sihaAttackInProgress) { // Convert coordinates to local space properly var localPos = { x: x, y: y }; // Calculate distance from center var distance = Math.sqrt(localPos.x * localPos.x + localPos.y * localPos.y); // Constrain knob within the control pad with smooth movement if (distance > controlPadMaxDistance) { var angle = Math.atan2(localPos.y, localPos.x); localPos.x = Math.cos(angle) * controlPadMaxDistance; localPos.y = Math.sin(angle) * controlPadMaxDistance; } // Smooth knob movement for better responsiveness controlPadKnob.x = localPos.x; controlPadKnob.y = localPos.y; // Move cursor directly based on knob position var knobOffsetX = controlPadKnob.x / controlPadMaxDistance; var knobOffsetY = controlPadKnob.y / controlPadMaxDistance; var dynamicSpeed = cursorSpeed * 1.0; // Default responsiveness cursorContainer.x += knobOffsetX * dynamicSpeed; cursorContainer.y += knobOffsetY * dynamicSpeed; // Keep cursor within screen bounds cursorContainer.x = Math.max(20, Math.min(2028, cursorContainer.x)); cursorContainer.y = Math.max(20, Math.min(2712, cursorContainer.y)); // Set control pad as active when moving controlPadActive = true; } }; // Target selection variables var selectedTarget = null; var targetSelectionActive = false; var lastSelectedCell = null; // Selected cell cursor in enemy waters var selectedCellCursor = new Container(); selectedCellCursor.zIndex = 1000; // Ensure cursor is always on top game.addChild(selectedCellCursor); // Create cursor components for selected cell - sized to fit single cell var selectedCellBorder = selectedCellCursor.attachAsset('cursorRing', { anchorX: 0.5, anchorY: 0.5, alpha: 0.9, scaleX: 1.2, scaleY: 1.2, tint: 0x00ffff }); var selectedCellInner = selectedCellCursor.attachAsset('cursorCenter', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8, scaleX: 1.5, scaleY: 1.5, tint: 0xffff00 }); // Initially hide the selected cell cursor selectedCellCursor.visible = false; // Add cursor movement handler with enhanced aiming for enemy waters game.move = function (x, y, obj) { // Update cursor position based on control pad if active, otherwise use mouse/touch if (!controlPadActive && gamePhase === 'battle' && enemyGrid.visible) { // Restrict cursor movement to enemy grid area only var localX = x - enemyGrid.x; var localY = y - enemyGrid.y; var cellSize = 60 * enemyGrid.scaleX; var gridWidth = gridSize * cellSize; var gridHeight = gridSize * cellSize; // Constrain to enemy grid boundaries if (localX >= 0 && localX < gridWidth && localY >= 0 && localY < gridHeight) { cursorContainer.x = x; cursorContainer.y = y; } } else if (!controlPadActive && gamePhase !== 'battle') { // Allow free movement outside battle phase cursorContainer.x = x; cursorContainer.y = y; } // Show cursor during battle phase if (gamePhase === 'battle') { cursorContainer.visible = true; // Enhanced targeting for enemy waters if (enemyGrid.visible) { // Convert screen coordinates to grid coordinates var localX = cursorContainer.x - enemyGrid.x; var localY = cursorContainer.y - enemyGrid.y; var cellSize = 60 * enemyGrid.scaleX; // Check if cursor is over enemy grid if (localX >= 0 && localX < gridSize * cellSize && localY >= 0 && localY < gridSize * cellSize) { var gridCol = Math.floor(localX / cellSize); var gridRow = Math.floor(localY / cellSize); // Check if valid target if (gridRow >= 0 && gridRow < gridSize && gridCol >= 0 && gridCol < gridSize) { var targetCell = enemyGrid.cells[gridRow][gridCol]; var currentCellKey = gridRow + '_' + gridCol; // Check if we've moved to a new cell for target selection if (lastSelectedCell !== currentCellKey) { lastSelectedCell = currentCellKey; selectedTarget = { row: gridRow, col: gridCol, cell: targetCell }; targetSelectionActive = true; // Update selected cell cursor position var cellCenterX = enemyGrid.x + gridCol * cellSize + cellSize / 2; var cellCenterY = enemyGrid.y + gridRow * cellSize + cellSize / 2; selectedCellCursor.x = cellCenterX; selectedCellCursor.y = cellCenterY; selectedCellCursor.visible = true; // Bring cursor to front to ensure visibility above enemy grid game.removeChild(selectedCellCursor); game.addChild(selectedCellCursor); // Animate selected cell cursor with pulsing effect - sized for single cell tween(selectedCellBorder, { scaleX: 1.4, scaleY: 1.4, alpha: 0.7 }, { duration: 400, easing: tween.easeInOut }); tween(selectedCellInner, { scaleX: 1.7, scaleY: 1.7, alpha: 0.6 }, { duration: 400, easing: tween.easeInOut }); // Stop any ongoing crosshair animations tween.stop(targetCenter); tween.stop(targetCrosshair); } if (!targetCell.isHit && !targetCell.isMiss) { // Enhanced aiming for enemy waters - bright targeting crosshair targetCrosshair.tint = 0x00ffff; targetCenter.tint = 0xff4444; // Enhanced aiming animation for valid targets - sized for single cell tween(targetCenter, { scaleX: 1.3, scaleY: 1.3, alpha: 1.0 }, { duration: 300, easing: tween.easeOut }); tween(targetCrosshair, { scaleX: 1.0, scaleY: 1.0, alpha: 1.0 }, { duration: 300, easing: tween.easeOut }); } else { // Already targeted - red crosshair with warning colors targetCrosshair.tint = 0xff0000; targetCenter.tint = 0xff0000; // Scale up but reduce opacity for invalid targets - sized for single cell tween(targetCenter, { scaleX: 1.0, scaleY: 1.0, alpha: 0.8 }, { duration: 200, easing: tween.easeOut }); tween(targetCrosshair, { scaleX: 0.9, scaleY: 0.9, alpha: 0.7 }, { duration: 200, easing: tween.easeOut }); } } else { // Outside enemy grid targeting area - hide cursor completely selectedTarget = null; targetSelectionActive = false; lastSelectedCell = null; cursorContainer.visible = false; } } else { // Outside enemy waters - hide all cursors selectedTarget = null; targetSelectionActive = false; lastSelectedCell = null; // Hide selected cell cursor when outside enemy waters selectedCellCursor.visible = false; cursorContainer.visible = false; } } } else { // Hide cursor during other phases cursorContainer.visible = false; selectedTarget = null; targetSelectionActive = false; lastSelectedCell = null; // Hide selected cell cursor during non-battle phases selectedCellCursor.visible = false; } }; // Play background music from game start LK.playMusic('deniz'); // Show info page initially gameInfoContainer.visible = true; game.update = function () { if (!gameInfoShown) { // Show info page gameInfoContainer.visible = true; difficultyContainer.visible = false; } else if (!difficultySelected) { // Show difficulty selection gameInfoContainer.visible = false; difficultyContainer.visible = true; } else if (difficultySelected) { // Show game elements once difficulty is selected gameInfoContainer.visible = false; difficultyContainer.visible = false; playerGrid.visible = true; enemyGrid.visible = gamePhase === 'battle'; statusText.visible = true; turnText.visible = true; enemyLabel.visible = gamePhase === 'battle'; playerLabel.visible = true; rotateButton.visible = gamePhase === 'placement'; autoPlaceButton.visible = gamePhase === 'placement'; startBattleButton.visible = gamePhase === 'placement' && currentShipIndex >= shipSizes.length; shipPreviewContainer.visible = gamePhase === 'placement' && currentShipIndex < shipSizes.length; playerFleetStatus.visible = true; enemyFleetStatus.visible = true; // Update cursor visibility and animation if (gamePhase === 'battle' && playerTurn && !airBombardmentInProgress && !submarineAttackInProgress && !sihaAttackInProgress) { cursorContainer.visible = true; controlPadContainer.visible = true; updateCursorPulse(); // Continuous cursor movement based on control pad position if (controlPadContainer.visible) { var knobOffsetX = controlPadKnob.x / controlPadMaxDistance; var knobOffsetY = controlPadKnob.y / controlPadMaxDistance; // Calculate movement speed based on knob distance for variable sensitivity var knobDistance = Math.sqrt(knobOffsetX * knobOffsetX + knobOffsetY * knobOffsetY); // Only move cursor if knob is displaced significantly if (knobDistance > 0.05) { var dynamicSpeed = cursorSpeed * (0.5 + knobDistance * 0.5); // Default speed scaling // Calculate new cursor position var newX = cursorContainer.x + knobOffsetX * dynamicSpeed; var newY = cursorContainer.y + knobOffsetY * dynamicSpeed; // Restrict cursor movement to enemy grid area only var cellSize = 60 * enemyGrid.scaleX; var gridWidth = gridSize * cellSize; var gridHeight = gridSize * cellSize; var enemyGridLeft = enemyGrid.x; var enemyGridRight = enemyGrid.x + gridWidth; var enemyGridTop = enemyGrid.y; var enemyGridBottom = enemyGrid.y + gridHeight; // Constrain cursor to enemy grid boundaries cursorContainer.x = Math.max(enemyGridLeft, Math.min(enemyGridRight - 1, newX)); cursorContainer.y = Math.max(enemyGridTop, Math.min(enemyGridBottom - 1, newY)); } } } else { cursorContainer.visible = false; controlPadContainer.visible = false; } } };
===================================================================
--- original.js
+++ change.js
@@ -2102,9 +2102,9 @@
x: 0,
y: 0
};
var controlPadMaxDistance = 120;
-var cursorSpeed = 4;
+var cursorSpeed = 8;
var lastControlPadUpdate = 0;
// Create cursor/crosshair system
var cursorContainer = new Container();
game.addChild(cursorContainer);
@@ -2318,9 +2318,9 @@
controlPadKnob.y = localPos.y;
// Move cursor directly based on knob position
var knobOffsetX = controlPadKnob.x / controlPadMaxDistance;
var knobOffsetY = controlPadKnob.y / controlPadMaxDistance;
- var dynamicSpeed = cursorSpeed * 0.7; // Further reduced responsiveness for better control
+ var dynamicSpeed = cursorSpeed * 1.0; // Default responsiveness
cursorContainer.x += knobOffsetX * dynamicSpeed;
cursorContainer.y += knobOffsetY * dynamicSpeed;
// Keep cursor within screen bounds
cursorContainer.x = Math.max(20, Math.min(2028, cursorContainer.x));
@@ -2542,10 +2542,10 @@
var knobOffsetY = controlPadKnob.y / controlPadMaxDistance;
// Calculate movement speed based on knob distance for variable sensitivity
var knobDistance = Math.sqrt(knobOffsetX * knobOffsetX + knobOffsetY * knobOffsetY);
// Only move cursor if knob is displaced significantly
- if (knobDistance > 0.1) {
- var dynamicSpeed = cursorSpeed * (0.2 + knobDistance * 0.3); // Optimized speed scaling for precise control
+ if (knobDistance > 0.05) {
+ var dynamicSpeed = cursorSpeed * (0.5 + knobDistance * 0.5); // Default speed scaling
// Calculate new cursor position
var newX = cursorContainer.x + knobOffsetX * dynamicSpeed;
var newY = cursorContainer.y + knobOffsetY * dynamicSpeed;
// Restrict cursor movement to enemy grid area only
sketch tarzında carrier gemisi. In-Game asset. 2d. High contrast. No shadows
sketch tarzında cruıser savas gemısı. In-Game asset. 2d. High contrast. No shadows
skecth tarzında destroyer savas gemisi. In-Game asset. 2d. High contrast. No shadows
suya düşen füze. In-Game asset. 2d. High contrast. No shadows
suya düşen nesne sonrası oluşan dalgacıklar. In-Game asset. 2d. High contrast. No shadows
patlama sonrası kıvılcımlar. In-Game asset. 2d. High contrast. No shadows
aşağı yönde giden füze. In-Game asset. 2d. High contrast. No shadows
denizaltı gemisi torpidosundan ateşleme. In-Game asset. 2d. High contrast. No shadows