Bomberman looks like it needs sprites, a physics engine, and enemy scripting. It doesn't. The entire game is a 2D array of integers plus three ideas: a countdown, a raycast, and a breadth-first search. Here's how each piece works, in about 250 lines of vanilla JavaScript on one canvas.
The arena is just numbers
The whole board is grid[row][col] holding one of three values: 0 floor, 1 unbreakable stone, 2 a destructible crate. The classic layout isn't random — the outer ring is stone, and there's a pillar on every cell whose row and column are both even. That checkerboard is why the board can never seal shut: the odd-numbered lanes are always open.
const COLS = 15, ROWS = 13; // odd sizes give the pillar grid
const EMPTY = 0, HARD = 1, SOFT = 2;
for (let r = 0; r < ROWS; r++)
for (let c = 0; c < COLS; c++){
const border = r===0 || c===0 || r===ROWS-1 || c===COLS-1;
const pillar = r % 2 === 0 && c % 2 === 0; // even row AND even col
grid[r][c] = (border || pillar) ? HARD : EMPTY;
}
A bomb is a cell plus a countdown
Dropping a bomb pushes one small object: its cell, a two-second fuse, and your blast range. Every frame each fuse loses the elapsed time; when it hits zero, it explodes.
const FUSE = 2.0;
function dropBomb(){
const cell = occupantCell(player);
if (bombs.length >= maxBombs || bombAt(cell.c, cell.r)) return;
bombs.push({ col: cell.c, row: cell.r, timer: FUSE, range: bombRange });
}
function tickBombs(dt){
for (const b of bombs) b.timer -= dt;
for (const b of bombs) if (b.timer <= 0) explode(b);
}
The explosion: a raycast in four directions
This is the heart of the game. Light the bomb's own cell, then shoot a ray down each of the four directions, one tile at a time, up to the blast range. Each step asks the tile ahead one question. Stone or off the board? Stop. A crate? Break it into floor, light that one tile, and stop — each arm destroys exactly one crate. Otherwise it's floor: light it and keep going. And if a lit tile holds another bomb, detonate it too — that single recursive line is the whole chain reaction.
function explode(b){
if (b.exploded) return;
b.exploded = true;
addFire(b.col, b.row); // the bomb's own cell
for (const [dc, dr] of [[1,0],[-1,0],[0,1],[0,-1]]){
for (let i = 1; i <= b.range; i++){
const c = b.col + dc*i, r = b.row + dr*i;
if (!inBounds(c, r) || grid[r][c] === HARD) break; // stone blocks it
if (grid[r][c] === SOFT){ grid[r][c] = EMPTY; addFire(c, r); break; }
addFire(c, r); // floor: burn + continue
const chained = bombAt(c, r);
if (chained && !chained.exploded) explode(chained); // chain reaction
}
}
}
Hunters that actually pathfind
The enemies aren't scripted with "if player is left, go left." Each one runs a breadth-first search from its own cell across the floor, recording who first reached each cell, until the wave touches your tile. Then it walks that parent chain back to find the first step of the shortest path and takes only that step. BFS on a 15x13 grid is instant, and because it re-plans every step, the hunter follows you around corners.
function bfsStep(sc, sr, tc, tr){
const q = [[sc, sr]], prev = {}, seen = new Set([sc + "," + sr]);
while (q.length){
const [c, r] = q.shift();
if (c === tc && r === tr) break; // reached the player
for (const [dc, dr] of [[1,0],[-1,0],[0,1],[0,-1]]){
const nc = c+dc, nr = r+dr, k = nc + "," + nr;
if (seen.has(k) || grid[nr][nc] !== EMPTY || bombAt(nc, nr)) continue;
seen.add(k); prev[k] = [c, r]; q.push([nc, nr]); // remember who found it
}
}
// walk prev[] back from (tc,tr) to (sc,sr) -> return the first step
}
Win, lose, one loop
After everyone moves each frame: filter out any hunter standing on fire, lose if the player is on fire or shares a cell with a hunter, win if the hunter array is empty. Three checks against the fire set — no state machine required.
The neat trick tying it together is canEnter: a cell is enterable if it's floor and has no bomb on it. You're never entering the cell you already stand on, so you can walk off your own fresh bomb but never back onto one.
Play it, drag the difficulty knobs, and step through the annotated build here: https://dev48v.infy.uk/game/day53-bomberman.html
Top comments (0)