Workshop › Zelda-style Dungeon › Step 1 of 22
Explore four rooms, fight with a sword, find the key, open the door and escape. Rooms written as text, walking and sliding along walls, moving between rooms, a sword hitbox, enemies that wander and chase, hearts, keys and a world that remembers what you took.
We are building a Zelda-style dungeon: walk through four rooms, fight with a sword, find the key, open the door and escape down the stairs. First the world: four rooms written as text, 15 tiles wide and 11 high, arranged 2 by 2. We load the first room and draw it tile by tile, below a strip at the top kept free for hearts and keys.
```js
const canvas = document.getElementById('game')
const ctx = canvas.getContext('2d')
const T = 32 // one tile
const TOP = 48 // room for hearts, keys and the timer
// Four rooms, in a 2 by 2 grid. # wall, D locked door, k key, h heart, e enemy, E the stairs out, P the start.
// A gap in the wall at the edge of a room leads to the room next to it.
const ROOMS = [
[
[
'###############',
'#.............#',
'#..P..........#',
'#....###......#',
'#....#.....e..#',
'#....#.........',
'#.............#',
'#..........h..#',
'#.............#',
'#.............#',
'#######.#######',
],
[
'###############',
'#.............#',
'#..e......e...#',
'#....#####....#',
'#.............#',
'..............#',
'#.............#',
'#...##...##...#',
'#.......e.....#',
'#.............#',
'#######D#######',
],
],
[
[
'#######.#######',
'#.............#',
'#..e..........#',
'#...#######...#',
'#.............#',
'#.....k.......#',
'#.............#',
'#...#######...#',
'#..........e..#',
'#.............#',
'###############',
],
[
'#######.#######',
'#.............#',
'#.e.........e.#',
'#.............#',
'#....#####....#',
'#....#.E.#....#',
'#....#...#....#',
'#.............#',
'#......e......#',
'#.............#',
'###############',
],
],
]
const COLS = 15
const ROWS = 11
let tiles // the current room, as arrays of characters we can change (doors open, keys are picked up)
let room // { rx, ry }: which room we are in
function enter(rx, ry) {
room = { rx, ry }
tiles = ROOMS[ry][rx].map((line) => [...line].map((ch) => (ch === 'P' || ch === 'e' ? '.' : ch)))
}
function draw() {
ctx.fillStyle = '#0c0a09'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.save()
ctx.translate(0, TOP)
tiles.forEach((line, row) => {
line.forEach((ch, col) => {
const x = col * T
const y = row * T
ctx.fillStyle = ch === '#' ? '#57534e' : '#d6c7a1'
ctx.fillRect(x, y, T, T)
})
})
ctx.restore()
}
enter(0, 0)
draw()
```ROOMS[ry][rx] is the room in row ry, column rx of the 2×2 grid; each room is a list of strings.enter copies the room into tiles as arrays of characters, so single tiles can change later. The start P and
the enemies e become floor: they are not tiles.ctx.translate(0, TOP) moves everything down 48 pixels until ctx.restore(); save remembers how it was.Write the lines under the comments (the map carefully), then press Run.
Skills: Drawing on a canvas, Arrays and objects