diff --git a/src/anim/mod.rs b/src/anim/mod.rs new file mode 100644 index 0000000..a4ad353 --- /dev/null +++ b/src/anim/mod.rs @@ -0,0 +1,3 @@ +//! Animation-related components + +pub mod sprite; diff --git a/src/anim/sprite.rs b/src/anim/sprite.rs new file mode 100644 index 0000000..fddd96e --- /dev/null +++ b/src/anim/sprite.rs @@ -0,0 +1,76 @@ +//! Animated sprite module + +use std::{collections::HashMap, time::Duration}; + +use bevy::prelude::*; + +use crate::timer::duration_from_bpm; + +/// Data for [AnimatedSprite] +#[derive(Clone, PartialEq, Debug, Reflect)] +#[reflect(Clone, PartialEq, Debug)] +pub struct AnimationData { + /// Handle to sprite image + pub image: Handle, + /// Animation duration in beats + pub duration: f32, +} + +impl AnimationData { + /// Construct new [AnimationData] + pub fn new(image: Handle, duration: f32) -> Self { + Self { image, duration } + } +} + +/// Animated sprite with states +#[derive(Clone, PartialEq, Debug, Reflect)] +#[reflect(Clone, PartialEq, Debug, Default)] +pub struct AnimatedSprite { + data: HashMap, + current: Option, + timer: Timer, + bpm: Duration, +} + +impl Default for AnimatedSprite { + fn default() -> Self { + Self { + data: HashMap::new(), + current: None, + timer: Timer::new(Duration::default(), TimerMode::Repeating), + bpm: Duration::default(), + } + } +} + +impl AnimatedSprite { + /// Add new animation to sprite + pub fn add(&mut self, data: AnimationData, label: String) { + self.data.insert(label, data); + } + + /// Sets internal BPM state + pub fn set_bpm(&mut self, bpm: f32) { + self.bpm = duration_from_bpm(bpm); + } + + /// Finds animation by its label and returns true if it started playing + pub fn play(&mut self, label: &str, mode: TimerMode) -> bool { + match self.data.get(label) { + Some(data) => { + self.current = Some(data.clone()); + self.timer.set_duration(self.bpm.mul_f32(data.duration)); + self.timer.set_mode(mode); + + true + }, + None => false, + } + } + + /// Updates animation and returns true if animation should stop + pub fn tick(&mut self, dt: Duration) -> bool { + self.timer.tick(dt).just_finished() + } +} diff --git a/src/lib.rs b/src/lib.rs index bdf01d2..75484eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ #[cfg(test)] mod tests; +pub mod anim; pub mod combat; pub mod graph; pub mod input;