use bevy::prelude::*; use crate::definitions::*; use crate::query::AnimationQuery; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, SystemLabel)] pub enum AnimationSystems { TickAnimations, SyncAnimations, } #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AnimationCompleted { pub entity: Entity, pub user_data: u128, } pub fn tick_animations(time: Res<Time>, mut query: AnimationQuery) { let seconds = time.delta_seconds(); let _ = query.tick_all(seconds); } pub fn tick_simple_sprite_animations( time: Res<Time>, mut query: Query< ( &SimpleLoopedAnimation, &mut SimpleLoopedAnimationStatus, &mut TextureAtlasSprite, ), With<HasSimpleAnimations>, >, ) { let seconds = time.delta_seconds(); for (animation, mut state, mut sprite) in &mut query { state.frame_time += seconds; while state.frame_time >= animation.frame_secs { state.frame_time -= animation.frame_secs; state.active_step += 1; if state.active_step >= animation.frames.len() { state.active_step = 0; } } sprite.index = animation.frames[state.active_step]; } } pub fn sync_parent_animations(mut query: AnimationQuery) { query.sync_parent_animations(); } #[cfg(feature = "ecs_tilemap")] pub fn tick_simple_tilemap_animation( time: Res<Time>, mut query: Query< ( &SimpleLoopedAnimation, &mut SimpleLoopedAnimationStatus, &mut bevy_ecs_tilemap::tiles::TileTextureIndex, ), With<HasSimpleAnimations>, >, ) { let seconds = time.delta_seconds(); for (animation, mut state, mut tile) in &mut query { state.frame_time += seconds; while state.frame_time >= animation.frame_secs { state.frame_time -= animation.frame_secs; state.active_step += 1; if state.active_step >= animation.frames.len() { state.active_step = 0; } } *tile = bevy_ecs_tilemap::tiles::TileTextureIndex(animation.frames[state.active_step] as u32); } } pub struct AnimationSystemsPlugin; impl Plugin for AnimationSystemsPlugin { fn build(&self, app: &mut App) { let mut tick_systems = SystemSet::new() .label(AnimationSystems::TickAnimations) .with_system(tick_animations) .with_system(tick_simple_sprite_animations); #[cfg(feature = "ecs_tilemap")] { tick_systems = tick_systems.with_system(tick_simple_tilemap_animation); } app.add_event::<AnimationCompleted>() .add_system_set_to_stage(CoreStage::PostUpdate, tick_systems) .add_system_to_stage( CoreStage::PostUpdate, sync_parent_animations .label(AnimationSystems::SyncAnimations) .after(AnimationSystems::TickAnimations), ); } }