Animate entities from the sheet's states

Idle frames tick on a global clock offset by entity id, walk frames run
on a per-entity clock while the position lerp is in flight, and the sim's
Attacked/Died events drive the attacker's action, the victim's flinch and
a corpse that shows the dead frames for a few seconds. All render-side;
the sim is untouched. The snapshot test can dump a strip of frames.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-20 20:50:55 +02:00
co-authored by Claude Opus 5
parent 4aa99815d7
commit dd0526f5e9
2 changed files with 123 additions and 18 deletions
+9 -3
View File
@@ -55,9 +55,15 @@ crate's `tick`/`set_action` interface is the seam a server could be wrapped arou
See `notes/07-map-loader.md`
- [x] Tile rendering: chunk-based world rendering straight from `World` (`render_viewport`)
- [x] Sprite-based entity rendering: entity `type_id` → sprite row in `entities.png`
(via the `entities.toml` manifest, see Assets above), idle frame blitted with
transparency. Animation (walk while the lerp runs, hit/dead from events) is the
next step — the sheet layout and loader already carry the frames.
(via the `entities.toml` manifest, see Assets above), blitted with transparency.
- [x] Sprite animation, purely render-side (`Game::entity_frame`): idle on a global
clock offset by entity id (so a flock doesn't blink in unison), walk while the
position lerp runs (a per-entity walk clock accumulates across steps so the cycle
stays continuous), action 1 on the attacker and hit on the victim for 250 ms from
the `Attacked` event, and `Died` leaves a `Corpse` showing the dead frames for a
few seconds. Priority: hit > action > walk > idle; missing states fall back to
idle. `FRAMES=6 SNAPSHOT=… cargo test -p game dump_frame -- --ignored` dumps a
strip of consecutive frames.
- [x] Hybrid tick loop: 24 Hz base tick, movement in `entity_tick` every 4th tick (6 Hz);
the game loop drives the sim with a fixed-timestep accumulator. See `notes/06-hybrid-tick-loop.md`
- [x] Intent model: one scheduled action per entity per movement window (`Sim::set_action`),