User prompt
You are doing a terrible job with getGridCoords. Please remove it. What you are going to do is checking the click / tap position on the screen. If it's bigger on x and you can move to the next adjacent cell on the right on x, you do. If it's smaller, then you move to the right on x. Same with y.
Code edit (3 edits merged)
Please save this source code
User prompt
The getGridCoords is still borked. I'm clicking on col1, row 4 and it's showing col1, row 5. No way it's detecting row 4. Why?
Code edit (1 edits merged)
Please save this source code
User prompt
GetGridCoords is still having a weird behaviour, sometimes it detects the correct cell, sometimes it detects the previous or next. What I suggest you is that you probably return a list of possible cells and then you detect if any of those is adjacent and if so, you move to the adjacent one (if many, the first one)
Code edit (1 edits merged)
Please save this source code
User prompt
Ok, I don't lke the bomb button you created. Remove it. Instead, to place a bomb, I want you to check if I am clicking on the same cell the player is. If so, it places a bomb.
Code edit (3 edits merged)
Please save this source code
User prompt
getGridCoords is not working at all. Please redo it with other logic. When I click on 1,1 it shows 2,2. When I click on 2,1 it shows 3,2. And the worst: when I click on 3,1 it shows 5,2 !!! It's skipping 4. Please redo completely the logic.
User prompt
getGridCoords is not working properly. When I click on col 3, row 1 it shows col 4 row 1. And many cells have issues.
Code edit (1 edits merged)
Please save this source code
User prompt
player.isMoving is not being set to false after the movement finishes ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (7 edits merged)
Please save this source code
User prompt
After I've moved my player, I can't move it anymore! Fix it!
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Something is not working with the movement. I click / tap on a cell and it's not walking to it. Please check and fix.
User prompt
Ok the movement seems borked. What I need you to do is, if I click / tap on a free cell adjacent cell, the player should move to it. Ignore the movement if it's not adjacent or not free (there is a wall, a brick or a bomb)
Code edit (1 edits merged)
Please save this source code
User prompt
Grid Blast Mania
Initial prompt
Bomberman, the retro arcarde
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Represents a placed bomb var Bomb = Container.expand(function (col, row) { var self = Container.call(this); var graphics = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5 }); self.col = col; self.row = row; self.x = getWorldCoords(col, row).x; self.y = getWorldCoords(col, row).y; self.isBomb = true; // Identifier // Start the explosion timer var explosionTimer = LK.setTimeout(function () { explodeBomb(self); }, BOMB_TIMER); // Public method to trigger explosion early (chain reaction) self.triggerExplosion = function () { LK.clearTimeout(explosionTimer); explodeBomb(self); }; // Override destroy to clear the timer var baseDestroy = self.destroy; self.destroy = function () { LK.clearTimeout(explosionTimer); // Make sure the grid cell is marked empty when bomb is destroyed (e.g., by explosion) if (grid[self.col] && grid[self.col][self.row] === CELL_TYPE.BOMB) { setCell(self.col, self.row, CELL_TYPE.EMPTY); } // Remove from active bombs list in game scope var index = activeBombs.indexOf(self); if (index !== -1) { activeBombs.splice(index, 1); } if (baseDestroy) { baseDestroy.call(self); } // Call original destroy if exists }; return self; }); // Represents a single explosion particle/cell var Explosion = Container.expand(function (col, row) { var self = Container.call(this); var graphics = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5 }); self.col = col; self.row = row; self.x = getWorldCoords(col, row).x; self.y = getWorldCoords(col, row).y; self.isExplosion = true; // Identifier for collision checks // Fade out and destroy after duration var timer = LK.setTimeout(function () { self.destroy(); // Destroy handled by Game update loop removal }, EXPLOSION_DURATION); // Override destroy to clear the timer var baseDestroy = self.destroy; self.destroy = function () { LK.clearTimeout(timer); if (baseDestroy) { baseDestroy.call(self); } // Call original destroy if exists }; return self; }); // Represents the player character var Player = Container.expand(function (startCol, startRow) { var self = Container.call(this); var graphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.col = startCol; self.row = startRow; self.isPlayer = true; // Identifier // Snap to initial grid position var initialPos = getWorldCoords(self.col, self.row); self.x = initialPos.x; self.y = initialPos.y; self.isMoving = false; // Flag to track movement animation state // Public method to move the player self.moveTo = function (newCol, newRow) { var playerInstance = self; // Store reference to the player instance // The walkability check is now done in game.down before calling moveTo playerInstance.isMoving = true; // Set flag: player is now moving playerInstance.col = newCol; playerInstance.row = newRow; // Use tween for smooth movement var targetPos = getWorldCoords(newCol, newRow); tween(playerInstance, { // Use playerInstance as tween target x: targetPos.x, y: targetPos.y }, { duration: 100, // Keep the movement snappy easing: tween.linear, onFinish: function onFinish() { // Use onFinish as per tween plugin documentation // Use the stored playerInstance to ensure we reset the flag on the correct object playerInstance.isMoving = false; // Clear flag: movement animation finished } }); return true; // Move initiated successfully }; // Public method to place a bomb self.placeBomb = function () { if (activeBombs.length < MAX_BOMBS && getCellType(self.col, self.row) === CELL_TYPE.EMPTY) { LK.getSound('place_bomb').play(); var newBomb = new Bomb(self.col, self.row); game.addChild(newBomb); activeBombs.push(newBomb); setCell(self.col, self.row, CELL_TYPE.BOMB); // Mark cell as containing a bomb } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xaaaaaa // Light gray background }); /**** * Game Code ****/ // --- Constants --- // Engine will implicitly create assets based on usage below. // Let's define the shapes we'll use: var GRID_COLS = 15; // Ensure odd number for wall placement var GRID_ROWS = 21; // Ensure odd number for wall placement var CELL_SIZE = 128; var GRID_WIDTH = GRID_COLS * CELL_SIZE; var GRID_HEIGHT = GRID_ROWS * CELL_SIZE; var GRID_OFFSET_X = (2048 - GRID_WIDTH) / 2; var GRID_OFFSET_Y = (2732 - GRID_HEIGHT) / 2 + 50; // Adjust Y offset slightly down var CELL_TYPE = { EMPTY: 0, DESTRUCTIBLE: 1, INDESTRUCTIBLE: 2, BOMB: 3, // Cell temporarily occupied by a bomb EXPLOSION: 4 // Cell temporarily occupied by explosion }; var BOMB_TIMER = 2500; // Milliseconds before bomb explodes var EXPLOSION_DURATION = 400; // Milliseconds explosion visuals last var BOMB_RANGE = 2; // Number of cells explosion reaches in each direction var MAX_BOMBS = 1; // Max bombs player can have active at once var BRICK_DENSITY = 0.6; // Probability of a potential spot having a brick // --- Game State Variables --- var grid = []; // 2D array holding CELL_TYPE for each cell var gridSprites = []; // 2D array holding visual sprites for walls/bricks var player; var activeBombs = []; var activeExplosions = []; // Array to hold active Explosion objects var score = 0; var scoreTxt; var isGameOver = false; // --- Helper Functions --- // Convert grid cell indices to world coordinates (center of the cell) function getWorldCoords(col, row) { var x = GRID_OFFSET_X + col * CELL_SIZE + CELL_SIZE / 2; var y = GRID_OFFSET_Y + row * CELL_SIZE + CELL_SIZE / 2; return { x: x, y: y }; } // Get the type of a cell, handling out-of-bounds function getCellType(col, row) { if (col < 0 || col >= GRID_COLS || row < 0 || row >= GRID_ROWS) { return CELL_TYPE.INDESTRUCTIBLE; // Treat out of bounds as walls } return grid[col][row]; } // Set the type of a cell function setCell(col, row, type) { if (col >= 0 && col < GRID_COLS && row >= 0 && row < GRID_ROWS) { grid[col][row] = type; } } // Check if a cell is valid and empty for movement function isWalkable(col, row) { var cellType = getCellType(col, row); // A cell is walkable only if it's currently empty. Player cannot initiate move into other tiles. return cellType === CELL_TYPE.EMPTY; } // --- Grid Generation --- function generateGrid() { grid = []; gridSprites = []; // Clear previous sprites if any game.children.forEach(function (child) { if (child.isGridElement) { // Add a flag to identify grid sprites child.destroy(); } }); game.removeChildren(); // Clear all children before regenerating // Add floor tiles everywhere first for (var c = 0; c < GRID_COLS; c++) { for (var r = 0; r < GRID_ROWS; r++) { var floorTile = LK.getAsset('floor', { anchorX: 0.0, anchorY: 0.0 }); floorTile.x = GRID_OFFSET_X + c * CELL_SIZE; floorTile.y = GRID_OFFSET_Y + r * CELL_SIZE; floorTile.isGridElement = true; game.addChild(floorTile); } } for (var c = 0; c < GRID_COLS; c++) { grid[c] = []; gridSprites[c] = []; for (var r = 0; r < GRID_ROWS; r++) { var cellType; var sprite = null; // Place indestructible walls around border and in a checkerboard pattern inside if (c === 0 || c === GRID_COLS - 1 || r === 0 || r === GRID_ROWS - 1 || c % 2 === 0 && r % 2 === 0) { cellType = CELL_TYPE.INDESTRUCTIBLE; sprite = LK.getAsset('wall', { anchorX: 0.0, anchorY: 0.0 }); } else { // Place destructible bricks randomly, ensuring player start area is clear if (c <= 2 && r <= 2 || c >= GRID_COLS - 3 && r >= GRID_ROWS - 3) { // Clear corners for potential spawns cellType = CELL_TYPE.EMPTY; } else if (Math.random() < BRICK_DENSITY) { cellType = CELL_TYPE.DESTRUCTIBLE; sprite = LK.getAsset('brick', { anchorX: 0.0, anchorY: 0.0 }); } else { cellType = CELL_TYPE.EMPTY; } } grid[c][r] = cellType; if (sprite) { sprite.x = GRID_OFFSET_X + c * CELL_SIZE; sprite.y = GRID_OFFSET_Y + r * CELL_SIZE; sprite.isGridElement = true; // Mark as part of the grid visuals game.addChild(sprite); gridSprites[c][r] = sprite; } else { gridSprites[c][r] = null; } } } // Ensure player start is clear setCell(1, 1, CELL_TYPE.EMPTY); setCell(1, 2, CELL_TYPE.EMPTY); setCell(2, 1, CELL_TYPE.EMPTY); if (gridSprites[1] && gridSprites[1][1]) { var _gridSprites$1$; (_gridSprites$1$ = gridSprites[1][1]) === null || _gridSprites$1$ === void 0 || _gridSprites$1$.destroy(); gridSprites[1][1] = null; } if (gridSprites[1] && gridSprites[1][2]) { var _gridSprites$1$2; (_gridSprites$1$2 = gridSprites[1][2]) === null || _gridSprites$1$2 === void 0 || _gridSprites$1$2.destroy(); gridSprites[1][2] = null; } if (gridSprites[2] && gridSprites[2][1]) { var _gridSprites$2$; (_gridSprites$2$ = gridSprites[2][1]) === null || _gridSprites$2$ === void 0 || _gridSprites$2$.destroy(); gridSprites[2][1] = null; } } // --- Explosion Handling --- function createExplosion(col, row) { if (col < 0 || col >= GRID_COLS || row < 0 || row >= GRID_ROWS) { return false; } // Out of bounds var cellType = getCellType(col, row); if (cellType === CELL_TYPE.INDESTRUCTIBLE) { return false; // Explosion stops at indestructible walls } // Create visual explosion part var explosionPart = new Explosion(col, row); game.addChild(explosionPart); activeExplosions.push(explosionPart); setCell(col, row, CELL_TYPE.EXPLOSION); // Mark cell as exploding // Check for chain reactions or destroying bricks if (cellType === CELL_TYPE.DESTRUCTIBLE) { var brickSprite = gridSprites[col][row]; if (brickSprite) { brickSprite.destroy(); gridSprites[col][row] = null; } setCell(col, row, CELL_TYPE.EXPLOSION); // Becomes explosion temporarily LK.getSound('destroy_brick').play(); LK.setScore(LK.getScore() + 10); // Award score for destroying brick scoreTxt.setText(LK.getScore()); return false; // Explosion stops after destroying a brick } else if (cellType === CELL_TYPE.BOMB) { // Find the bomb object at this location and trigger it var bombToTrigger = null; for (var i = 0; i < activeBombs.length; i++) { if (activeBombs[i].col === col && activeBombs[i].row === row) { bombToTrigger = activeBombs[i]; break; } } if (bombToTrigger && !bombToTrigger.isExploding) { // Prevent infinite loops if already triggered bombToTrigger.isExploding = true; // Mark as exploding to avoid re-triggering bombToTrigger.triggerExplosion(); } return false; // Chain reaction handles further explosion; stop this particular ray } return true; // Explosion continues } function explodeBomb(bomb) { if (!bomb || bomb.destroyed) { return; } // Bomb might already be destroyed by chain reaction LK.getSound('explosion_sound').play(); var centerCol = bomb.col; var centerRow = bomb.row; // Remove bomb object itself first to prevent chain reaction with self bomb.destroy(); // This also removes from activeBombs and sets cell to EMPTY // Create explosion at the center createExplosion(centerCol, centerRow); // Create explosions outwards in four directions var directions = [[0, 1], [0, -1], [1, 0], [-1, 0]]; // Down, Up, Right, Left for (var i = 0; i < directions.length; i++) { var dx = directions[i][0]; var dy = directions[i][1]; for (var r = 1; r <= BOMB_RANGE; r++) { var currentC = centerCol + dx * r; var currentR = centerRow + dy * r; if (!createExplosion(currentC, currentR)) { break; // Stop this direction if explosion is blocked } } } } // --- Game Initialization --- function initGame() { isGameOver = false; score = 0; LK.setScore(0); activeBombs = []; activeExplosions = []; generateGrid(); // Create Player player = new Player(1, 1); // Start at top-left clear area game.addChild(player); // Score Display scoreTxt = new Text2('0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Add score to top center UI } // --- Event Handlers --- // Handle player interaction: place bomb on current cell or move to adjacent walkable cell game.down = function (x, y, obj) { // Check if player exists, game isn't over, AND player is not already moving if (isGameOver || !player || player.isMoving) { return; // Ignore taps if game over, player doesn't exist, or player is currently moving } var gameCoords = game.toLocal({ x: x, y: y }); // Convert event coords to game coords // Check if the click is on the player's current cell to place a bomb // Convert player's world position to grid coordinates var playerWorldPos = getWorldCoords(player.col, player.row); var playerCellCenterX = playerWorldPos.x; var playerCellCenterY = playerWorldPos.y; // Calculate the boundaries of the player's cell in world coordinates var playerCellLeft = playerCellCenterX - CELL_SIZE / 2; var playerCellRight = playerCellCenterX + CELL_SIZE / 2; var playerCellTop = playerCellCenterY - CELL_SIZE / 2; var playerCellBottom = playerCellCenterY + CELL_SIZE / 2; // Check if the click coordinates are within the bounds of the player's cell if (gameCoords.x >= playerCellLeft && gameCoords.x < playerCellRight && gameCoords.y >= playerCellTop && gameCoords.y < playerCellBottom) { player.placeBomb(); return; // Action handled, exit the function } // If not placing a bomb, try to move the player var playerCol = player.col; var playerRow = player.row; var targetCol = playerCol; var targetRow = playerRow; // Determine intended direction based on click position relative to player's cell center if (gameCoords.x > playerCellCenterX) { targetCol = playerCol + 1; // Try to move right } else if (gameCoords.x < playerCellCenterX) { targetCol = playerCol - 1; // Try to move left } if (gameCoords.y > playerCellCenterY) { targetRow = playerRow + 1; // Try to move down } else if (gameCoords.y < playerCellCenterY) { targetRow = playerRow - 1; // Try to move up } // If the click is exactly on the center of the player cell in one dimension, the target might be the same as the player. // We only want to initiate a move if the target is different from the current cell. if (targetCol !== playerCol || targetRow !== playerRow) { // Prioritize horizontal movement if horizontal displacement is greater, otherwise vertical var deltaX = Math.abs(gameCoords.x - playerCellCenterX); var deltaY = Math.abs(gameCoords.y - playerCellCenterY); var finalTargetCol = playerCol; var finalTargetRow = playerRow; if (deltaX > deltaY) { // Prioritize horizontal move finalTargetCol = gameCoords.x > playerCellCenterX ? playerCol + 1 : playerCol - 1; finalTargetRow = playerRow; // Keep row same // Check if the prioritized horizontal move is walkable. if (isWalkable(finalTargetCol, finalTargetRow)) { player.moveTo(finalTargetCol, finalTargetRow); return; // Move handled, exit } // If horizontal move isn't walkable, try the vertical move finalTargetCol = playerCol; // Reset col finalTargetRow = gameCoords.y > playerCellCenterY ? playerRow + 1 : playerRow - 1; if (isWalkable(finalTargetCol, finalTargetRow)) { player.moveTo(finalTargetCol, finalTargetRow); return; // Move handled, exit } // If neither horizontal nor vertical prioritized moves were walkable, do nothing. } else { // Prioritize vertical move (or if deltaX === deltaY) finalTargetCol = playerCol; // Keep col same finalTargetRow = gameCoords.y > playerCellCenterY ? playerRow + 1 : playerRow - 1; // Check if the prioritized vertical move is walkable. if (isWalkable(finalTargetCol, finalTargetRow)) { player.moveTo(finalTargetCol, finalTargetRow); return; // Move handled, exit } // If vertical move isn't walkable, try the horizontal move finalTargetCol = gameCoords.x > playerCellCenterX ? playerCol + 1 : playerCol - 1; finalTargetRow = playerRow; // Reset row if (isWalkable(finalTargetCol, finalTargetRow)) { player.moveTo(finalTargetCol, finalTargetRow); return; // Move handled, exit } // If neither vertical nor horizontal prioritized moves were walkable, do nothing. } } // If the click was not on the player's cell and did not result in a walkable adjacent cell target, do nothing. }; // --- Game Update Loop --- game.update = function () { if (isGameOver) { return; } // Check for player collision with explosions var playerCol = player.col; var playerRow = player.row; if (getCellType(playerCol, playerRow) === CELL_TYPE.EXPLOSION) { LK.getSound('player_die').play(); LK.effects.flashObject(player, 0xff0000, 300); // Flash player red isGameOver = true; LK.setTimeout(function () { LK.showGameOver(); // Show game over screen after a short delay }, 500); return; // Stop further updates after game over } // Clean up finished explosions and reset cell types for (var i = activeExplosions.length - 1; i >= 0; i--) { var explosion = activeExplosions[i]; // Check if the explosion sprite itself has been destroyed (by its internal timer) // Accessing internal properties like `_destroyed` is generally discouraged, // but necessary if the destroy mechanism is purely timer-based without explicit flags. // A better approach would be for Explosion class to set a 'finished' flag. // Let's assume Explosion.destroy correctly removes it from the stage. // We need a reliable way to know when to remove from activeExplosions and reset the grid cell. // We'll check if it's still parented to the game stage as a proxy. if (!explosion.parent) { // If it's been removed from the stage // Reset the grid cell only if it's still marked as EXPLOSION if (getCellType(explosion.col, explosion.row) === CELL_TYPE.EXPLOSION) { setCell(explosion.col, explosion.row, CELL_TYPE.EMPTY); } activeExplosions.splice(i, 1); // Remove from active list } } // Optional: Add win condition check (e.g., all bricks destroyed) // let bricksRemaining = false; // for (var c = 0; c < GRID_COLS; c++) { // for (var r = 0; r < GRID_ROWS; r++) { // if (getCellType(c, r) === CELL_TYPE.DESTRUCTIBLE) { // bricksRemaining = true; // break; // } // } // if (bricksRemaining) break; // } // if (!bricksRemaining) { // LK.showYouWin(); // } }; // --- Start the Game --- initGame();
===================================================================
--- original.js
+++ change.js
@@ -167,79 +167,8 @@
var score = 0;
var scoreTxt;
var isGameOver = false;
// --- Helper Functions ---
-// Convert world coordinates (relative to game stage 0,0) to grid cell indices.
-// Returns an array of candidate {col, row} objects, prioritizing the main cell
-// and including neighbors if the click is near a border.
-function getGridCoords(worldX, worldY) {
- var candidates = [];
- var uniqueCandidatesMap = {}; // Use object keys to track uniqueness
- // Calculate coordinates relative to the grid's top-left corner
- var relativeX = worldX - GRID_OFFSET_X;
- var relativeY = worldY - GRID_OFFSET_Y;
- // Check if click is outside the grid area based on relative coordinates
- if (relativeX < 0 || relativeX >= GRID_WIDTH || relativeY < 0 || relativeY >= GRID_HEIGHT) {
- return []; // Click is outside the grid, return empty array
- }
- // Calculate the main column and row index using Math.floor
- var mainCol = Math.floor(relativeX / CELL_SIZE);
- var mainRow = Math.floor(relativeY / CELL_SIZE);
- // Calculate position within the main cell (0 to CELL_SIZE)
- var xInCell = relativeX % CELL_SIZE;
- var yInCell = relativeY % CELL_SIZE;
- // Define a margin (e.g., 25% of cell size) to detect clicks near borders
- var margin = CELL_SIZE * 0.25;
- // Function to add a candidate if it's unique and within grid bounds
- function addCandidate(c, r) {
- if (c >= 0 && c < GRID_COLS && r >= 0 && r < GRID_ROWS) {
- var key = c + "," + r;
- if (!uniqueCandidatesMap[key]) {
- // DON'T CHANGE THIS, THIS IS RIGHT!
- candidates.push({
- col: c - 1,
- row: r - 1
- });
- uniqueCandidatesMap[key] = true;
- }
- }
- }
- // 1. Add the main cell first (highest priority)
- addCandidate(mainCol, mainRow);
- // 2. Add adjacent cells if click is near the border
- if (xInCell < margin) {
- // Near left edge
- addCandidate(mainCol - 1, mainRow);
- }
- if (xInCell > CELL_SIZE - margin) {
- // Near right edge
- addCandidate(mainCol + 1, mainRow);
- }
- if (yInCell < margin) {
- // Near top edge
- addCandidate(mainCol, mainRow - 1);
- }
- if (yInCell > CELL_SIZE - margin) {
- // Near bottom edge
- addCandidate(mainCol, mainRow + 1);
- }
- // Optional: Add diagonal candidates if near corners (uncomment if needed)
- /*
- if (xInCell < margin && yInCell < margin) { // Near top-left corner
- addCandidate(mainCol - 1, mainRow - 1);
- }
- if (xInCell > CELL_SIZE - margin && yInCell < margin) { // Near top-right corner
- addCandidate(mainCol + 1, mainRow - 1);
- }
- if (xInCell < margin && yInCell > CELL_SIZE - margin) { // Near bottom-left corner
- addCandidate(mainCol - 1, mainRow + 1);
- }
- if (xInCell > CELL_SIZE - margin && yInCell > CELL_SIZE - margin) { // Near bottom-right corner
- addCandidate(mainCol + 1, mainRow + 1);
- }
- */
- return candidates;
-}
// Convert grid cell indices to world coordinates (center of the cell)
function getWorldCoords(col, row) {
var x = GRID_OFFSET_X + col * CELL_SIZE + CELL_SIZE / 2;
var y = GRID_OFFSET_Y + row * CELL_SIZE + CELL_SIZE / 2;
@@ -449,52 +378,79 @@
}
var gameCoords = game.toLocal({
x: x,
y: y
- }); // Convert event coords to game coords//{24}
- var candidates = getGridCoords(gameCoords.x, gameCoords.y); // Get potential target cells
- console.log(candidates);
- if (candidates.length === 0) {
- return; // Click was outside grid or generated no candidates
+ }); // Convert event coords to game coords
+ // Check if the click is on the player's current cell to place a bomb
+ // Convert player's world position to grid coordinates
+ var playerWorldPos = getWorldCoords(player.col, player.row);
+ var playerCellCenterX = playerWorldPos.x;
+ var playerCellCenterY = playerWorldPos.y;
+ // Calculate the boundaries of the player's cell in world coordinates
+ var playerCellLeft = playerCellCenterX - CELL_SIZE / 2;
+ var playerCellRight = playerCellCenterX + CELL_SIZE / 2;
+ var playerCellTop = playerCellCenterY - CELL_SIZE / 2;
+ var playerCellBottom = playerCellCenterY + CELL_SIZE / 2;
+ // Check if the click coordinates are within the bounds of the player's cell
+ if (gameCoords.x >= playerCellLeft && gameCoords.x < playerCellRight && gameCoords.y >= playerCellTop && gameCoords.y < playerCellBottom) {
+ player.placeBomb();
+ return; // Action handled, exit the function
+ } // If not placing a bomb, try to move the player
+ var playerCol = player.col;
+ var playerRow = player.row;
+ var targetCol = playerCol;
+ var targetRow = playerRow;
+ // Determine intended direction based on click position relative to player's cell center
+ if (gameCoords.x > playerCellCenterX) {
+ targetCol = playerCol + 1; // Try to move right
+ } else if (gameCoords.x < playerCellCenterX) {
+ targetCol = playerCol - 1; // Try to move left
}
- var playerCell = {
- col: player.col,
- row: player.row
- };
- console.log(playerCell);
- var tappedCurrentCell = false;
- var firstAdjacentWalkableTarget = null;
- // Iterate through candidate cells
- for (var i = 0; i < candidates.length; i++) {
- var candidate = candidates[i];
- // Check 1: Is this candidate the player's current cell?
- if (candidate.col === playerCell.col && candidate.row === playerCell.row) {
- tappedCurrentCell = true;
- break; // Bomb placement takes priority, stop checking candidates
+ if (gameCoords.y > playerCellCenterY) {
+ targetRow = playerRow + 1; // Try to move down
+ } else if (gameCoords.y < playerCellCenterY) {
+ targetRow = playerRow - 1; // Try to move up
+ } // If the click is exactly on the center of the player cell in one dimension, the target might be the same as the player.
+ // We only want to initiate a move if the target is different from the current cell.
+ if (targetCol !== playerCol || targetRow !== playerRow) {
+ // Prioritize horizontal movement if horizontal displacement is greater, otherwise vertical
+ var deltaX = Math.abs(gameCoords.x - playerCellCenterX);
+ var deltaY = Math.abs(gameCoords.y - playerCellCenterY);
+ var finalTargetCol = playerCol;
+ var finalTargetRow = playerRow;
+ if (deltaX > deltaY) {
+ // Prioritize horizontal move
+ finalTargetCol = gameCoords.x > playerCellCenterX ? playerCol + 1 : playerCol - 1;
+ finalTargetRow = playerRow; // Keep row same
+ // Check if the prioritized horizontal move is walkable.
+ if (isWalkable(finalTargetCol, finalTargetRow)) {
+ player.moveTo(finalTargetCol, finalTargetRow);
+ return; // Move handled, exit
+ } // If horizontal move isn't walkable, try the vertical move
+ finalTargetCol = playerCol; // Reset col
+ finalTargetRow = gameCoords.y > playerCellCenterY ? playerRow + 1 : playerRow - 1;
+ if (isWalkable(finalTargetCol, finalTargetRow)) {
+ player.moveTo(finalTargetCol, finalTargetRow);
+ return; // Move handled, exit
+ } // If neither horizontal nor vertical prioritized moves were walkable, do nothing.
+ } else {
+ // Prioritize vertical move (or if deltaX === deltaY)
+ finalTargetCol = playerCol; // Keep col same
+ finalTargetRow = gameCoords.y > playerCellCenterY ? playerRow + 1 : playerRow - 1;
+ // Check if the prioritized vertical move is walkable.
+ if (isWalkable(finalTargetCol, finalTargetRow)) {
+ player.moveTo(finalTargetCol, finalTargetRow);
+ return; // Move handled, exit
+ } // If vertical move isn't walkable, try the horizontal move
+ finalTargetCol = gameCoords.x > playerCellCenterX ? playerCol + 1 : playerCol - 1;
+ finalTargetRow = playerRow; // Reset row
+ if (isWalkable(finalTargetCol, finalTargetRow)) {
+ player.moveTo(finalTargetCol, finalTargetRow);
+ return; // Move handled, exit
+ } // If neither vertical nor horizontal prioritized moves were walkable, do nothing.
}
- // Check 2: If we haven't found a move target yet, is this candidate adjacent and walkable?
- if (firstAdjacentWalkableTarget === null) {
- var dx = candidate.col - playerCell.col;
- var dy = candidate.row - playerCell.row;
- // Check if it's exactly one step away (horizontally or vertically)
- if (Math.abs(dx) + Math.abs(dy) === 1) {
- // Check if the adjacent cell is walkable
- if (isWalkable(candidate.col, candidate.row)) {
- firstAdjacentWalkableTarget = candidate; // Found a potential move target
- // Don't break yet, continue checking other candidates in case one IS the current cell
- }
- }
- }
}
- // Perform action based on findings
- if (tappedCurrentCell) {
- // If any candidate matched the player's current cell, place bomb
- player.placeBomb();
- } else if (firstAdjacentWalkableTarget !== null) {
- // If no candidate matched the current cell, but we found an adjacent walkable one, move there
- player.moveTo(firstAdjacentWalkableTarget.col, firstAdjacentWalkableTarget.row);
- }
- // If neither condition is met (no current cell tap, no adjacent walkable found), do nothing.
+ // If the click was not on the player's cell and did not result in a walkable adjacent cell target, do nothing.
};
// --- Game Update Loop ---
game.update = function () {
if (isGameOver) {
concrete floor tile, retro, pixel style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
bomb, pixel style, retro. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a demonic strawberry, pixel style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a demonic cherry, pixel style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a demonic kiwi, pixel style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A human character, player from an arcade retro game, looking like in the 80s 90s, hair, male, looking right, pixel style. In-Game asset. 2d. High contrast. No shadows
fire texture pixel style retro square. In-Game asset. 2d. High contrast. No shadows
powerup icon for an additional charge of a bomb, retro arcade game. In-Game asset. 2d. High contrast. No shadows
powerup icon for an additional range of the bomb explosion you can throw, retro arcade game. In-Game asset. 2d. High contrast. No shadows