The Tilemap Concept
A tilemap is a technique that breaks a large game world (the map) into small, reusable graphic squares (tiles), typically $8\times 8$ or $16\times 16$ pixels.
Why Tilemaps are Essential:
- Memory Saving: Instead of storing the pixel data for the entire map, you only store the data for a small set of unique tiles (the tileset) and then store the map itself as a small array of tile IDs (indices).
- Fast Rendering: The CPU can draw the screen by reading the tile ID from the map and using that ID as an index to quickly look up and draw the corresponding tile graphic.
The Map Data Structure
The map data is a simple, linear array stored in memory.
Memory Location | Value | Meaning |
---|---|---|
MAP_DATA + 0 |
05H | Tile at (0, 0) is Tile ID #5 (a ‘grass’ tile) |
MAP_DATA + 1 |
1AH | Tile at (1, 0) is Tile ID #26 (a ‘water’ tile) |
Rendering the Screen with a Tilemap
To draw one screen full of tiles, the Z80 must loop through every visible screen position, perform a calculation to find the correct tile ID, and then copy the graphic data.
The Rendering Loop (Simplified):
LD BC, 0 ; B = Y-coordinate (Row), C = X-coordinate (Column)
RENDER_LOOP:
; 1. Calculate the map index: (Y × MapWidth) + X
CALL CALCULATE_MAP_INDEX
; 2. Read the Tile ID from the map data
LD A, (HL) ; Assume HL points to the map index (A ← Tile ID)
; 3. Calculate the address of the actual graphic data
; (Tile ID × TileSize) + TILESET_BASE
CALL LOOKUP_TILE_ADDRESS ; HL ← Address of the graphic data
; 4. Calculate the screen destination address (Part 23)
CALL CALCULATE_SCREEN_ADDR ; DE ← Address on screen
; 5. Draw the tile (copy 8x8 block)
CALL LDIR_TILE_BLOCK
; 6. Increment X (C) and Y (B) and loop BC times
; ...
RET
Tile-Based Collision
Collision checks become extremely simple with tilemaps. Instead of checking complex bounding boxes, you check the Tile ID at the sprite’s location.
Example: Checking for a Wall
- Calculate the map index corresponding to the sprite’s new position.
- Read the Tile ID at that index into A.
- Compare A with the ID reserved for walls (
WALL_ID EQU 0FFH
).
CALL CALCULATE_MAP_INDEX
LD A, (HL)
CP WALL_ID
JP Z, COLLISION_DETECTED