Newer
Older
AnimationOverride, AnimationPaused, AnimationSet, AnimationStatus, OverrideData,
SimpleAnimation, SimpleAnimationStatus, SyncToParent,
use crate::directionality::Directionality;
use bevy::asset::Assets;
use bevy::prelude::{
Commands, Entity, EventWriter, Handle, Parent, Query, Res, Time, With, Without,
};
pub struct AnimationComponents {
handle: &'static Handle<AnimationSet>,
status: &'static mut AnimationStatus,
pub struct DirectionalAnimationComponents {
handle: &'static Handle<AnimationSet>,
direction: &'static Directionality,
status: &'static mut AnimationStatus,
pub struct OverrideAnimationComponents {
handle: &'static Handle<AnimationSet>,
data: Option<&'static OverrideData>,
status: &'static mut AnimationOverride,
#[derive(QueryData)]
#[query_data(mutable)]
pub struct DirectionalOverrideAnimationComponents {
handle: &'static Handle<AnimationSet>,
direction: &'static Directionality,
data: Option<&'static OverrideData>,
status: &'static mut AnimationOverride,
atlas: &'static mut TextureAtlas,
}
pub struct SimpleAnimationComponents {
anim: &'static SimpleAnimation,
status: &'static mut SimpleAnimationStatus,
pub struct OnlyAnimations {
_status: With<AnimationStatus>,
_override: Without<AnimationOverride>,
_direction: Without<Directionality>,
_paused: Without<AnimationPaused>,
}
pub struct OnlyDirectionalAnimations {
_status: With<AnimationStatus>,
_direction: With<Directionality>,
_override: Without<AnimationOverride>,
_paused: Without<AnimationPaused>,
}
pub struct OnlyOverrideAnimations {
_override: With<AnimationOverride>,
_direction: Without<Directionality>,
_paused: Without<AnimationPaused>,
}
pub struct OnlyDirectionalOverrideAnimations {
_override: With<AnimationOverride>,
_direction: With<Directionality>,
_paused: Without<AnimationPaused>,
}
macro_rules! get_current_anim {
($anims: expr, $handle: expr, $name: expr) => {
match $anims.get($handle) {
Some(active) => match active.get(&$name) {
Some(inner) => inner,
None => continue,
},
None => continue,
};
($anims: expr, $handle: expr, $name: expr, $($also: expr),+) => {
match $anims.get($handle) {
Some(active) => match active.get(&$name)$(.or_else(|| active.get(&$also)))+ {
Some(inner) => inner,
None => continue,
},
None => continue,
}
};
}
macro_rules! tick_animation {
($delta: expr, $anim: expr, $status: expr, $atlas: expr) => {{
let current_frame = $atlas.index;
let mut has_looped = false;
$status.frame_time += $delta.as_secs_f32();
while $status.frame_time >= $anim.frame_secs {
$status.frame_time = ($status.frame_time - $anim.frame_secs).max(0.0);
let next_frame = $status.active_step.saturating_add(1);
$status.active_step = if next_frame >= $anim.frames.len() {
has_looped = true;
0
} else {
next_frame
};
}
if current_frame != $anim.frames[$status.active_step] {
has_looped
}};
}
pub fn play_animations(
time: Res<Time>,
mut anim_query: Query<AnimationComponents, OnlyAnimations>,
animations: Res<Assets<AnimationSet>>,
) {
let delta = time.delta();
for AnimationComponentsItem {
mut status,
handle,
} in &mut anim_query
{
let anim = get_current_anim!(animations, handle, status.active_name);
pub fn play_directional_animations(
time: Res<Time>,
mut anim_query: Query<DirectionalAnimationComponents, OnlyDirectionalAnimations>,
animations: Res<Assets<AnimationSet>>,
) {
let delta = time.delta();
for DirectionalAnimationComponentsItem {
mut status,
handle,
direction,
} in &mut anim_query
{
let anim = get_current_anim!(
animations,
handle,
format!("{}_{}", status.active_name, direction),
status.active_name
);
pub fn play_override_animation(
time: Res<Time>,
mut commands: Commands,
mut anim_query: Query<(Entity, OverrideAnimationComponents), OnlyOverrideAnimations>,
animations: Res<Assets<AnimationSet>>,
mut events: EventWriter<AnimationCompleted>,
) {
let delta = time.delta();
for (
entity,
OverrideAnimationComponentsItem {
mut status,
handle,
data,
},
) in &mut anim_query
{
let anim = get_current_anim!(animations, handle, status.active_name);
if looped {
commands
.entity(entity)
.remove::<(AnimationOverride, OverrideData)>();
if let Some(data) = data {
events.send(AnimationCompleted {
entity,
user_data: **data,
});
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
pub fn play_directional_override_animation(
time: Res<Time>,
mut commands: Commands,
mut anim_query: Query<
(Entity, DirectionalOverrideAnimationComponents),
OnlyDirectionalOverrideAnimations,
>,
animations: Res<Assets<AnimationSet>>,
mut events: EventWriter<AnimationCompleted>,
) {
let delta = time.delta();
for (
entity,
DirectionalOverrideAnimationComponentsItem {
mut status,
direction,
handle,
mut atlas,
data,
},
) in &mut anim_query
{
let anim = get_current_anim!(
animations,
handle,
format!("{}_{}", status.active_name, direction),
status.active_name
);
let looped = tick_animation!(delta, anim, status, atlas);
if looped {
commands
.entity(entity)
.remove::<(AnimationOverride, OverrideData)>();
if let Some(data) = data {
events.send(AnimationCompleted {
entity,
user_data: **data,
});
}
}
}
}
pub fn play_simple_animation(
time: Res<Time>,
mut anim_query: Query<SimpleAnimationComponents, Without<AnimationPaused>>,
) {
let delta = time.delta();
for SimpleAnimationComponentsItem {
mut status,
anim,
} in &mut anim_query
{
pub fn sync_child_animation(
mut children: Query<(&Parent, &mut TextureAtlas), With<SyncToParent>>,
parents: Query<&TextureAtlas, Without<SyncToParent>>,
) {
for (parent, mut child_sprite) in &mut children {
if let Ok(parent_sprite) = parents.get(**parent) {
if parent_sprite.index != child_sprite.index {
child_sprite.index = parent_sprite.index;