use bevy::prelude::*; use crate::definitions::*; use crate::query::AnimationQuery; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, SystemSet)] pub enum AnimationSystems { TickAnimations, SyncAnimations, } #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Event)] #[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) { app.configure_sets( PostUpdate, (AnimationSystems::TickAnimations.before(AnimationSystems::SyncAnimations),), ); app.add_event::<AnimationCompleted>() .add_systems( PostUpdate, (tick_animations, tick_simple_sprite_animations) .in_set(AnimationSystems::SyncAnimations), ) .add_systems( PostUpdate, sync_parent_animations.in_set(AnimationSystems::SyncAnimations), ); #[cfg(feature = "ecs_tilemap")] { app.add_systems( PostUpdate, tick_simple_tilemap_animation.in_set(AnimationSystems::TickAnimations), ); } } }