User prompt
Less bricks, more enemies
User prompt
I can't collect the powerups :'( they block my way / my movement! They should not be blocking, the other way around - I should be able to collect them by getting into the same cell as them. If so, apply the buff / powerup to the player
User prompt
Please fix then the issue and have a bigger spawn rate as well
User prompt
When destroying the bricks, you have a 10% of having a powerup. THere are two types of powerup: 1) if picked by the player, will allow you to place one more bomb. 2) if picked by the player, the radius of the explosion is +1
Code edit (1 edits merged)
Please save this source code
User prompt
Super cool. Now please add enemies on free cells which will move erratically to one adjacent cell at a time, a random cell that is free. To do that you may need to remove bricks as there are many!
User prompt
Do it! ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
yoyo:true does not exist on tween. Please emulate it using onFinish
User prompt
yoyo: true and repeat: Infinity don't exist on tween. You need to use onFinish callback. Please fix it. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Timeout.tick error: tween.killTweensOf is not a function' in or related to this line: 'tween.killTweensOf(self.scale); // Stop the pulsating tween targeting the scale object' Line Number: 61
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'quadratic')' in or related to this line: 'tween(self.scale, {' Line Number: 35 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please add a cool tween on the bomb when placed: as it explodes in some time, maybe an animation like growing and shrinking until it explodes.
User prompt
If the player goes to the left, mirror the graphic on the player. If to the right, don't mirror it.
Code edit (3 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: tween.to is not a function' in or related to this line: 'tween.to(player, {' Line Number: 424 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
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 increase the player col in one. If it's smaller, then you move to the left (decrease col in 1) x. Same with y and cols.
User prompt
Remove please all the movement and bomb placement logic.
User prompt
The movement: don't transform the click region on a target cell, I don't need that. 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 (1 edits merged)
Please save this source code
User prompt
Result: Clicked cell ... is returning row+1 and col+1. Probalby you are not counting from 1 but from 0!
User prompt
Placing a bomb is not working! Please fix! I think you are not doing well the detection of the cell I'm clicking. Detect the cell I'm clicking / tapping! Log it! And then place the bomb.
User prompt
Placing a bomb is not working. Please check if I'm clicking / tapping the screen on the cell the player is at. If so, don't move the player and place a bomb in that player cell.
User prompt
Detect if I'm clicking on the player. If so, place a bomb on that cell
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
/****
* 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
self.pulsatingTween = null; // Initialize tween variable
// Define the pulsation functions
function scaleDown() {
// Prevent tweening if the bomb is already destroyed
if (self.destroyed) {
return;
}
self.pulsatingTween = tween(self.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200,
ease: tween.easeInOut,
onFinish: scaleUp // When shrinking finishes, start growing
});
}
function scaleUp() {
// Prevent tweening if the bomb is already destroyed
if (self.destroyed) {
return;
}
self.pulsatingTween = tween(self.scale, {
x: 1.1,
y: 1.1
}, {
duration: 200,
ease: tween.easeInOut,
onFinish: scaleDown // When growing finishes, start shrinking
});
}
// Start the pulsation cycle
scaleUp();
// 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);
// Stop the specific pulsating tween instance
if (self.pulsatingTween) {
self.pulsatingTween.kill(); // Use the kill() method on the stored tween instance
self.pulsatingTween = null; // Clear the reference
}
// 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);
}
// Mark as destroyed so ongoing tween callbacks won't try to run
self.destroyed = true;
if (baseDestroy) {
baseDestroy.call(self);
} // Call original destroy if exists
};
return self;
});
// Represents an enemy that moves between grid cells
var Enemy = Container.expand(function (startCol, startRow) {
var self = Container.call(this);
var graphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
// Tint the enemy red to differentiate from player
graphics.tint = 0xff0000;
self.col = startCol;
self.row = startRow;
self.isEnemy = true; // Identifier
self.isMoving = false; // Flag to track movement animation state
self.moveDelay = 1000 + Math.random() * 1000; // Random delay between moves
self.lastMoveTime = Date.now(); // Track when last moved
// Snap to initial grid position
var initialPos = getWorldCoords(self.col, self.row);
self.x = initialPos.x;
self.y = initialPos.y;
// Try to move in a random direction
self.tryRandomMove = function () {
if (self.isMoving) {
return false;
}
// Get all possible directions: up, right, down, left
var directions = [{
dx: 0,
dy: -1
},
// up
{
dx: 1,
dy: 0
},
// right
{
dx: 0,
dy: 1
},
// down
{
dx: -1,
dy: 0
} // left
];
// Shuffle directions for randomness
for (var i = directions.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = directions[i];
directions[i] = directions[j];
directions[j] = temp;
}
// Try each direction until a valid move is found
for (var i = 0; i < directions.length; i++) {
var newCol = self.col + directions[i].dx;
var newRow = self.row + directions[i].dy;
if (isWalkable(newCol, newRow)) {
// Found valid move
self.moveTo(newCol, newRow, directions[i].dx);
return true;
}
}
return false; // No valid moves found
};
// Move to a new cell
self.moveTo = function (newCol, newRow, dx) {
self.isMoving = true;
self.col = newCol;
self.row = newRow;
var targetPos = getWorldCoords(newCol, newRow);
// Flip sprite based on movement direction
if (dx < 0) {
graphics.scale.x = -1;
} else if (dx > 0) {
graphics.scale.x = 1;
}
// Animate movement
tween(self, {
x: targetPos.x,
y: targetPos.y
}, {
duration: 200,
onFinish: function onFinish() {
self.isMoving = false;
self.lastMoveTime = Date.now();
}
});
return true;
};
return self;
});
// Spawn enemies at random empty cells
// 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
// Start scaled down for explosion effect
self.scale.set(0);
// Animate the explosion appearing
tween(self.scale, {
x: 1,
y: 1
}, {
duration: 150,
ease: tween.easeOutQuad
});
// 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
// Empty placeholder for movement - functionality removed
self.moveTo = function (newCol, newRow) {
// Movement functionality removed
return false; // Movement disabled
};
// Empty placeholder for bomb placement - functionality removed
self.placeBomb = function () {
// Bomb placement functionality removed
};
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.4; // Reduced probability of a potential spot having a brick to make room for enemies
// --- 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 enemies = []; // Array to hold all enemy instances
var score = 0;
var scoreTxt;
var isGameOver = false;
var ENEMY_COUNT = 3; // Number of enemies to spawn
// --- 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 = [];
enemies = [];
generateGrid();
// Create Player
player = new Player(1, 1); // Start at top-left clear area
game.addChild(player);
// Spawn enemies on empty cells
spawnEnemies();
// 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 movement and bomb placement based on click/tap position
game.down = function (x, y, obj) {
if (isGameOver || player.isMoving) {
return;
}
// Get click position relative to the game area
var clickGameX = x;
var clickGameY = y;
// Determine the target grid cell based on click position
var targetCol = Math.floor((clickGameX - GRID_OFFSET_X) / CELL_SIZE);
var targetRow = Math.floor((clickGameY - GRID_OFFSET_Y) / CELL_SIZE);
// Ensure target is within grid bounds
if (targetCol < 0 || targetCol >= GRID_COLS || targetRow < 0 || targetRow >= GRID_ROWS) {
return; // Click outside the grid
}
// Check if the clicked cell is the player's current cell
if (targetCol === player.col && targetRow === player.row) {
// Clicked on player's cell, place a bomb if possible
if (activeBombs.length < MAX_BOMBS && getCellType(player.col, player.row) !== CELL_TYPE.BOMB) {
var newBomb = new Bomb(player.col, player.row);
game.addChild(newBomb);
activeBombs.push(newBomb);
setCell(player.col, player.row, CELL_TYPE.BOMB);
}
} else {
// Clicked on a different cell, attempt to move
var dx = targetCol - player.col;
var dy = targetRow - player.row;
// Determine direction of movement based on the larger difference
if (Math.abs(dx) > Math.abs(dy)) {
// Horizontal movement
if (dx > 0) {
// Move Right
if (isWalkable(player.col + 1, player.row)) {
player.col++;
player.isMoving = true;
}
} else {
// Move Left
if (isWalkable(player.col - 1, player.row)) {
player.col--;
player.isMoving = true;
}
}
} else {
// Vertical movement
if (dy > 0) {
// Move Down
if (isWalkable(player.col, player.row + 1)) {
player.row++;
player.isMoving = true;
}
} else {
// Move Up
if (isWalkable(player.col, player.row - 1)) {
player.row--;
player.isMoving = true;
}
}
}
// If player is moving, tween the position
if (player.isMoving) {
var targetPos = getWorldCoords(player.col, player.row);
// Mirror the player graphic if moving left
if (dx < 0) {
player.children[0].scale.x = -1;
} else if (dx > 0) {
// Un-mirror if moving right
player.children[0].scale.x = 1;
}
tween(player, {
x: targetPos.x,
y: targetPos.y
}, {
duration: 150,
onFinish: function onFinish() {
player.isMoving = false;
}
});
}
}
};
// --- 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
}
// Check for player collision with enemies
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (enemy.col === playerCol && enemy.row === playerRow) {
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
}
// Check for enemy collision with explosions
if (getCellType(enemy.col, enemy.row) === CELL_TYPE.EXPLOSION) {
// Enemy hit by explosion
LK.effects.flashObject(enemy, 0xffff00, 200);
enemy.destroy();
enemies.splice(i, 1);
// Add score for killing enemy
LK.setScore(LK.getScore() + 50);
scoreTxt.setText(LK.getScore());
i--; // Adjust index after removing element
}
}
// Move enemies randomly with their individual timing
var now = Date.now();
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (!enemy.isMoving && now - enemy.lastMoveTime > enemy.moveDelay) {
enemy.tryRandomMove();
}
}
// 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
}
}
// Win condition: all enemies destroyed and no bricks remaining
if (enemies.length === 0) {
var 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();
// Spawn enemies at random empty cells
function spawnEnemies() {
// Clear any existing enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
enemies = [];
// Find all empty cells
var emptyCells = [];
for (var c = 0; c < GRID_COLS; c++) {
for (var r = 0; r < GRID_ROWS; r++) {
// Don't spawn near player start position
if (getCellType(c, r) === CELL_TYPE.EMPTY && !(c <= 3 && r <= 3)) {
// Avoid player's starting area
emptyCells.push({
col: c,
row: r
});
}
}
}
// Shuffle empty cells
for (var i = emptyCells.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = emptyCells[i];
emptyCells[i] = emptyCells[j];
emptyCells[j] = temp;
}
// Create enemies
var enemiesToSpawn = Math.min(ENEMY_COUNT, emptyCells.length);
for (var i = 0; i < enemiesToSpawn; i++) {
var enemyCell = emptyCells[i];
var enemy = new Enemy(enemyCell.col, enemyCell.row);
enemies.push(enemy);
game.addChild(enemy);
}
} ===================================================================
--- original.js
+++ change.js
@@ -87,9 +87,9 @@
});
// Represents an enemy that moves between grid cells
var Enemy = Container.expand(function (startCol, startRow) {
var self = Container.call(this);
- var graphics = self.attachAsset('player', {
+ var graphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
// Tint the enemy red to differentiate from player
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