Sprite Animation

Sprites can be animated using a series of pre-made images. For performance reasons they're usually packed into a rectangular texture, where each individual image located in its own cell of a grid. Such texture is called a sprite sheet, and it looks something like this:

sprite sheet example

As you can see, there are multiple frames for each animation (idle, run, sword swing, etc.) packed into a single image. To play an animation, all we need to do is to change frames with some desired frequency and... that's pretty much all. That's the simplest animation technique one could imagine.

Sprite sheets usually made by artists, not programmers, so just search online for some sprite sheet or order a new one from an artist. Programmer's art is pretty much always bad.

How to use

sprite animation editor

Fyrox offers a built-in sprite animation system which has its own editor. To be able to use sprite animation all you need to do is to add a SpriteSheetAnimation field (or a bunch of them) to your script and put the following code in its on_update:

#![allow(unused)]
fn main() {
#[derive(Default, Clone, Debug, Reflect, Visit, TypeUuidProvider, ComponentProvider)]
#[type_uuid(id = "aeebb95f-8e32-490e-971c-c22417bd19c5")]
#[visit(optional)]
struct Player {
    animation: SpriteSheetAnimation,
}

impl ScriptTrait for Player {
    fn on_update(&mut self, ctx: &mut ScriptContext) {
        // Update the animation first, it will switch current frame automatically if needed.
        self.animation.update(ctx.dt);

        if let Some(sprite) = ctx
            .scene
            .graph
            .try_get_mut(ctx.handle)
            .and_then(|n| n.cast_mut::<Rectangle>())
        {
            // Assign the texture from the animation to the sprite first.
            sprite
                .material()
                .data_ref()
                .set_texture(&"diffuseTexture".into(), self.animation.texture())
                .unwrap();

            // Set the current animation's UV rect to the sprite.
            sprite.set_uv_rect(self.animation.current_frame_uv_rect().unwrap_or_default());
        }
    }
}
}