Workshop › Wolfenstein-style 3D Maze › Step 1 of 18
Walk through a 3D maze drawn from a flat map, the way the first 3D shooters did it. Angles with sin and cos, sliding along walls, casting rays through a grid (DDA), perspective, the fish-eye fix and shading.
We are building a 3D maze like the first 3D shooters (Wolfenstein 3D): you walk inside it and see walls in perspective. The trick: the world is really a flat grid. First we write that grid as a list of strings and draw it small in the corner, as a minimap.
```js
const canvas = document.getElementById('game')
const ctx = canvas.getContext('2d')
// # stone wall, 2 brick wall, E the exit (a wall you walk into), . floor.
const MAP = [
'############',
'#....#.....#',
'#.##.#.###.#',
'#.#..#...#.#',
'#.#.###2#..#',
'#.#.....#.##',
'#.#22#.##..#',
'#..........#',
'###.##.#.#.#',
'#...#..#.#.#',
'#.#...##.#E#',
'############',
]
const MINI = 8 // minimap pixels per tile
function draw() {
// The minimap, seen from above.
MAP.forEach((line, row) => {
;[...line].forEach((ch, col) => {
ctx.fillStyle = ch === '.' ? 'rgba(15, 23, 42, 0.6)' : ch === 'E' ? '#22c55e' : 'rgba(226, 232, 240, 0.8)'
ctx.fillRect(col * MINI, row * MINI, MINI, MINI)
})
})
}
draw()
```# and 2 are walls, E the exit, . floor.MAP.forEach((line, row) => ...) visits each row with its number; [...line] splits a row into characters.; in front of [...line] keeps JavaScript from gluing that line to the one before.Write the lines under the comments, then press Run.
Skills: Drawing on a canvas, Arrays and objects