Implement optional sprite animation auto looping

This commit is contained in:
SeanOMik 2024-12-01 18:15:27 -05:00
parent 275fdbc8d8
commit d4fc3000f1
Signed by: SeanOMik
GPG key ID: FEC9E2FC15235964

View file

@ -26,6 +26,8 @@ pub struct SpriteAnimation {
pub frames: Vec<URect>,
/// The length of time a frame is displayed.
pub frame_time: f32,
/// Should the animation loop after its completed.
pub auto_loop: bool,
}
impl SpriteAnimation {
@ -36,7 +38,7 @@ impl SpriteAnimation {
/// * `frame_time` - The time per frame of the animation.
/// * `atlas` - The texture atlas that this animation is from, used to acquire `self.frames`.
/// * `sprites` are the rect indexes in the atlas for this animation.
pub fn from_atlas<I>(name: &str, frame_time: f32, atlas: &TextureAtlas, sprites: I) -> Self
pub fn from_atlas<I>(name: &str, frame_time: f32, atlas: &TextureAtlas, auto_loop: bool, sprites: I) -> Self
where
I: Iterator<Item = u32>,
{
@ -51,6 +53,7 @@ impl SpriteAnimation {
name: name.into(),
frames,
frame_time,
auto_loop,
}
}
}
@ -70,7 +73,13 @@ impl IntoSpriteAnimation for SpriteAnimation {
impl<'a, I: Iterator<Item = u32> + Clone> IntoSpriteAnimation for (&'a str, f32, I) {
fn into_animation(&self, atlas: &TextureAtlas) -> SpriteAnimation {
SpriteAnimation::from_atlas(self.0, self.1, atlas, self.2.clone())
SpriteAnimation::from_atlas(self.0, self.1, atlas, true, self.2.clone())
}
}
impl<'a, I: Iterator<Item = u32> + Clone> IntoSpriteAnimation for (&'a str, f32, bool, I) {
fn into_animation(&self, atlas: &TextureAtlas) -> SpriteAnimation {
SpriteAnimation::from_atlas(self.0, self.1, atlas, self.2, self.3.clone())
}
}
@ -171,6 +180,8 @@ pub struct ActiveAtlasAnimation {
/// This is not the index of the rect in the atlas.
pub index: u32,
pub paused: bool,
/// A boolean indicating if the animation has reached its last frame
pub complete: bool,
/// The time since last animation frame change.
///
/// This is used to detect if enough time has passed for the frame.
@ -186,6 +197,7 @@ impl ActiveAtlasAnimation {
name: name.into(),
index: 0,
paused: false,
complete: false,
timer: 0.0,
}
}
@ -198,6 +210,7 @@ impl ActiveAtlasAnimation {
name: name.into(),
index,
paused: false,
complete: false,
timer: 0.0,
}
}
@ -275,13 +288,23 @@ fn system_animation_entity_impl(
return;
}
if active.timer >= anim.frame_time {
if anim.auto_loop && active.complete {
active.complete = false;
}
if active.timer >= anim.frame_time && !active.complete && !active.paused {
active.timer = 0.0;
active.index += 1;
// wrap the animation around
if active.index as usize >= anim.frames.len() {
active.index = 0;
if anim.auto_loop {
// wrap the animation around
active.index = 0;
} else {
active.index = anim.frames.len() as u32 - 1;
active.complete = true;
return;
}
}
// Get the sprite for the animation frame