nightshade 0.13.2

A cross-platform data-oriented game engine.
Documentation
use crate::tui::ecs::world::*;

pub fn animation_system(world: &mut World) {
    let delta = world.resources.timing.delta_seconds;

    let updates: Vec<(freecs::Entity, char, f64, usize, bool)> = world
        .query_entities(SPRITE | SPRITE_ANIMATION)
        .filter_map(|entity| {
            let animation = world.get_sprite_animation(entity)?;
            if animation.finished || animation.frames.is_empty() {
                return None;
            }

            let mut elapsed = animation.elapsed + delta;
            let mut current_frame = animation.current_frame;
            let mut finished = animation.finished;
            let frame_duration = animation.frame_duration;
            let looping = animation.looping;
            let frames = &animation.frames;

            while elapsed >= frame_duration {
                elapsed -= frame_duration;
                current_frame += 1;
                if current_frame >= frames.len() {
                    if looping {
                        current_frame = 0;
                    } else {
                        current_frame = frames.len() - 1;
                        finished = true;
                        break;
                    }
                }
            }

            let character = frames[current_frame];
            Some((entity, character, elapsed, current_frame, finished))
        })
        .collect();

    for (entity, character, elapsed, current_frame, finished) in updates {
        if let Some(sprite) = world.get_sprite_mut(entity) {
            sprite.character = character;
        }
        if let Some(animation) = world.get_sprite_animation_mut(entity) {
            animation.elapsed = elapsed;
            animation.current_frame = current_frame;
            animation.finished = finished;
        }
    }
}