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
****/
// Carrier (5 parts)
// Battleship (4 parts)
// Cruiser (3 parts)
// Destroyer (2 parts)
// Carrier parts (5 parts)
// Battleship parts (4 parts)
// Cruiser parts (3 parts)
// Destroyer parts (2 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('Place your ships', {
size: 60,
fill: 0xFFFFFF
});
phaseText.anchor.set(0.5, 0);
LK.gui.top.addChild(phaseText);
var instructionText = new Text2('Tap to place Destroyer (2)', {
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', {
size: 30,
fill: 0xFFFF00
});
rotateText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(rotateText);
// 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) {
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];
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;
}
// Handle rotation during placement is now handled by the rotate button
// 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)'); ===================================================================
--- original.js
+++ change.js
@@ -362,8 +362,12 @@
id: 'cruiser',
size: 3,
name: 'Cruiser'
}, {
+ id: 'cruiser',
+ size: 3,
+ name: 'Cruiser'
+}, {
id: 'battleship',
size: 4,
name: 'Battleship'
}, {