bevy_animations/
plugins.rs1use core::panic;
2
3use bevy::prelude::*;
4
5use crate::*;
6
7#[derive(Debug, Default)]
22pub struct AnimationsPlugin {
23 pub pixels_per_meter: f32,
25}
26
27impl Plugin for AnimationsPlugin {
28 fn build(&self, app: &mut App) {
30 app.insert_resource(AnimationsConfig {
31 pixels_per_meter: self.pixels_per_meter,
32 })
33 .add_event::<AnimationEvent>()
34 .add_event::<ResetAnimationEvent>()
35 .add_event::<FXAnimationEvent>()
36 .insert_resource(Animations::default())
37 .insert_resource(EntitesToRemove::default())
38 .add_systems(
39 Update,
40 (
41 catch_fx_animation_events,
42 catch_animation_events,
43 catch_reset_events,
44 remove_entites,
45 )
46 .chain(),
47 );
48 }
49}
50
51fn catch_animation_events(
55 time: Res<Time>,
56 mut query: Query<(
57 &mut TextureAtlas,
58 &mut Handle<Image>,
59 &mut Sprite,
60 &mut Transform,
61 &Animator,
62 )>,
63 mut animations: ResMut<Animations>,
64 mut entities_to_remove: ResMut<EntitesToRemove>,
65 config: Res<AnimationsConfig>,
66 mut animation_events: EventReader<AnimationEvent>,
67 mut commands: Commands,
68) {
69 for event in animation_events.read() {
71 if !animations.has_entity(&event.1) {
72 panic!("Entity Not Found in Map For {} animation make sure your adding every necessary component to the entity i.e `Animator`", event.0);
73 }
74 if !animations.has_animation(event.0) {
75 panic!("Animation {} not found", event.0);
76 }
77 let (mut texture_atlas, mut texture, _, _, animator) =
79 match query.get_mut(event.1) {
80 Ok(handle) => handle,
81 Err(_) => {
82 entities_to_remove.0.push(event.1);
84 continue;
85 }
86 };
87 let direction = animator.get_direction();
88 if animations
90 .is_new_animation(event.0, &event.1)
91 .unwrap_or_else(|| {
92 panic!(
93 "Something Went Terribly Wrong Getting New Animation For {}",
94 event.0
95 )
96 })
97 {
98 let new_animation_handles = animations.get_handles(event.0).unwrap_or_else(|| {
99 panic!(
100 "Something Went Terribly Wrong Getting Animation For {}",
101 event.0
102 )
103 });
104 let animating_entity = animations.get_entity(&event.1).unwrap_or_else(|| panic!("Entity Not Found in Map For {} animation make sure your adding every necessary component to the entity i.e `AnimationDirection`", event.0));
106 let Some(new_animation_arc) = animating_entity.animations.get(event.0) else {
110 panic!("Animation `{}` not found for {:?} make sure the name matches your configuration", event.0, animating_entity.entity);
111 };
112
113 let mut new_animation = new_animation_arc.lock().unwrap();
115 let mut blocking = false;
116 let mut new_priority = 0;
117 let mut sprite_index = 0;
118
119 if let Some(new_timed_animation) = new_animation.timed_animation() {
121 blocking = new_timed_animation.blocking;
122 new_priority = new_timed_animation.blocking_priority;
123 sprite_index =
124 new_timed_animation.sprite_index(&animating_entity.last_valid_direction);
125 } else if let Some(new_singe_frame_animation) = new_animation.single_frame_animation() {
126 blocking = new_singe_frame_animation.blocking;
127 new_priority = new_singe_frame_animation.blocking_priority;
128 sprite_index =
129 new_singe_frame_animation.sprite_index(&animating_entity.last_valid_direction);
130 }
131 else if let Some(new_transform_animation) = new_animation.transform_animation() {
133 sprite_index =
134 new_transform_animation.sprite_index(&animating_entity.last_valid_direction);
135 }
136
137 if animating_entity.in_blocking_animation {
140 let mut curr_animation = animating_entity.curr_animation.lock().unwrap();
142 if let Some(curr_timed_animation) = curr_animation.timed_animation() {
143 if curr_timed_animation.blocking_priority > new_priority {
144 continue;
146 }
147 } else if let Some(curr_single_frame_animation) =
148 curr_animation.single_frame_animation()
149 {
150 if curr_single_frame_animation.blocking_priority > new_priority
152 && !curr_single_frame_animation.blocking_finished
153 {
154 continue;
156 }
157 } else {
158 continue;
160 }
161 }
162
163 animating_entity
164 .curr_animation
165 .lock()
166 .unwrap()
167 .reset_animation();
168 animating_entity.curr_animation = new_animation_arc.clone();
169 animating_entity.in_blocking_animation = blocking;
170
171 texture_atlas.index = sprite_index;
172 texture_atlas.layout = new_animation_handles.layout();
173 *texture = new_animation_handles.image();
174 }
175
176 let animating_entity = animations.get_entity(&event.1).unwrap_or_else(|| panic!("Entity Not Found in Map For {} animation make sure your adding every necessary component to the entity i.e `AnimationDirection`", event.0));
177 animating_entity.curr_animation_called = true;
178
179 if animating_entity.curr_direction != *direction {
181 animating_entity.curr_direction = direction.clone();
182 if *direction != AnimationDirection::Still {
184 animating_entity.last_valid_direction = direction.clone();
185 }
186 }
187 }
188
189 for (entity, animation_entity) in animations.entities.iter_mut() {
191 let (texture_atlas, _, sprite, transform, _) =
193 match query.get_mut(*entity) {
194 Ok(query) => query,
195 Err(_) => {
196 if !animation_entity.fx_animation {
198 entities_to_remove.0.push(*entity);
199 }
200 continue;
201 }
202 };
203 let mut curr_animation = animation_entity.curr_animation.lock().unwrap();
205
206 if !animation_entity.curr_animation_called {
208 continue;
209 }
210
211 if let Some(transform_animation) = curr_animation.transform_animation() {
215 if animation_entity.in_blocking_animation {
216 continue;
217 }
218 if transform_animation.cycle_animation(
219 sprite,
220 texture_atlas,
221 &animation_entity.last_valid_direction,
222 transform,
223 config.pixels_per_meter,
224 ).is_none() {
225 if animation_entity.fx_animation {
226 entities_to_remove.0.push(*entity);
227 commands.entity(*entity).despawn_recursive();
228 }
229 animation_entity.curr_animation_called = false;
230 }
231 }
232 else if let Some(timed_animation) = curr_animation.timed_animation() {
234 if timed_animation.cycle_animation(
235 sprite,
236 texture_atlas,
237 &animation_entity.last_valid_direction,
238 time.delta(),
239 ).is_none() {
240 if animation_entity.fx_animation {
241 entities_to_remove.0.push(*entity);
242 commands.entity(*entity).despawn_recursive();
243 }
244 animation_entity.in_blocking_animation = false;
245 animation_entity.curr_animation_called = false;
246 }
247 }
248 else if let Some(linear_timed_animation) = curr_animation.linear_timed_animation() {
250 if linear_timed_animation.cycle_animation(texture_atlas, time.delta()).is_none() {
251 if animation_entity.fx_animation {
252 entities_to_remove.0.push(*entity);
253 commands.entity(*entity).despawn_recursive();
254 }
255 animation_entity.in_blocking_animation = false;
256 animation_entity.curr_animation_called = false;
257 }
258 }
259 else if let Some(linear_transform_animation) = curr_animation.linear_transform_animation()
261 {
262 if linear_transform_animation.cycle_animation(
263 texture_atlas,
264 transform,
265 config.pixels_per_meter,
266 ).is_none() {
267 if animation_entity.fx_animation {
268 entities_to_remove.0.push(*entity);
269 commands.entity(*entity).despawn_recursive();
270 }
271 animation_entity.curr_animation_called = false;
272 }
273 }
274 else if let Some(single_frame_animation) = curr_animation.single_frame_animation() {
276 single_frame_animation.cycle_animation(
277 sprite,
278 texture_atlas,
279 &animation_entity.last_valid_direction,
280 time.delta(),
281 )
282 }
283 else {
285 panic!(
286 "Something Went Terribly Wrong Animating {} Check Your Configurations",
287 curr_animation.get_name()
288 );
289 }
290 }
291}
292
293fn catch_reset_events(
294 mut query: Query<(&mut Sprite, &mut TextureAtlas, &Animator)>,
295 mut animations: ResMut<Animations>,
296 mut entities_to_remove: ResMut<EntitesToRemove>,
297 mut animation_events: EventReader<ResetAnimationEvent>,
298) {
299 for event in animation_events.read() {
300 let (sprite, texture_atlas, animator) = match query.get_mut(event.0) {
302 Ok(q) => q,
303 Err(_) => {
304 entities_to_remove.0.push(event.0);
305 continue;
306 }
307 };
308 let direction = animator.get_direction();
309 let mut curr_animation = animations
310 .entities
311 .get_mut(&event.0)
312 .expect("Entity Not Found from `ResetAnimationEvent`")
313 .curr_animation
314 .lock()
315 .unwrap();
316 if let Some(timed_animation) = curr_animation.timed_animation() {
319 timed_animation.reset_animation(Some(sprite), Some(texture_atlas), Some(direction));
320 }
321 else if let Some(transform_animation) = curr_animation.transform_animation() {
323 transform_animation.reset_animation(Some(sprite), Some(texture_atlas), Some(direction));
324 }
325 else if let Some(linear_timed_animation) = curr_animation.linear_timed_animation() {
327 linear_timed_animation.reset_animation(Some(texture_atlas));
328 }
329 else if let Some(linear_transform_animation) = curr_animation.linear_transform_animation()
331 {
332 linear_transform_animation.reset_animation(Some(texture_atlas));
333 }
334 else if let Some(single_frame_animation) = curr_animation.single_frame_animation() {
336 single_frame_animation.reset_animation(Some(sprite), Some(direction));
337 } else {
338 panic!("Something went terribly wrong resetting the current animation");
339 }
340 }
341}
342
343fn catch_fx_animation_events(
344 mut event_reader: EventReader<FXAnimationEvent>,
345 mut commands: Commands,
346 mut animations: ResMut<Animations>,
347) {
348 for event in event_reader.read() {
349 let entity = commands.spawn(Animator::default()).id();
350 let Ok(sprite_sheet_bundle) = animations.start_fx_animation(entity, event.0, event.1)
351 else {
352 warn!("There was a problem spawning your FXAnimation {}", event.0);
353 continue;
354 };
355
356 commands
357 .entity(entity)
358 .insert(sprite_sheet_bundle)
359 .insert(FXAnimation)
360 .insert(Name::new("FX Animation"));
361 }
362}
363
364fn remove_entites(
366 mut animations: ResMut<Animations>,
367 mut entities_to_remove: ResMut<EntitesToRemove>,
368) {
369 for entity in entities_to_remove.0.iter() {
370 animations.entities.remove(entity);
371 }
372 entities_to_remove.0.clear();
373}