feat: overhaul cursed apple sprite with custom tile data, vibrant palette, and dynamic pulsing glow

This commit is contained in:
phillip committed 2026-10-03 21:02:59 +02:00
1 parent 60bf111400
commit 08a4b41280
4 files changed
+44 -25

No files matched your search

+1 -1
View File
@@ -97,7 +97,7 @@ The game operates in one of two scenes ([`Scene`](include/game_state.h#L9-L12)):
- **Snake Body:** Represented as `std::deque<std::array<int, 3>>` where each entry is `{x, y, direction}`. Alternating segments use regular and small sprite tiles. Head and tail sprites flip dynamically according to direction.
- **Normal Apple (Red):** Spawns if count < 1. Awards +10 score, increases length by 1, plays pickup sound. Flashes/blinks every 4 ticks.
- **Rotten Apple (Brown/Green):** Spawns in Hard Mode (periodic chance up to 20 on screen). Decreases length by 1, plays explosion SFX. If length drops below 2, triggers Game Over.
- **Cursed Apple (Purple):** Spawns occasionally. Inverts player steering controls (Up ↔ Down, Left ↔ Right) for `CURSE_DURATION_TICKS` (40 ticks). The sprite is procedurally constructed at startup in [`main.cpp:91-112`](source/main.cpp#L91-L112) by copying the rotten apple tile pixels and mapping them to dedicated palette entries (`CURSE_PAL_SHADOW`, `CURSE_PAL_OUTLINE`, `CURSE_PAL_FILL`, `CURSE_PAL_GLOW`).
- **Cursed Apple (Electric Neon Purple & Radioactive Green):** Spawns occasionally. Inverts player steering controls (Up ↔ Down, Left ↔ Right) for `CURSE_DURATION_TICKS` (40 ticks). Rendered using a dedicated 8x8 sprite with a glowing core rune and toxic green horn, using high-contrast dedicated palette entries (`CURSE_PAL_OUTLINE`, `CURSE_PAL_FILL`, `CURSE_PAL_GLOW`, `CURSE_PAL_CORE`, `CURSE_PAL_LEAF`). Its palette dynamically breathes and pulses with radioactive energy every frame at 60 FPS in [`handle_vblank()`](source/main.cpp#L134-L153), and its sprite sways/twitches with mystical instability in [`draw_apples_cursed()`](source/game_render.cpp#L139-L151).
- **Reverse-Direction Denial:** Pressing the D-Pad in the exact opposite direction (i.e. into the snake's own neck) is silently denied instead of causing an immediate Game Over. The game computes the would-be next head position (including edge-wrapping) and compares it to the neck segment; if they match, the direction change is rejected and a subtle "denied" thud SFX plays.
### 3.4 Game Modes & Progressive Speed Mechanics