AABB sprite-vs-sprite and tile-based wall collision in a walled arena. Move the white square with the D-pad. Overlapping a red enemy turns both green.
Build & Run
cd $OPENSNES_HOME
make -C examples/basics/collision_demo
Then open collision_demo.sfc in your emulator (Mesen2 recommended).
Controls
| Button | Action |
| D-Pad | Move player sprite (2 pixels/frame) |
What You'll Learn
- AABB collision via collideRect() with Rect struct pointers
- Tile-based wall collision via collideTile() with a collision map array
- Per-axis rejection for sliding along walls instead of stopping dead
- Direct oamMemory[] buffer writes (avoiding oamSet()'s 158-byte stack overhead)
- OAM high table management for X high bit and sprite size
- Palette bank swapping for visual collision feedback
SNES Concepts
AABB Collision with Rect Pointers
collideRect() takes two Rect* pointers and returns non-zero if the rectangles overlap. The Rect struct holds x, y, width, and height fields:
}
static u8 collision_flags
Bitmask tracking which enemies the player is currently overlapping.
Definition main.c:75
#define PLAYER_SIZE
Definition main.c:50
static Rect player_box
Player bounding box for AABB collision tests via collideRect().
Definition main.c:60
static Rect enemy_box[4]
Bounding boxes for each enemy, rebuilt every frame for collideRect().
Definition main.c:67
static s16 player_y
Player Y position in screen coordinates.
Definition main.c:58
static s16 player_x
Player X position in screen coordinates.
Definition main.c:56
u8 collideRect(Rect *a, Rect *b)
Check rectangle vs rectangle collision (AABB).
static u8 i
Definition main.c:156
The example checks the player against four static enemy sprites each frame, storing results in a bitmask (collision_flags). Bit N set means enemy N is overlapping.
Tile-Based Wall Collision
collideTile() takes four parameters: a pixel X coordinate, a pixel Y coordinate, a pointer to the collision map array, and the map width in tiles:
static const u8 collision_map[16 *14]
Tile-based collision map (16x14 = 224 bytes, 128x112 pixel area).
Definition main.c:96
#define MAP_WIDTH
Definition main.c:81
u8 collideTile(s16 px, s16 py, const u8 *tilemap, u16 mapWidth)
Check collision with tile at pixel coordinates.
It converts the pixel position to a tile index (dividing by 8) and returns the tile value – 1 for solid, 0 for passable. The example checks all four corners of the player's 8x8 bounding box to detect wall overlap.
Per-Axis Sliding
When a diagonal movement would collide, each axis is tested independently. If only the X component collides, the Y movement still applies (and vice versa). This lets the player slide along walls:
} else {
}
static u8 check_wall_collision(s16 new_x, s16 new_y)
Test whether a position would overlap a solid wall tile.
Definition main.c:373
Direct oamMemory[] Writes
Instead of calling oamSet() (which has a 158-byte stack frame per call), the example writes sprite data directly into the OAM buffer. Each sprite is 4 bytes: X low, Y, tile number, and attribute byte (priority + palette bank):
unsigned char u8
8-bit unsigned integer (0 to 255)
Definition types.h:47
u8 oamMemory[]
Hardware OAM buffer (544 bytes at $7E:0300).
volatile u8 oam_update_flag
OAM DMA trigger flag.
When a collision is active, the palette bank switches from 0 (normal colors: white player, red enemies) to 1 (green highlight for both), providing instant visual feedback.
Collision Map Layout
The arena is a 16x14 tile grid (128x112 pixels) centered on the 256x224 screen. Walls form the border with symmetric internal platforms:
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 (top wall)
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
...
1,0,0,1,1,0,0,0,0,0,0,1,1,0,0,1 (platforms)
...
1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1 (center platform)
...
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 (bottom wall)
The same data drives both the visual BG tilemap (drawn once at init) and the runtime collision checks (read every frame).
Files
| File | Purpose |
| main.c | Collision logic, sprite management, game loop |
| Makefile | Build config (LIB_MODULES := console input sprite dma collision background) |
What's Next?
Game: Breakout - Complete game with collision, sprites, and levels