entities_and_hazards - jonathanperis/super-mango-editor GitHub Wiki
Entities & Hazards
Super Mango has six enemy types and seven hazard types. All are stored as fixed-size arrays inside GameState and managed via the standard init / update / render lifecycle. Positions are in logical pixels (400Γ300 space).
Enemies
Spider
File: src/entities/spider.c / spider.h
Sprite: assets/sprites/entities/spider.png β 192Γ48 px, 3 frames of 64Γ48 px
Behaviour: Horizontal ground patrol. Walks back and forth between patrol_x0 and patrol_x1. No gravity β stays on the ground floor. Reverses direction and flips sprite when it hits a patrol boundary.
| Constant | Value | Description |
|---|---|---|
MAX_SPIDERS |
16 | Slots in the GameState array |
SPIDER_FRAMES |
3 | Animation frames |
SPIDER_FRAME_W |
64 | Width of one frame slot in px |
SPIDER_ART_W |
25 | Width of visible art (cols 20β44) |
SPIDER_ART_H |
10 | Height of visible art (rows 22β31) |
SPIDER_SPEED |
50.0 | Walk speed in logical px/s |
SPIDER_FRAME_MS |
150 | ms per animation frame |
TOML placement:
[spiders](/jonathanperis/super-mango-editor/wiki/spiders)
x = 600.0
vx = 50.0 # positive = starts moving right
patrol_x0 = 592.0
patrol_x1 = 750.0
frame_index = 0 # starting animation frame (0β2)
Jumping Spider
File: src/entities/jumping_spider.c / jumping_spider.h
Sprite: assets/sprites/entities/jumping_spider.png
Behaviour: Like the spider but can leap across sea gaps. Detects approaching floor gaps and jumps before reaching them, allowing it to follow the player across openings where a normal spider would fall.
TOML placement:
[jumping_spiders](/jonathanperis/super-mango-editor/wiki/jumping_spiders)
x = 130.0
vx = 55.0
patrol_x0 = 46.0
patrol_x1 = 310.0
Bird
File: src/entities/bird.c / bird.h
Sprite: assets/sprites/entities/bird.png β 144Γ48 px, 3 frames of 48Γ48 px
Behaviour: Slow sine-wave sky patrol. Flies horizontally while oscillating vertically around base_y using a sine curve. The wing-flap sound effect plays once per animation cycle with distance-based volume.
| Constant | Value | Description |
|---|---|---|
MAX_BIRDS |
16 | Slots in GameState |
BIRD_FRAMES |
3 | Animation frames |
BIRD_FRAME_W |
48 | Frame slot width in px |
BIRD_ART_W |
15 | Visible art width (cols 17β31) |
BIRD_ART_H |
14 | Visible art height (rows 17β30) |
BIRD_SPEED |
45.0 | Horizontal speed in px/s |
BIRD_WAVE_AMP |
20.0 | Sine-wave vertical amplitude in px |
BIRD_WAVE_FREQ |
0.015 | Sine cycles per horizontal px of travel |
BIRD_FRAME_MS |
140 | ms per animation frame |
TOML placement:
[birds](/jonathanperis/super-mango-editor/wiki/birds)
x = 100.0
base_y = 60.0 # vertical centre of the sine wave
vx = 45.0
patrol_x0 = 0.0
patrol_x1 = 700.0
frame_index = 0
Faster Bird
File: src/entities/faster_bird.c / faster_bird.h
Sprite: assets/sprites/entities/faster_bird.png
Behaviour: Aggressive sky patrol with higher speed and a tighter wave. Same schema as Bird but uses [faster_birds](/jonathanperis/super-mango-editor/wiki/faster_birds) in TOML. Typical vx is 70β100 px/s vs. the bird's 45 px/s.
[faster_birds](/jonathanperis/super-mango-editor/wiki/faster_birds)
x = 600.0
base_y = 50.0
vx = -80.0
patrol_x0 = 300.0
patrol_x1 = 1100.0
frame_index = 0
Fish
File: src/entities/fish.c / fish.h
Sprite: assets/sprites/entities/fish.png β 96Γ48 px, 2 frames of 48Γ48 px
Behaviour: Patrols horizontally in the water lane at the bottom of the screen. Periodically performs a random upward jump (impulse β280 px/s) that can reach the player on the ground floor. Jump interval is randomised between 1.4 s and 3.0 s.
| Constant | Value | Description |
|---|---|---|
MAX_FISH |
16 | Slots in GameState |
FISH_FRAMES |
2 | Animation frames |
FISH_FRAME_W |
48 | Frame slot width in px |
FISH_SPEED |
70.0 | Horizontal patrol speed in px/s |
FISH_JUMP_VY |
β280.0 | Upward jump impulse in px/s |
FISH_JUMP_MIN |
1.4 | Minimum seconds between jumps |
FISH_JUMP_MAX |
3.0 | Maximum seconds between jumps |
FISH_HITBOX_PAD_X |
16 | Left/right inset for collision |
FISH_HITBOX_PAD_Y |
13 | Top inset for collision |
FISH_FRAME_MS |
120 | ms per animation frame |
[fish](/jonathanperis/super-mango-editor/wiki/fish)
x = 700.0
vx = 70.0
patrol_x0 = 500.0
patrol_x1 = 950.0
Faster Fish
File: src/entities/faster_fish.c / faster_fish.h
Behaviour: Same as fish but patrols at 120 px/s and jumps more frequently. Uses [faster_fish](/jonathanperis/super-mango-editor/wiki/faster_fish) in TOML.
[faster_fish](/jonathanperis/super-mango-editor/wiki/faster_fish)
x = 1100.0
vx = 120.0
patrol_x0 = 900.0
patrol_x1 = 1400.0
Hazards
All hazards deal 1 heart of damage on contact with knockback (same apply_damage path in player.c).
Spike Row
File: src/hazards/spike.c / spike.h
Sprite: assets/sprites/hazards/spike.png β 16Γ16 px per tile
Behaviour: Static horizontal strip of spike tiles sitting on the ground floor. No movement or animation. Damages the player on any overlap.
| Constant | Value | Description |
|---|---|---|
MAX_SPIKE_ROWS |
16 | Rows in GameState |
MAX_SPIKE_TILES |
16 | Max tiles per row |
SPIKE_TILE_W |
16 | Width of one spike tile in px |
SPIKE_TILE_H |
16 | Height of one spike tile in px |
[spike_rows](/jonathanperis/super-mango-editor/wiki/spike_rows)
x = 780.0 # left edge of the strip
count = 4 # number of tiles
Spike Block
File: src/hazards/spike_block.c / spike_block.h
Sprite: assets/sprites/hazards/spike_block.png
Behaviour: A rotating hazard that travels along a Rail path. References a rail by index and can be given an initial offset and speed. Visually rotates as it travels. The player is pushed on contact.
[spike_blocks](/jonathanperis/super-mango-editor/wiki/spike_blocks)
rail_index = 0 # 0-based index into the [rails](/jonathanperis/super-mango-editor/wiki/rails) list
t_offset = 0.0 # starting position on the rail (0.0 = first tile)
speed = 1.5 # traversal speed in tiles/s
Spike Platform
File: src/hazards/spike_platform.c / spike_platform.h
Sprite: assets/sprites/hazards/spike_platform.png
Behaviour: Elevated static surface tiled across tile_count units. The player is damaged when landing on the top surface or touching the sides.
[spike_platforms](/jonathanperis/super-mango-editor/wiki/spike_platforms)
x = 370.0
y = 200.0 # top edge in logical pixels
tile_count = 3
Circular Saw
File: src/hazards/circular_saw.c / circular_saw.h
Sprite: assets/sprites/hazards/circular_saw.png β 32Γ32 px
Behaviour: Spins continuously and patrols a horizontal line at ground level. Does not ride a rail β it bounces between patrol_x0 and patrol_x1. Faster than the player's walk speed. Pushes the player on contact.
| Constant | Value | Description |
|---|---|---|
SAW_FRAME_W/H |
32 | Sprite dimensions in px |
SAW_SPIN_DEG_PER_SEC |
720.0 | Rotation speed (2 full rotations/s) |
SAW_PATROL_SPEED |
180.0 | Horizontal patrol speed in px/s |
SAW_PUSH_SPEED |
220.0 | Push impulse magnitude on contact |
SAW_PUSH_VY |
β150.0 | Upward component of push |
[circular_saws](/jonathanperis/super-mango-editor/wiki/circular_saws)
x = 1350.0
y = 0.0 # engine snaps to floor level
patrol_x0 = 1350.0
patrol_x1 = 1446.0
direction = 1 # 1 = starts right, -1 = starts left
Axe Trap
File: src/hazards/axe_trap.c / axe_trap.h
Sprite: assets/sprites/hazards/axe_trap.png β 48Γ64 px
Behaviour: Swinging or spinning axe mounted at the top centre of a platform pillar. Two modes:
- PENDULUM β sinusoidal swing from β60Β° to +60Β° over a 2 s cycle. SFX plays at each extreme.
- SPIN β continuous 360Β° clockwise rotation at 180Β°/s. SFX plays each full rotation.
Collision uses the full rotated bounding box of the blade region.
| Constant | Value | Description |
|---|---|---|
AXE_FRAME_W/H |
48 / 64 | Sprite dimensions |
AXE_SWING_AMPLITUDE |
60.0Β° | Max angle from vertical |
AXE_SWING_PERIOD |
2.0 s | Full pendulum cycle duration |
AXE_SPIN_SPEED |
180.0Β°/s | Full-rotation variant speed |
[axe_traps](/jonathanperis/super-mango-editor/wiki/axe_traps)
pillar_x = 256.0 # centre x of the pillar column
y = 0.0 # pivot y (engine computes from pillar height)
mode = "PENDULUM" # or "SPIN"
Blue Flame
File: src/hazards/blue_flame.c / blue_flame.h
Sprite: assets/sprites/hazards/blue_flame.png β 96Γ48 px, 2 frames of 48Γ48 px
Behaviour: Erupts from a sea gap in four phases:
| Phase | Duration | Description |
|---|---|---|
WAITING |
1.5 s | Hidden below the floor, counting down |
RISING |
Until apex (y = 60) | Launches at β550 px/s, decelerates at 800 px/sΒ² |
FLIPPING |
0.12 s | Rotates 180Β° at the apex |
FALLING |
Until below floor | Descends upside-down, accelerating with gravity |
Blue flames are spawned automatically for each entry in floor_gaps. They can also be manually added via [blue_flames](/jonathanperis/super-mango-editor/wiki/blue_flames) to override position.
[blue_flames](/jonathanperis/super-mango-editor/wiki/blue_flames)
x = 192.0 # world-space x of the sea gap
| Constant | Value | Description |
|---|---|---|
BLUE_FLAME_LAUNCH_VY |
β550.0 | Initial upward impulse in px/s |
BLUE_FLAME_APEX_Y |
60.0 | Highest point in logical pixels |
BLUE_FLAME_FLIP_DURATION |
0.12 s | Time to rotate 180Β° at apex |
BLUE_FLAME_WAIT_DURATION |
1.5 s | Idle time between eruptions |
Fire Flame
File: src/hazards/fire_flame.c / fire_flame.h
Sprite: assets/sprites/hazards/fire_flame.png
Behaviour: Same eruption cycle as the blue flame but with a fire-colored sprite. Used in volcanic or lava-themed levels. Shares the same phase constants.
Collision Architecture
All entityβplayer collision uses AABB (axis-aligned bounding box) overlap tests. Entity hitboxes are inset from the sprite frame to match visible art bounds only β transparent padding is excluded.
/* Example: is the player overlapping a coin? */
static int aabb_overlap(float ax, float ay, int aw, int ah,
float bx, float by, int bw, int bh) {
return ax < bx + bw && ax + aw > bx &&
ay < by + bh && ay + ah > by;
}
For entities with non-rectangular visible art (birds, fish, spiders), get_hitbox() functions return a pre-computed inset SDL_Rect that matches the actual art bounds. See each entity's header for ART_X, ART_W, ART_Y, ART_H, and HITBOX_PAD_* constants.
Adding a New Enemy or Hazard
See the Developer Guide for the full entity template and step-by-step checklist.