Skip to content
Snippets Groups Projects
systems.rs 2.63 KiB
Newer Older
Louis's avatar
Louis committed
use bevy::prelude::*;

use crate::definitions::*;
use crate::query::AnimationQuery;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, SystemSet)]
Louis's avatar
Louis committed
pub enum AnimationSystems {
	TickAnimations,
	SyncAnimations,
}

Louis's avatar
Louis committed
#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Event)]
Louis's avatar
Louis committed
#[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);
	}
}
Louis's avatar
Louis committed

pub struct AnimationSystemsPlugin;

impl Plugin for AnimationSystemsPlugin {
	fn build(&self, app: &mut App) {
Louis's avatar
Louis committed
		app.configure_sets(
			PostUpdate,
			(AnimationSystems::TickAnimations.before(AnimationSystems::SyncAnimations),),
		);
Louis's avatar
Louis committed

		app.add_event::<AnimationCompleted>()
Louis's avatar
Louis committed
				PostUpdate,
				(tick_animations, tick_simple_sprite_animations)
Louis's avatar
Louis committed
					.in_set(AnimationSystems::SyncAnimations),
Louis's avatar
Louis committed
			.add_systems(
				PostUpdate,
				sync_parent_animations.in_set(AnimationSystems::SyncAnimations),
			);
		#[cfg(feature = "ecs_tilemap")]
		{
Louis's avatar
Louis committed
			app.add_systems(
				PostUpdate,
				tick_simple_tilemap_animation.in_set(AnimationSystems::TickAnimations),