use crate::ecs::sprite_animator::components::LoopMode;
use crate::ecs::world::{SPRITE, SPRITE_ANIMATOR, World};
pub fn sprite_animation_system(world: &mut World) {
let delta_time = world.resources.window.timing.delta_time;
let entities: Vec<_> = world.query_entities(SPRITE_ANIMATOR | SPRITE).collect();
for entity in entities {
let (uv_min, uv_max, texture_index) = {
let Some(animator) = world.get_sprite_animator_mut(entity) else {
continue;
};
if !animator.playing || animator.frames.is_empty() {
continue;
}
animator.elapsed += delta_time * animator.speed;
let frame_duration = animator.frames[animator.current_frame].duration;
if animator.elapsed >= frame_duration {
animator.elapsed -= frame_duration;
match animator.loop_mode {
LoopMode::Once => {
if animator.current_frame + 1 < animator.frames.len() {
animator.current_frame += 1;
} else {
animator.playing = false;
}
}
LoopMode::Loop => {
animator.current_frame =
(animator.current_frame + 1) % animator.frames.len();
}
LoopMode::PingPong => {
if animator.ping_pong_forward {
if animator.current_frame + 1 < animator.frames.len() {
animator.current_frame += 1;
} else {
animator.ping_pong_forward = false;
if animator.current_frame > 0 {
animator.current_frame -= 1;
}
}
} else if animator.current_frame > 0 {
animator.current_frame -= 1;
} else {
animator.ping_pong_forward = true;
animator.current_frame += 1;
}
}
}
}
let frame = &animator.frames[animator.current_frame];
(frame.uv_min, frame.uv_max, frame.texture_index)
};
if let Some(sprite) = world.get_sprite_mut(entity) {
sprite.uv_min = uv_min;
sprite.uv_max = uv_max;
if let Some(texture_index) = texture_index {
sprite.texture_index = texture_index;
sprite.texture_index2 = texture_index;
}
}
}
}