diff options
Diffstat (limited to 'src/animation.rs')
-rw-r--r-- | src/animation.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/animation.rs b/src/animation.rs new file mode 100644 index 0000000..24932b2 --- /dev/null +++ b/src/animation.rs @@ -0,0 +1,81 @@ +use ggez::graphics::Rect; +use std::collections::HashMap; +use std::f32::consts::PI; +use std::time::Instant; + +use crate::entity::Action; +use crate::tileset::Tileset; + +#[derive(Clone)] +pub struct Animation { + pub animation: Vec<(usize, Rect)>, + pub animations: HashMap<Action, Vec<(usize, Rect)>>, + pub timer: Instant, + pub source: Rect, +} + +impl Animation { + pub fn new(tileset: &Tileset) -> Animation { + let mut animations = HashMap::new(); + + let mut source = tileset.get_tile_by_entity_keyframe("player-top", 0); + source.h += tileset.get_tile_by_entity_keyframe("player-bottom", 0).h; + animations.insert(Action::IdleLeft, vec![(1, source)]); + + let mut moving = tileset.get_tile_by_entity_keyframe("player-top", 1); + moving.h += tileset.get_tile_by_entity_keyframe("player-bottom", 1).h; + + animations.insert(Action::MovingLeft, vec![(100, source), (100, moving)]); + animations.insert(Action::MovingUpLeft, vec![(100, source), (100, moving)]); + animations.insert(Action::MovingDownLeft, vec![(100, source), (100, moving)]); + + source = flip(source); + moving = flip(moving); + + animations.insert(Action::IdleRight, vec![(1, source)]); + + animations.insert(Action::MovingRight, vec![(100, source), (100, moving)]); + animations.insert(Action::MovingUpRight, vec![(100, source), (100, moving)]); + animations.insert(Action::MovingDownRight, vec![(100, source), (100, moving)]); + + Animation { + animations, + source, + timer: Instant::now(), + animation: Vec::new(), + } + } + + pub fn update(&mut self, action: &Action) { + self.animation = self.animations.get(&action).cloned().unwrap_or_default(); + let (source, timer) = next_source(self.source, &self.animation, self.timer); + self.source = source; + self.timer = timer; + } +} + +pub fn next_source(source: Rect, animation: &[(usize, Rect)], timer: Instant) -> (Rect, Instant) { + if let Some(mut i) = animation.iter().position(|a| a.1 == source) { + if timer.elapsed().as_millis() > animation[i].0 as u128 { + i = if i == animation.len() - 1 { 0 } else { i + 1 }; + (animation[i].1, Instant::now()) + } else { + (source, timer) + } + } else if !animation.is_empty() { + (animation[0].1, timer) + } else { + (source, timer) + } +} + +pub fn convert_angle_to_rad(angle: f32) -> f32 { + angle * (PI / 180.0) +} + +pub fn flip(rect: Rect) -> Rect { + let mut r = rect; + r.x *= -1.0; + r.x -= rect.w; + r +} |