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