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.