diff --git a/src/entity/direction.rs b/src/entity/direction.rs index bdeade8..cfb23af 100644 --- a/src/entity/direction.rs +++ b/src/entity/direction.rs @@ -29,9 +29,9 @@ impl Direction { self.into() } - /// Returns the direction as a u8 (0-3). Constant time. + /// Returns the direction as a usize (0-3). Constant time. /// This is useful for indexing into arrays. - pub const fn as_u8(self) -> u8 { + pub const fn as_usize(self) -> usize { match self { Direction::Up => 0, Direction::Down => 1, @@ -51,5 +51,3 @@ impl From for IVec2 { } } } - -pub const DIRECTIONS: [Direction; 4] = [Direction::Up, Direction::Down, Direction::Left, Direction::Right]; diff --git a/src/entity/pacman.rs b/src/entity/pacman.rs index 63b84f8..6db4d0d 100644 --- a/src/entity/pacman.rs +++ b/src/entity/pacman.rs @@ -15,7 +15,6 @@ use crate::texture::directional::DirectionalAnimatedTexture; use crate::texture::sprite::SpriteAtlas; use sdl2::keyboard::Keycode; use sdl2::render::{Canvas, RenderTarget}; -use std::collections::HashMap; /// Determines if Pac-Man can traverse a given edge. /// @@ -41,8 +40,8 @@ impl Pacman { /// Sets up animated textures for all four directions with moving and stopped states. /// The moving animation cycles through open mouth, closed mouth, and full sprites. pub fn new(graph: &Graph, start_node: NodeId, atlas: &SpriteAtlas) -> Self { - let mut textures = HashMap::new(); - let mut stopped_textures = HashMap::new(); + let mut textures = [None, None, None, None]; + let mut stopped_textures = [None, None, None, None]; for direction in Direction::DIRECTIONS { let moving_prefix = match direction { @@ -59,14 +58,9 @@ impl Pacman { let stopped_tiles = vec![SpriteAtlas::get_tile(atlas, &format!("{moving_prefix}_b.png")).unwrap()]; - textures.insert( - direction, - AnimatedTexture::new(moving_tiles, 0.08).expect("Invalid frame duration"), - ); - stopped_textures.insert( - direction, - AnimatedTexture::new(stopped_tiles, 0.1).expect("Invalid frame duration"), - ); + textures[direction.as_usize()] = Some(AnimatedTexture::new(moving_tiles, 0.08).expect("Invalid frame duration")); + stopped_textures[direction.as_usize()] = + Some(AnimatedTexture::new(stopped_tiles, 0.1).expect("Invalid frame duration")); } Self { diff --git a/src/texture/directional.rs b/src/texture/directional.rs index 2f4ff8e..aa71a7f 100644 --- a/src/texture/directional.rs +++ b/src/texture/directional.rs @@ -1,7 +1,6 @@ use anyhow::Result; use sdl2::rect::Rect; use sdl2::render::{Canvas, RenderTarget}; -use std::collections::HashMap; use crate::entity::direction::Direction; use crate::texture::animated::AnimatedTexture; @@ -9,12 +8,12 @@ use crate::texture::sprite::SpriteAtlas; #[derive(Clone)] pub struct DirectionalAnimatedTexture { - textures: HashMap, - stopped_textures: HashMap, + textures: [Option; 4], + stopped_textures: [Option; 4], } impl DirectionalAnimatedTexture { - pub fn new(textures: HashMap, stopped_textures: HashMap) -> Self { + pub fn new(textures: [Option; 4], stopped_textures: [Option; 4]) -> Self { Self { textures, stopped_textures, @@ -22,8 +21,10 @@ impl DirectionalAnimatedTexture { } pub fn tick(&mut self, dt: f32) { - for texture in self.textures.values_mut() { - texture.tick(dt); + for texture in self.textures.iter_mut() { + if let Some(texture) = texture { + texture.tick(dt); + } } } @@ -34,7 +35,7 @@ impl DirectionalAnimatedTexture { dest: Rect, direction: Direction, ) -> Result<()> { - if let Some(texture) = self.textures.get(&direction) { + if let Some(texture) = &self.textures[direction.as_usize()] { texture.render(canvas, atlas, dest) } else { Ok(()) @@ -48,7 +49,7 @@ impl DirectionalAnimatedTexture { dest: Rect, direction: Direction, ) -> Result<()> { - if let Some(texture) = self.stopped_textures.get(&direction) { + if let Some(texture) = &self.stopped_textures[direction.as_usize()] { texture.render(canvas, atlas, dest) } else { Ok(()) @@ -58,24 +59,24 @@ impl DirectionalAnimatedTexture { /// Returns true if the texture has a direction. #[allow(dead_code)] pub fn has_direction(&self, direction: Direction) -> bool { - self.textures.contains_key(&direction) + self.textures[direction.as_usize()].is_some() } /// Returns true if the texture has a stopped direction. #[allow(dead_code)] pub fn has_stopped_direction(&self, direction: Direction) -> bool { - self.stopped_textures.contains_key(&direction) + self.stopped_textures[direction.as_usize()].is_some() } /// Returns the number of textures. #[allow(dead_code)] pub fn texture_count(&self) -> usize { - self.textures.len() + self.textures.iter().filter(|t| t.is_some()).count() } /// Returns the number of stopped textures. #[allow(dead_code)] pub fn stopped_texture_count(&self) -> usize { - self.stopped_textures.len() + self.stopped_textures.iter().filter(|t| t.is_some()).count() } } diff --git a/tests/directional.rs b/tests/directional.rs index 753d615..e9b4708 100644 --- a/tests/directional.rs +++ b/tests/directional.rs @@ -4,7 +4,6 @@ use pacman::texture::animated::AnimatedTexture; use pacman::texture::directional::DirectionalAnimatedTexture; use pacman::texture::sprite::AtlasTile; use sdl2::pixels::Color; -use std::collections::HashMap; fn mock_atlas_tile(id: u32) -> AtlasTile { AtlasTile { @@ -20,10 +19,10 @@ fn mock_animated_texture(id: u32) -> AnimatedTexture { #[test] fn test_directional_texture_partial_directions() { - let mut textures = HashMap::new(); - textures.insert(Direction::Up, mock_animated_texture(1)); + let mut textures = [None, None, None, None]; + textures[Direction::Up.as_usize()] = Some(mock_animated_texture(1)); - let texture = DirectionalAnimatedTexture::new(textures, HashMap::new()); + let texture = DirectionalAnimatedTexture::new(textures, [None, None, None, None]); assert_eq!(texture.texture_count(), 1); assert!(texture.has_direction(Direction::Up)); @@ -34,7 +33,7 @@ fn test_directional_texture_partial_directions() { #[test] fn test_directional_texture_all_directions() { - let mut textures = HashMap::new(); + let mut textures = [None, None, None, None]; let directions = [ (Direction::Up, 1), (Direction::Down, 2), @@ -43,10 +42,10 @@ fn test_directional_texture_all_directions() { ]; for (direction, id) in directions { - textures.insert(direction, mock_animated_texture(id)); + textures[direction.as_usize()] = Some(mock_animated_texture(id)); } - let texture = DirectionalAnimatedTexture::new(textures, HashMap::new()); + let texture = DirectionalAnimatedTexture::new(textures, [None, None, None, None]); assert_eq!(texture.texture_count(), 4); for direction in &[Direction::Up, Direction::Down, Direction::Left, Direction::Right] {