User prompt
you again rotate every ship i mean i picked destroyer and placed to somewhere then when i click rotate button it should rotate.
User prompt
when i click one of the ships just rotate it not others
User prompt
no look i mean after i place the ship to somewhere, with rotate button i want to rotate it
User prompt
rotate button does not work
User prompt
when i click and drag ship to place it automatically being rotated so do not rotate it we have rotate button to rotate it whenever we want
User prompt
put start button a little bit down
User prompt
put carrier ship to next to them it is mixed to cruiser
User prompt
after being placed it is not changing rotation it stays the same also make sure that i will be able to put ships back with drag and drop again when i want to put it back.
User prompt
after placing, when i click on it it returns back. But i want when i click it should rotate. also the the one extra ship put it right not under the ships.
User prompt
okay do it 3 columns
User prompt
put ships neatly they all mix each other. Also whenever i rotate they mix. Additionally add start button. When i click game starts
User prompt
put ships vertically 6 of them 2*3 style and one next to them
User prompt
is not drag and drop active??? i cannot click and bring to place i want
User prompt
bring the previous version to back i dont mean it. I meant the area under rotate button where ships are. Then with drag and drop basically placing the ships to areas where we want.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'toGlobal')' in or related to this line: 'var globalPos = game.toLocal(obj.parent.toGlobal({' Line Number: 881
User prompt
make the area that we can see ships before hand with drag and drop place our ships.
User prompt
if we place by mistaken we cannot bring it back make it like that. Whenever player wants to change the location changes
User prompt
and 2 cruiser pls
User prompt
i want to increase the number of destroyer ships to 3
User prompt
make rotate button bigger
User prompt
if one side finds one give another chance until fails
User prompt
you do not understand me. Like sea battle . The main purpose of game is guessing. If when i click the part of ship and find it and if this part can be seen how can people guess other parts. All other parts are automatically being revealed and that does not make sense. I said when i click the parts keep them invisible just show hitmaker. When it is completely revealed, show the the full assests of ship.
User prompt
keep assests after fully blown up. When it is completely found, just bring assets instead of hitmaker.
User prompt
when i click just keep hitmaker asset
User prompt
after fully blown up make each part different colors. Also when i click and find a part dont make it colorful just keep it colorless. After fully finding the entire parts of ship make different colorful assets ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var GridTile = Container.expand(function (x, y, isPlayerGrid) {
var self = Container.call(this);
self.gridX = x;
self.gridY = y;
self.isPlayerGrid = isPlayerGrid;
self.hasShip = false;
self.isHit = false;
self.shipId = null;
self.shipPartIndex = null;
self.shipPartGraphic = null;
var background = self.attachAsset('waterTile', {
anchorX: 0.5,
anchorY: 0.5
});
self.marker = null;
self.setShip = function (shipId, partIndex, isHorizontal) {
self.hasShip = true;
self.shipId = shipId;
self.shipPartIndex = partIndex;
// Only show ship parts on player grid during placement
if (self.isPlayerGrid) {
var assetName = shipId + 'Part' + partIndex + 'Normal';
self.shipPartGraphic = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Apply rotation if ship is vertical (not horizontal)
if (!isHorizontal) {
self.shipPartGraphic.rotation = Math.PI / 2; // 90 degrees
}
}
// For enemy grid, don't show ship parts initially - they'll be revealed when hit
};
self.markHit = function () {
if (!self.isHit) {
self.isHit = true;
if (self.hasShip) {
// For ship hits, only show hit marker - keep ship parts invisible for guessing
self.marker = self.attachAsset('hitMarker', {
anchorX: 0.5,
anchorY: 0.5
});
// Explosion effect for ship hit
self.marker.scaleX = 0.1;
self.marker.scaleY = 0.1;
self.marker.alpha = 0.8;
tween(self.marker, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 1
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.marker, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
// Flash the background tile
var background = self.children[0]; // Get the water tile background
tween(background, {
tint: 0xff4444
}, {
duration: 150,
onFinish: function onFinish() {
tween(background, {
tint: 0xffffff
}, {
duration: 150
});
}
});
} else {
self.marker = self.attachAsset('missMarker', {
anchorX: 0.5,
anchorY: 0.5
});
// Small splash effect for miss
self.marker.scaleX = 0.3;
self.marker.scaleY = 0.3;
tween(self.marker, {
scaleX: 1,
scaleY: 1
}, {
duration: 400,
easing: tween.bounceOut
});
}
}
};
self.blowUpShipPart = function (keepColorless) {
if (self.shipPartGraphic) {
// Store the current rotation before removing
var currentRotation = self.shipPartGraphic.rotation;
self.removeChild(self.shipPartGraphic);
var assetName = self.shipId + 'Part' + self.shipPartIndex + 'Blown';
self.shipPartGraphic = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Restore the rotation
self.shipPartGraphic.rotation = currentRotation;
// Explosion effect for individual part
self.shipPartGraphic.scaleX = 0.2;
self.shipPartGraphic.scaleY = 0.2;
self.shipPartGraphic.alpha = 0.5;
self.shipPartGraphic.tint = 0xff4444;
// Only animate if shipPartGraphic exists
if (self.shipPartGraphic) {
tween(self.shipPartGraphic, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 1
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (self.shipPartGraphic) {
var finalTint = keepColorless ? 0x666666 : 0xffffff; // Keep colorless or make it white for color
tween(self.shipPartGraphic, {
scaleX: 1,
scaleY: 1,
tint: finalTint
}, {
duration: 400,
easing: tween.easeInOut
});
}
}
});
}
}
};
self.makePartColorful = function () {
if (self.shipPartGraphic) {
// Remove the current blown part and replace with colorful version
var currentRotation = self.shipPartGraphic.rotation;
self.removeChild(self.shipPartGraphic);
var assetName = self.shipId + 'Part' + self.shipPartIndex + 'Blown';
self.shipPartGraphic = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Restore the rotation
self.shipPartGraphic.rotation = currentRotation;
// Make it colorful with a nice tween effect
self.shipPartGraphic.tint = 0xffffff; // Start white to show the asset's natural colors
tween(self.shipPartGraphic, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.shipPartGraphic, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
}
};
self.markMiss = function () {
if (!self.isHit) {
self.isHit = true;
self.marker = self.attachAsset('missMarker', {
anchorX: 0.5,
anchorY: 0.5
});
}
};
self.markSunk = function () {
if (self.marker) {
self.removeChild(self.marker);
}
// Now show the actual ship asset when fully sunk
if (!self.isPlayerGrid && self.hasShip) {
var assetName = self.shipId + 'Part' + self.shipPartIndex + 'Normal';
self.shipPartGraphic = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Apply rotation if ship is vertical (not horizontal)
// Find ship to determine orientation
for (var i = 0; i < aiShips.length; i++) {
if (aiShips[i].id === self.shipId) {
self.shipPartGraphic.rotation = aiShips[i].isHorizontal ? 0 : Math.PI / 2;
break;
}
}
}
// Then make the individual part colorful for visual effect
self.makePartColorful();
// Background explosion flash
var background = self.children[0]; // Get the water tile background
tween(background, {
tint: 0xff6600
}, {
duration: 200,
onFinish: function onFinish() {
tween(background, {
tint: 0x2c5aa0
}, {
duration: 400,
onFinish: function onFinish() {
tween(background, {
tint: 0xffffff
}, {
duration: 200
});
}
});
}
});
};
self.down = function (x, y, obj) {
if (gamePhase === 'placement') {
handleShipPlacement(self.gridX, self.gridY);
} else if (gamePhase === 'battle' && !self.isPlayerGrid && !self.isHit) {
handleAttack(self.gridX, self.gridY);
}
};
return self;
});
var RotateButton = Container.expand(function () {
var self = Container.call(this);
var buttonBg = self.attachAsset('rotateButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2('ROTATE', {
size: 24,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.down = function (x, y, obj) {
if (gamePhase === 'placement') {
selectedRotation = !selectedRotation;
var rotationText = selectedRotation ? 'Horizontal' : 'Vertical';
rotateText.setText('Current: ' + rotationText + ' (Tap to change)');
// Visual feedback
tween(buttonBg, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
onFinish: function onFinish() {
tween(buttonBg, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
}
};
return self;
});
var Ship = Container.expand(function (id, size, name) {
var self = Container.call(this);
self.id = id;
self.size = size;
self.name = name;
self.positions = [];
self.hits = 0;
self.isHorizontal = true;
self.isPlaced = false;
self.isSunk = false;
self.getPositions = function () {
return self.positions;
};
self.hit = function () {
self.hits++;
if (self.hits >= self.size) {
self.isSunk = true;
return true;
}
return false;
};
self.placeAt = function (startX, startY, horizontal) {
self.positions = [];
self.isHorizontal = horizontal;
self.isPlaced = true;
for (var i = 0; i < self.size; i++) {
if (horizontal) {
self.positions.push({
x: startX + i,
y: startY
});
} else {
self.positions.push({
x: startX,
y: startY + i
});
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x001122
});
/****
* Game Code
****/
// Destroyer parts (2 parts)
// Cruiser parts (3 parts)
// Battleship parts (4 parts)
// Carrier parts (5 parts)
// Destroyer (2 parts)
// Cruiser (3 parts)
// Battleship (4 parts)
// Carrier (5 parts)
var GRID_SIZE = 10;
var TILE_SIZE = 90;
var GRID_SPACING = 120;
var gamePhase = 'placement'; // 'placement', 'battle', 'gameOver'
var currentPlayer = 'player'; // 'player', 'ai'
var playerGrid = [];
var aiGrid = [];
var playerShips = [];
var aiShips = [];
var currentShipIndex = 0;
var selectedRotation = true; // true = horizontal, false = vertical
// Ship definitions
var shipDefinitions = [{
id: 'destroyer',
size: 2,
name: 'Destroyer'
}, {
id: 'destroyer',
size: 2,
name: 'Destroyer'
}, {
id: 'destroyer',
size: 2,
name: 'Destroyer'
}, {
id: 'cruiser',
size: 3,
name: 'Cruiser'
}, {
id: 'cruiser',
size: 3,
name: 'Cruiser'
}, {
id: 'battleship',
size: 4,
name: 'Battleship'
}, {
id: 'carrier',
size: 5,
name: 'Carrier'
}];
// UI Elements
var phaseText = new Text2('Drag ships to place them', {
size: 60,
fill: 0xFFFFFF
});
phaseText.anchor.set(0.5, 0);
LK.gui.top.addChild(phaseText);
var instructionText = new Text2('Drag and drop ships from preview area', {
size: 40,
fill: 0xCCCCCC
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 80;
LK.gui.top.addChild(instructionText);
var rotateText = new Text2('Tap ship to rotate before dragging', {
size: 30,
fill: 0xFFFF00
});
rotateText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(rotateText);
// Preview area for ships
var previewArea = [];
var draggedShip = null;
var dragOffset = {
x: 0,
y: 0
};
var previewShips = [];
// Create preview ships
function createPreviewShips() {
var previewStartX = 100;
var previewStartY = 400;
var yOffset = 0;
for (var i = 0; i < shipDefinitions.length; i++) {
var def = shipDefinitions[i];
var previewShip = new Container();
previewShip.shipIndex = i;
previewShip.isHorizontal = true;
previewShip.x = previewStartX;
previewShip.y = previewStartY + yOffset;
previewShip.parts = [];
previewShip.placed = false;
previewShip.originalX = previewShip.x;
previewShip.originalY = previewShip.y;
// Create ship parts
for (var j = 0; j < def.size; j++) {
var partAsset = previewShip.attachAsset(def.id + 'Part' + j + 'Normal', {
anchorX: 0.5,
anchorY: 0.5
});
partAsset.x = j * 88;
partAsset.y = 0;
previewShip.parts.push(partAsset);
}
// Add tap handler for rotation
previewShip.down = function (x, y, obj) {
if (!this.placed) {
this.isHorizontal = !this.isHorizontal;
this.updateRotation();
}
};
// Add move handler for dragging
previewShip.move = function (x, y, obj) {
if (draggedShip === this) {
var globalPos = game.toLocal(obj.parent.toGlobal({
x: x,
y: y
}));
this.x = globalPos.x - dragOffset.x;
this.y = globalPos.y - dragOffset.y;
this.showPlacementPreview();
}
};
// Add up handler for placement
previewShip.up = function (x, y, obj) {
if (draggedShip === this) {
this.attemptPlacement();
draggedShip = null;
}
};
previewShip.updateRotation = function () {
for (var k = 0; k < this.parts.length; k++) {
if (this.isHorizontal) {
this.parts[k].x = k * 88;
this.parts[k].y = 0;
this.parts[k].rotation = 0;
} else {
this.parts[k].x = 0;
this.parts[k].y = k * 88;
this.parts[k].rotation = Math.PI / 2;
}
}
};
previewShip.showPlacementPreview = function () {
// Clear previous highlights
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
var tile = playerGrid[x][y];
if (tile.highlight) {
tile.removeChild(tile.highlight);
tile.highlight = null;
}
}
}
// Find grid position under ship
var gridStartX = 2048 / 4 - GRID_SIZE * TILE_SIZE / 2;
var gridStartY = 2732 / 2 - GRID_SIZE * TILE_SIZE / 2;
var gridX = Math.floor((this.x - gridStartX) / TILE_SIZE);
var gridY = Math.floor((this.y - gridStartY) / TILE_SIZE);
// Show placement preview
if (gridX >= 0 && gridY >= 0 && this.canPlaceAt(gridX, gridY)) {
for (var i = 0; i < shipDefinitions[this.shipIndex].size; i++) {
var checkX = this.isHorizontal ? gridX + i : gridX;
var checkY = this.isHorizontal ? gridY : gridY + i;
if (checkX < GRID_SIZE && checkY < GRID_SIZE) {
var tile = playerGrid[checkX][checkY];
tile.highlight = tile.attachAsset('placementHighlight', {
anchorX: 0.5,
anchorY: 0.5
});
tile.highlight.alpha = 0.5;
}
}
}
};
previewShip.canPlaceAt = function (gridX, gridY) {
var size = shipDefinitions[this.shipIndex].size;
return canPlaceShip(playerGrid, gridX, gridY, size, this.isHorizontal);
};
previewShip.attemptPlacement = function () {
var gridStartX = 2048 / 4 - GRID_SIZE * TILE_SIZE / 2;
var gridStartY = 2732 / 2 - GRID_SIZE * TILE_SIZE / 2;
var gridX = Math.floor((this.x - gridStartX) / TILE_SIZE);
var gridY = Math.floor((this.y - gridStartY) / TILE_SIZE);
// Clear highlights
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
var tile = playerGrid[x][y];
if (tile.highlight) {
tile.removeChild(tile.highlight);
tile.highlight = null;
}
}
}
if (gridX >= 0 && gridY >= 0 && this.canPlaceAt(gridX, gridY)) {
// Place ship
var ship = playerShips[this.shipIndex];
placeShip(playerGrid, ship, gridX, gridY, this.isHorizontal);
this.placed = true;
this.visible = false;
// Check if all ships are placed
var allPlaced = true;
for (var i = 0; i < previewShips.length; i++) {
if (!previewShips[i].placed) {
allPlaced = false;
break;
}
}
if (allPlaced) {
placeAIShips();
startBattlePhase();
}
} else {
// Return to original position
tween(this, {
x: this.originalX,
y: this.originalY
}, {
duration: 300,
easing: tween.easeOut
});
}
};
previewShips.push(previewShip);
game.addChild(previewShip);
yOffset += Math.max(100, def.size * 20 + 60);
}
}
// Create rotate button
var rotateButton = new RotateButton();
rotateButton.x = 2048 / 2; // Center horizontally
rotateButton.y = 280; // Position a little bit down from top center
rotateButton.scaleX = 2.0; // Make it bigger
rotateButton.scaleY = 2.0; // Make it bigger
game.addChild(rotateButton);
// Initialize grids
function initializeGrids() {
var playerGridStartX = 2048 / 4 - GRID_SIZE * TILE_SIZE / 2;
var aiGridStartX = 3 * 2048 / 4 - GRID_SIZE * TILE_SIZE / 2;
var gridStartY = 2732 / 2 - GRID_SIZE * TILE_SIZE / 2;
// Create player grid
for (var x = 0; x < GRID_SIZE; x++) {
playerGrid[x] = [];
for (var y = 0; y < GRID_SIZE; y++) {
var tile = new GridTile(x, y, true);
tile.x = playerGridStartX + x * TILE_SIZE;
tile.y = gridStartY + y * TILE_SIZE;
playerGrid[x][y] = tile;
game.addChild(tile);
}
}
// Create AI grid
for (var x = 0; x < GRID_SIZE; x++) {
aiGrid[x] = [];
for (var y = 0; y < GRID_SIZE; y++) {
var tile = new GridTile(x, y, false);
tile.x = aiGridStartX + x * TILE_SIZE;
tile.y = gridStartY + y * TILE_SIZE;
aiGrid[x][y] = tile;
game.addChild(tile);
}
}
}
// Create ships
function createShips() {
for (var i = 0; i < shipDefinitions.length; i++) {
var def = shipDefinitions[i];
var ship = new Ship(def.id, def.size, def.name);
playerShips.push(ship);
var aiShip = new Ship(def.id, def.size, def.name);
aiShips.push(aiShip);
}
}
function canPlaceShip(grid, x, y, size, horizontal) {
for (var i = 0; i < size; i++) {
var checkX = horizontal ? x + i : x;
var checkY = horizontal ? y : y + i;
if (checkX >= GRID_SIZE || checkY >= GRID_SIZE) {
return false;
}
if (grid[checkX][checkY].hasShip) {
return false;
}
}
return true;
}
function placeShip(grid, ship, x, y, horizontal) {
ship.placeAt(x, y, horizontal);
var positions = ship.getPositions();
for (var i = 0; i < positions.length; i++) {
var pos = positions[i];
grid[pos.x][pos.y].setShip(ship.id, i, horizontal);
}
}
function handleShipPlacement(x, y) {
// Check if we're clicking on an already placed ship to move it
var clickedTile = playerGrid[x][y];
if (clickedTile.hasShip) {
// Find which ship this tile belongs to
var shipToMove = null;
var shipIndex = -1;
for (var i = 0; i < playerShips.length; i++) {
if (playerShips[i].isPlaced) {
var positions = playerShips[i].getPositions();
for (var j = 0; j < positions.length; j++) {
if (positions[j].x === x && positions[j].y === y) {
shipToMove = playerShips[i];
shipIndex = i;
break;
}
}
if (shipToMove) break;
}
}
if (shipToMove) {
// Remove ship from grid
var positions = shipToMove.getPositions();
for (var k = 0; k < positions.length; k++) {
var pos = positions[k];
var tile = playerGrid[pos.x][pos.y];
tile.hasShip = false;
tile.shipId = null;
tile.shipPartIndex = null;
if (tile.shipPartGraphic) {
tile.removeChild(tile.shipPartGraphic);
tile.shipPartGraphic = null;
}
}
// Reset ship state
shipToMove.isPlaced = false;
shipToMove.positions = [];
// Show preview ship again
var previewShip = previewShips[shipIndex];
previewShip.placed = false;
previewShip.visible = true;
previewShip.x = previewShip.originalX;
previewShip.y = previewShip.originalY;
return;
}
}
}
function placeAIShips() {
for (var i = 0; i < aiShips.length; i++) {
var ship = aiShips[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(aiGrid, x, y, ship.size, horizontal)) {
placeShip(aiGrid, ship, x, y, horizontal);
placed = true;
}
attempts++;
}
}
}
function startBattlePhase() {
gamePhase = 'battle';
phaseText.setText('Battle Phase');
instructionText.setText('Attack enemy grid!');
rotateText.setText('');
}
function handleAttack(x, y) {
if (gamePhase !== 'battle' || currentPlayer !== 'player') return;
var tile = aiGrid[x][y];
var isHit = tile.hasShip;
tile.markHit();
if (isHit) {
LK.getSound('hit').play();
// Check if ship is sunk
var hitShip = null;
for (var i = 0; i < aiShips.length; i++) {
var ship = aiShips[i];
var positions = ship.getPositions();
for (var j = 0; j < positions.length; j++) {
if (positions[j].x === x && positions[j].y === y) {
hitShip = ship;
break;
}
}
if (hitShip) break;
}
// Individual part blow up is now handled in markHit method
if (hitShip && hitShip.hit()) {
LK.getSound('sink').play();
// Mark all ship positions as sunk
var positions = hitShip.getPositions();
for (var k = 0; k < positions.length; k++) {
var pos = positions[k];
aiGrid[pos.x][pos.y].markSunk();
}
if (checkVictory(aiShips)) {
gamePhase = 'gameOver';
phaseText.setText('You Win!');
instructionText.setText('All enemy ships destroyed!');
LK.showYouWin();
return;
}
}
// Player hit - give another chance
instructionText.setText('Hit! Attack again!');
} else {
tile.markMiss();
LK.getSound('miss').play();
// Player missed - switch to AI turn
currentPlayer = 'ai';
instructionText.setText('AI is attacking...');
LK.setTimeout(function () {
aiAttack();
}, 1000);
}
}
function aiAttack() {
var validTargets = [];
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
if (!playerGrid[x][y].isHit) {
validTargets.push({
x: x,
y: y
});
}
}
}
if (validTargets.length === 0) return;
var target = validTargets[Math.floor(Math.random() * validTargets.length)];
var tile = playerGrid[target.x][target.y];
var isHit = tile.hasShip;
tile.markHit();
if (isHit) {
LK.getSound('hit').play();
// Check if ship is sunk
var hitShip = null;
for (var i = 0; i < playerShips.length; i++) {
var ship = playerShips[i];
var positions = ship.getPositions();
for (var j = 0; j < positions.length; j++) {
if (positions[j].x === target.x && positions[j].y === target.y) {
hitShip = ship;
break;
}
}
if (hitShip) break;
}
// Individual part blow up is now handled in markHit method
if (hitShip && hitShip.hit()) {
LK.getSound('sink').play();
// Mark all ship positions as sunk
var positions = hitShip.getPositions();
for (var k = 0; k < positions.length; k++) {
var pos = positions[k];
playerGrid[pos.x][pos.y].markSunk();
}
if (checkVictory(playerShips)) {
gamePhase = 'gameOver';
phaseText.setText('You Lose!');
instructionText.setText('All your ships destroyed!');
LK.showGameOver();
return;
}
}
// AI hit - continue AI turn
instructionText.setText('AI hit! AI attacking again...');
LK.setTimeout(function () {
aiAttack();
}, 1000);
} else {
tile.markMiss();
LK.getSound('miss').play();
// AI missed - switch to player turn
currentPlayer = 'player';
instructionText.setText('Your turn - Attack enemy grid!');
}
}
function checkVictory(ships) {
for (var i = 0; i < ships.length; i++) {
if (!ships[i].isSunk) {
return false;
}
}
return true;
}
// Add global move handler for ship dragging
game.move = function (x, y, obj) {
// Handle dragging preview ships
for (var i = 0; i < previewShips.length; i++) {
var ship = previewShips[i];
if (ship.move) {
ship.move(x, y, obj);
}
}
};
// Add global down handler for starting drag
game.down = function (x, y, obj) {
// Check if we're starting to drag a preview ship
var globalPos = game.toLocal(obj.parent.toGlobal({
x: x,
y: y
}));
for (var i = 0; i < previewShips.length; i++) {
var ship = previewShips[i];
if (!ship.placed && ship.getBounds().contains(globalPos.x, globalPos.y)) {
draggedShip = ship;
dragOffset.x = globalPos.x - ship.x;
dragOffset.y = globalPos.y - ship.y;
break;
}
}
};
// Initialize game
initializeGrids();
createShips();
createPreviewShips();
// Update initial instruction
instructionText.setText('Drag and drop ships from preview area');
rotateText.setText('Tap ship to rotate before dragging'); ===================================================================
--- original.js
+++ change.js
@@ -375,27 +375,185 @@
size: 5,
name: 'Carrier'
}];
// UI Elements
-var phaseText = new Text2('Place your ships', {
+var phaseText = new Text2('Drag ships to place them', {
size: 60,
fill: 0xFFFFFF
});
phaseText.anchor.set(0.5, 0);
LK.gui.top.addChild(phaseText);
-var instructionText = new Text2('Tap to place Destroyer (2)', {
+var instructionText = new Text2('Drag and drop ships from preview area', {
size: 40,
fill: 0xCCCCCC
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 80;
LK.gui.top.addChild(instructionText);
-var rotateText = new Text2('Tap anywhere to rotate', {
+var rotateText = new Text2('Tap ship to rotate before dragging', {
size: 30,
fill: 0xFFFF00
});
rotateText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(rotateText);
+// Preview area for ships
+var previewArea = [];
+var draggedShip = null;
+var dragOffset = {
+ x: 0,
+ y: 0
+};
+var previewShips = [];
+// Create preview ships
+function createPreviewShips() {
+ var previewStartX = 100;
+ var previewStartY = 400;
+ var yOffset = 0;
+ for (var i = 0; i < shipDefinitions.length; i++) {
+ var def = shipDefinitions[i];
+ var previewShip = new Container();
+ previewShip.shipIndex = i;
+ previewShip.isHorizontal = true;
+ previewShip.x = previewStartX;
+ previewShip.y = previewStartY + yOffset;
+ previewShip.parts = [];
+ previewShip.placed = false;
+ previewShip.originalX = previewShip.x;
+ previewShip.originalY = previewShip.y;
+ // Create ship parts
+ for (var j = 0; j < def.size; j++) {
+ var partAsset = previewShip.attachAsset(def.id + 'Part' + j + 'Normal', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ partAsset.x = j * 88;
+ partAsset.y = 0;
+ previewShip.parts.push(partAsset);
+ }
+ // Add tap handler for rotation
+ previewShip.down = function (x, y, obj) {
+ if (!this.placed) {
+ this.isHorizontal = !this.isHorizontal;
+ this.updateRotation();
+ }
+ };
+ // Add move handler for dragging
+ previewShip.move = function (x, y, obj) {
+ if (draggedShip === this) {
+ var globalPos = game.toLocal(obj.parent.toGlobal({
+ x: x,
+ y: y
+ }));
+ this.x = globalPos.x - dragOffset.x;
+ this.y = globalPos.y - dragOffset.y;
+ this.showPlacementPreview();
+ }
+ };
+ // Add up handler for placement
+ previewShip.up = function (x, y, obj) {
+ if (draggedShip === this) {
+ this.attemptPlacement();
+ draggedShip = null;
+ }
+ };
+ previewShip.updateRotation = function () {
+ for (var k = 0; k < this.parts.length; k++) {
+ if (this.isHorizontal) {
+ this.parts[k].x = k * 88;
+ this.parts[k].y = 0;
+ this.parts[k].rotation = 0;
+ } else {
+ this.parts[k].x = 0;
+ this.parts[k].y = k * 88;
+ this.parts[k].rotation = Math.PI / 2;
+ }
+ }
+ };
+ previewShip.showPlacementPreview = function () {
+ // Clear previous highlights
+ for (var x = 0; x < GRID_SIZE; x++) {
+ for (var y = 0; y < GRID_SIZE; y++) {
+ var tile = playerGrid[x][y];
+ if (tile.highlight) {
+ tile.removeChild(tile.highlight);
+ tile.highlight = null;
+ }
+ }
+ }
+ // Find grid position under ship
+ var gridStartX = 2048 / 4 - GRID_SIZE * TILE_SIZE / 2;
+ var gridStartY = 2732 / 2 - GRID_SIZE * TILE_SIZE / 2;
+ var gridX = Math.floor((this.x - gridStartX) / TILE_SIZE);
+ var gridY = Math.floor((this.y - gridStartY) / TILE_SIZE);
+ // Show placement preview
+ if (gridX >= 0 && gridY >= 0 && this.canPlaceAt(gridX, gridY)) {
+ for (var i = 0; i < shipDefinitions[this.shipIndex].size; i++) {
+ var checkX = this.isHorizontal ? gridX + i : gridX;
+ var checkY = this.isHorizontal ? gridY : gridY + i;
+ if (checkX < GRID_SIZE && checkY < GRID_SIZE) {
+ var tile = playerGrid[checkX][checkY];
+ tile.highlight = tile.attachAsset('placementHighlight', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ tile.highlight.alpha = 0.5;
+ }
+ }
+ }
+ };
+ previewShip.canPlaceAt = function (gridX, gridY) {
+ var size = shipDefinitions[this.shipIndex].size;
+ return canPlaceShip(playerGrid, gridX, gridY, size, this.isHorizontal);
+ };
+ previewShip.attemptPlacement = function () {
+ var gridStartX = 2048 / 4 - GRID_SIZE * TILE_SIZE / 2;
+ var gridStartY = 2732 / 2 - GRID_SIZE * TILE_SIZE / 2;
+ var gridX = Math.floor((this.x - gridStartX) / TILE_SIZE);
+ var gridY = Math.floor((this.y - gridStartY) / TILE_SIZE);
+ // Clear highlights
+ for (var x = 0; x < GRID_SIZE; x++) {
+ for (var y = 0; y < GRID_SIZE; y++) {
+ var tile = playerGrid[x][y];
+ if (tile.highlight) {
+ tile.removeChild(tile.highlight);
+ tile.highlight = null;
+ }
+ }
+ }
+ if (gridX >= 0 && gridY >= 0 && this.canPlaceAt(gridX, gridY)) {
+ // Place ship
+ var ship = playerShips[this.shipIndex];
+ placeShip(playerGrid, ship, gridX, gridY, this.isHorizontal);
+ this.placed = true;
+ this.visible = false;
+ // Check if all ships are placed
+ var allPlaced = true;
+ for (var i = 0; i < previewShips.length; i++) {
+ if (!previewShips[i].placed) {
+ allPlaced = false;
+ break;
+ }
+ }
+ if (allPlaced) {
+ placeAIShips();
+ startBattlePhase();
+ }
+ } else {
+ // Return to original position
+ tween(this, {
+ x: this.originalX,
+ y: this.originalY
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ }
+ };
+ previewShips.push(previewShip);
+ game.addChild(previewShip);
+ yOffset += Math.max(100, def.size * 20 + 60);
+ }
+}
// Create rotate button
var rotateButton = new RotateButton();
rotateButton.x = 2048 / 2; // Center horizontally
rotateButton.y = 280; // Position a little bit down from top center
@@ -497,30 +655,17 @@
}
// Reset ship state
shipToMove.isPlaced = false;
shipToMove.positions = [];
- // Set current ship index to this ship for replacement
- currentShipIndex = shipIndex;
- var shipDef = shipDefinitions[shipIndex];
- instructionText.setText('Tap to place ' + shipDef.name + ' (' + shipDef.size + ')');
+ // Show preview ship again
+ var previewShip = previewShips[shipIndex];
+ previewShip.placed = false;
+ previewShip.visible = true;
+ previewShip.x = previewShip.originalX;
+ previewShip.y = previewShip.originalY;
return;
}
}
- // Normal placement logic
- if (currentShipIndex >= shipDefinitions.length) return;
- var currentShip = playerShips[currentShipIndex];
- if (canPlaceShip(playerGrid, x, y, currentShip.size, selectedRotation)) {
- placeShip(playerGrid, currentShip, x, y, selectedRotation);
- currentShipIndex++;
- if (currentShipIndex >= shipDefinitions.length) {
- // All ships placed, start AI placement
- placeAIShips();
- startBattlePhase();
- } else {
- var nextShip = shipDefinitions[currentShipIndex];
- instructionText.setText('Tap to place ' + nextShip.name + ' (' + nextShip.size + ')');
- }
- }
}
function placeAIShips() {
for (var i = 0; i < aiShips.length; i++) {
var ship = aiShips[i];
@@ -663,13 +808,38 @@
}
}
return true;
}
-// Handle rotation during placement is now handled by the rotate button
+// Add global move handler for ship dragging
+game.move = function (x, y, obj) {
+ // Handle dragging preview ships
+ for (var i = 0; i < previewShips.length; i++) {
+ var ship = previewShips[i];
+ if (ship.move) {
+ ship.move(x, y, obj);
+ }
+ }
+};
+// Add global down handler for starting drag
+game.down = function (x, y, obj) {
+ // Check if we're starting to drag a preview ship
+ var globalPos = game.toLocal(obj.parent.toGlobal({
+ x: x,
+ y: y
+ }));
+ for (var i = 0; i < previewShips.length; i++) {
+ var ship = previewShips[i];
+ if (!ship.placed && ship.getBounds().contains(globalPos.x, globalPos.y)) {
+ draggedShip = ship;
+ dragOffset.x = globalPos.x - ship.x;
+ dragOffset.y = globalPos.y - ship.y;
+ break;
+ }
+ }
+};
// Initialize game
initializeGrids();
createShips();
-// Set initial instruction
-if (shipDefinitions.length > 0) {
- instructionText.setText('Tap to place ' + shipDefinitions[0].name + ' (' + shipDefinitions[0].size + ')');
-}
-rotateText.setText('Current: Horizontal (Tap to change)');
\ No newline at end of file
+createPreviewShips();
+// Update initial instruction
+instructionText.setText('Drag and drop ships from preview area');
+rotateText.setText('Tap ship to rotate before dragging');
\ No newline at end of file