Game Dev 101
Progress
0/22

Lesson 12 of 22, in world 4: Visuals & Worlds

Tilemaps

Time
About 20 min
Builds on
Collision DetectionGravity, Jumping & Collision ResponseHandling Input

Drawing every wall of a level as a separate rectangle would be painful. Most 2D games — Zelda, Mario, Stardew Valley, Celeste — build their worlds from a tilemap: a grid of small square images called tiles, stored as a 2D array of numbers.

A level is just an array

JavaScript
const TILE = 32
const map = [
  [1, 1, 1, 1, 1, 1],
  [1, 0, 0, 4, 0, 1],   // 0 = floor, 1 = wall, 4 = coin
  [1, 0, 1, 1, 0, 1],
  [1, 1, 1, 1, 1, 1],
]
// Draw: loop over rows and columns
for (let row = 0; row < map.length; row++)
  for (let col = 0; col < map[row].length; col++)
    drawTile(map[row][col], col * TILE, row * TILE)
LivePaint a level, then walk in it
Brush

Click or drag on the map to paint tiles. Walk with the arrow keys / WASD. Walls and water are solid; coins are collected. Toggle "Show the data" to see that the whole level is just a 2D array of numbers.

World ↔ tile coordinates

The single most important tilemap formula converts a pixel position to a grid cell, and back:

JavaScript
const col = Math.floor(worldX / TILE)   // which column is this pixel in?
const row = Math.floor(worldY / TILE)
const worldX = col * TILE               // top-left pixel of a cell

Cheap collisions with tiles

Here’s the big win: you don’t need to test against every wall. To check whether the player hits a wall, convert the corners of its hitbox to tile coordinates and look those cells up in the array — an O(1) lookup, no matter how big the level is. The demo moves one axis at a time (lesson 10) and simply refuses steps that would land in a solid tile.

Tilesets and autotiling

The images for each tile id live in a tileset — a sprite sheet of tiles (lesson 11). Autotiling automatically picks the right edge/corner tile by looking at each cell’s neighbours, so painting a blob of “grass” gives you nice borders without placing each piece by hand.

Key takeaways

  • A tilemap is a 2D array of tile ids, drawn as a grid of tile images.
  • col = floor(x / TILE), row = floor(y / TILE).
  • Tile collisions are cheap: look up the cells under the hitbox corners.
  • Levels as data are easy to edit, store and generate.

Check yourself

Q1. With 32 px tiles, which column is the pixel x = 100 in?

Q2. Why are tile collisions cheap?

Q3. map[2][5] refers to…

Exercises

  1. Paint a small maze and collect all coins. Then wall yourself in completely.
  2. Make water "slow" instead of solid: what would you change in the movement code?
  3. Write the level above as a list of strings ("1111", "1041", …) and a parser — that is how the demo stores it.