Sprite animations can be defined using asset files (probably in RON format).
The Animation Asset Format
Settings
There is a settings header, which specifies general parameters for "simple animations": start frame, end frame, ticks per frame (playback speed). An "absolute tick mode" is also supported, for animations that should be timed from when the player entered a level/room, rather than when the animation entity was spawned.
Such a simple animation will just play from the start frame to the end frame, at the given rate, and stop. For more complex behaviors (such as looping), use "scripts".
Scripts
The animation file can also contain optional scripts, which are actions to perform at given times (on a given tick, on a given frame index, etc.). This allows complex behaviors to be attached to the animation.
In this PR, we only support some simple script actions:
jump to a given frame index (to support skips and looping in animations).
stop/pause/unpause
changing the playback speed
changing the sprite color
In the future, we can add more complex actions for advanced workflows:
Spawning a bevy scene (to create entities in the world)
Adding/removing components from the animation entity (via reflection)
Sending Bevy events (via reflection)
Running custom bevy systems (or iyes_cli commands)
Game-specific things, such as dealing damage
By the end of this all, we should have something that roughly feels like working in a dynamically scriptable game engine, driven by animations and powered by Bevy and Rust. ;)
The Animation Player Implementation
Entities that play sprite animations should have a SpriteAnimationPlayer component, which holds the internal data for animation playback. Animations can be started by calling the .play(...) method. This is similar to Bevy's (general) animations API.
Every Bevy update (not fixed update), the update system runs and will do what it has to do to "catch up" to the current tick: run scripts for any ticks that have elapsed, advance frames, run scripts for animation frames, ...
Playback can be paused. There are two "pause modes":
NoScripts is a full pause mode: nothing happens, other than checking the optional auto-resume value (to allow animations to unpause themselves after an interval, given that they can't run scripts in this mode)
Frozen is a semi-paused mode: the sprite does not update, but scripts still run
Sprite animations can be defined using asset files (probably in RON format).
The Animation Asset Format
Settings
There is a
settings
header, which specifies general parameters for "simple animations": start frame, end frame, ticks per frame (playback speed). An "absolute tick mode" is also supported, for animations that should be timed from when the player entered a level/room, rather than when the animation entity was spawned.Such a simple animation will just play from the start frame to the end frame, at the given rate, and stop. For more complex behaviors (such as looping), use "scripts".
Scripts
The animation file can also contain optional
script
s, which are actions to perform at given times (on a given tick, on a given frame index, etc.). This allows complex behaviors to be attached to the animation.In this PR, we only support some simple script actions:
In the future, we can add more complex actions for advanced workflows:
iyes_cli
commands)By the end of this all, we should have something that roughly feels like working in a dynamically scriptable game engine, driven by animations and powered by Bevy and Rust. ;)
The Animation Player Implementation
Entities that play sprite animations should have a
SpriteAnimationPlayer
component, which holds the internal data for animation playback. Animations can be started by calling the.play(...)
method. This is similar to Bevy's (general) animations API.Every Bevy update (not fixed update), the update system runs and will do what it has to do to "catch up" to the current tick: run scripts for any ticks that have elapsed, advance frames, run scripts for animation frames, ...
Playback can be paused. There are two "pause modes":
NoScripts
is a full pause mode: nothing happens, other than checking the optional auto-resume value (to allow animations to unpause themselves after an interval, given that they can't run scripts in this mode)Frozen
is a semi-paused mode: the sprite does not update, but scripts still runPlease give feedback! 😊