Skip to content

Commit

Permalink
feat: Allow to reset animation (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcornaz authored Jul 26, 2021
1 parent 4c7b5ad commit 1d54790
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 4 deletions.
19 changes: 18 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
//!
//! For a more precise configuration, it is possible to define the duration of each frame:
//!
//! ```rust
//! ```
//! # use benimator::*;
//! # use std::time::Duration;
//! SpriteSheetAnimation::from_frames(vec![
Expand All @@ -91,6 +91,22 @@
//! ]);
//! ```
//!
//! ## Reset animation
//!
//! For each entity with a [`SpriteSheetAnimation`], a [`SpriteSheetAnimationState`] component is automatically inserted.
//! It can be used to reset the animation state by calling [`SpriteSheetAnimationState::reset`]
//!
//! ```
//! # use bevy::prelude::*;
//! # use benimator::SpriteSheetAnimationState;
//!
//! fn restart_anim_from_start(mut query: Query<&mut SpriteSheetAnimationState>) {
//! for mut state in query.iter_mut() {
//! state.reset();
//! }
//! }
//! ```

#[cfg(test)]
#[macro_use]
extern crate rstest;
Expand All @@ -101,6 +117,7 @@ use bevy_ecs::prelude::*;
use bevy_reflect::Reflect;

pub use animation::{AnimationMode, Frame, SpriteSheetAnimation};
pub use state::SpriteSheetAnimationState;

mod animation;
mod state;
Expand Down
52 changes: 49 additions & 3 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,36 @@ pub(crate) fn post_update_system() -> impl System<In = (), Out = ()> {
animate.system()
}

/// Animation state component which is automatically inserted/removed
///
/// It can be used to reset the animation state.
///
/// # Example
///
/// ```
/// # use bevy::prelude::*;
/// # use benimator::SpriteSheetAnimationState;
///
/// fn restart_anim_from_start(mut query: Query<&mut SpriteSheetAnimationState>) {
/// for mut state in query.iter_mut() {
/// state.reset();
/// }
/// }
/// ```
#[derive(Default)]
struct SpriteSheetAnimationState {
pub struct SpriteSheetAnimationState {
current_frame: usize,
elapsed_in_frame: Duration,
}

impl SpriteSheetAnimationState {
/// Reset animation state
///
/// The animation will restart from the first frame, like if the animation was freshly spawned.
pub fn reset(&mut self) {
*self = Self::default();
}

/// Update the animation and the sprite (if necessary)
///
/// Returns true if the animation has ended
Expand All @@ -45,8 +68,7 @@ impl SpriteSheetAnimationState {
} else if matches!(animation.mode, AnimationMode::Repeat) {
self.current_frame = 0;
} else {
self.current_frame = 0;
self.elapsed_in_frame = Duration::ZERO;
self.reset();
return true;
}

Expand Down Expand Up @@ -145,6 +167,30 @@ mod tests {
frame_duration - Duration::from_millis(1)
}

mod reset {
use super::*;

#[fixture]
fn state() -> SpriteSheetAnimationState {
SpriteSheetAnimationState {
current_frame: 1,
elapsed_in_frame: Duration::from_secs(1),
}
}

#[rstest]
fn resets_current_frame(mut state: SpriteSheetAnimationState) {
state.reset();
assert_eq!(state.current_frame, 0);
}

#[rstest]
fn resets_elapsed_time(mut state: SpriteSheetAnimationState) {
state.reset();
assert_eq!(state.elapsed_in_frame, Duration::ZERO);
}
}

mod on_first_frame {
use super::*;

Expand Down

0 comments on commit 1d54790

Please sign in to comment.