Collision on a Tilemap
In a tile-based game, collision detection isn’t just about object-to-object overlap; it’s about checking if a moving sprite is trying to occupy a tile marked as solid (e.g., a wall, water, or rock).
The Core Logic: Before updating a sprite’s position, check the Tile ID at the new (target) location.
Step 1: Converting Sprite Position to Tile Index
The first challenge is converting the sprite’s precise pixel coordinates (X, Y) into the coarse array index needed to read the tilemap.
The Calculation: Since a tile is typically $8\times 8$ pixels, you perform integer division (fast right shift) on the sprite’s coordinates.
SPRITE_X_COORD EQU 00H ; 16-bit address of X-coordinate
GET_TILE_INDEX:
LD HL, SPRITE_X_COORD ; HL ← X-coordinate
; Perform division by 8 (3 fast right shifts)
SRL H ; Shift high byte
RR L ; Rotate low byte through the carry
SRL H ; Shift high byte again
RR L ; Rotate low byte again
SRL H ; Shift high byte (Final shift)
RR L ; Rotate low byte (Final shift)
; HL now holds the (X, Y) tile coordinates in the low 8 bits of H and L.
; This tile index is used for the map lookup.
RET
Step 2: Reading the Tile ID and Checking Solidity
Once you have the tile index, you calculate the address in the MAP_DATA
block, read the byte, and compare it against your list of solid tile IDs.
The Solidity Check:
SOLID_TILE_ID EQU 0FFH ; Example ID for a wall tile
VOID_TILE_ID EQU 00H ; Example ID for a hole/void
CHECK_SOLIDITY:
CALL GET_TILE_INDEX ; HL now holds the map coordinates
CALL CALCULATE_MAP_ADDR ; Converts HL coordinates to MAP_DATA address
LD A, (HL) ; A ← Tile ID at the target location
CP SOLID_TILE_ID ; Compare with wall ID
JP Z, COLLISION_WALL ; Found a solid wall
CP VOID_TILE_ID ; Compare with void/hole ID
JP Z, COLLISION_VOID ; Found a hole (player falls)
RET ; Tile is safe/walkable
Map Boundary Checks
Before performing any calculation, the sprite’s X and Y coordinates must be checked against the hard limits of the map array (e.g., $X_{max}$ and $Y_{max}$). If the target coordinate is outside the map’s bounds, it’s an illegal move, and the velocity must be stopped immediately.
Logic: Use the CP
(Compare) and `JP C′ (Jump if Carry/Below) instructions to check if the sprite’s position is below zero or above the maximum map dimension.