diff --git a/src/asset.rs b/src/asset.rs index a907eba..c340f28 100644 --- a/src/asset.rs +++ b/src/asset.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] //! Cross-platform asset loading abstraction. //! On desktop, assets are embedded using include_bytes!; on Emscripten, assets are loaded from the filesystem. @@ -5,7 +6,6 @@ use std::borrow::Cow; use std::io; use thiserror::Error; -#[allow(dead_code)] #[derive(Error, Debug)] pub enum AssetError { #[error("IO error: {0}")] diff --git a/src/audio.rs b/src/audio.rs index 32fd45e..0cc2b5d 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -11,6 +11,7 @@ const SOUND_ASSETS: [Asset; 4] = [Asset::Wav1, Asset::Wav2, Asset::Wav3, Asset:: /// /// This struct is responsible for initializing the audio device, loading sounds, /// and playing them. +#[allow(dead_code)] pub struct Audio { _mixer_context: mixer::Sdl2MixerContext, sounds: Vec, @@ -18,6 +19,12 @@ pub struct Audio { muted: bool, } +impl Default for Audio { + fn default() -> Self { + Self::new() + } +} + impl Audio { /// Creates a new `Audio` instance. pub fn new() -> Self { @@ -57,6 +64,7 @@ impl Audio { } /// Plays the "eat" sound effect. + #[allow(dead_code)] pub fn eat(&mut self) { if let Some(chunk) = self.sounds.get(self.next_sound_index) { match mixer::Channel(0).play(chunk, 0) { diff --git a/src/entity/direction.rs b/src/entity/direction.rs index 24ca810..3c2b233 100644 --- a/src/entity/direction.rs +++ b/src/entity/direction.rs @@ -18,7 +18,7 @@ impl Direction { } } - pub fn to_ivec2(&self) -> IVec2 { + pub fn as_ivec2(&self) -> IVec2 { (*self).into() } } diff --git a/src/entity/graph.rs b/src/entity/graph.rs index 27d8e55..da1dbe1 100644 --- a/src/entity/graph.rs +++ b/src/entity/graph.rs @@ -28,7 +28,7 @@ pub struct Node { /// Each field contains an optional edge leading in that direction. /// This structure is used to represent the adjacency list for each node, /// providing O(1) access to edges in any cardinal direction. -#[derive(Debug)] +#[derive(Debug, Default)] pub struct Intersection { /// Edge leading upward from this node, if it exists. pub up: Option, @@ -40,17 +40,6 @@ pub struct Intersection { pub right: Option, } -impl Default for Intersection { - fn default() -> Self { - Self { - up: None, - down: None, - left: None, - right: None, - } - } -} - impl Intersection { /// Returns an iterator over all edges from this intersection. /// @@ -253,6 +242,7 @@ pub enum Position { }, } +#[allow(dead_code)] impl Position { /// Returns `true` if the position is exactly at a node. pub fn is_at_node(&self) -> bool { @@ -260,6 +250,7 @@ impl Position { } /// Returns the `NodeId` of the current or most recently departed node. + #[allow(clippy::wrong_self_convention)] pub fn from_node_id(&self) -> NodeId { match self { Position::AtNode(id) => *id, @@ -268,6 +259,7 @@ impl Position { } /// Returns the `NodeId` of the destination node, if currently on an edge. + #[allow(clippy::wrong_self_convention)] pub fn to_node_id(&self) -> Option { match self { Position::AtNode(_) => None, diff --git a/src/entity/pacman.rs b/src/entity/pacman.rs index 2a1126b..9b4d5a7 100644 --- a/src/entity/pacman.rs +++ b/src/entity/pacman.rs @@ -29,12 +29,12 @@ impl Pacman { Direction::Right => "pacman/right", }; let moving_tiles = vec![ - SpriteAtlas::get_tile(&atlas, &format!("{}_a.png", moving_prefix)).unwrap(), - SpriteAtlas::get_tile(&atlas, &format!("{}_b.png", moving_prefix)).unwrap(), - SpriteAtlas::get_tile(&atlas, "pacman/full.png").unwrap(), + SpriteAtlas::get_tile(atlas, &format!("{moving_prefix}_a.png")).unwrap(), + SpriteAtlas::get_tile(atlas, &format!("{moving_prefix}_b.png")).unwrap(), + SpriteAtlas::get_tile(atlas, "pacman/full.png").unwrap(), ]; - let stopped_tiles = vec![SpriteAtlas::get_tile(&atlas, &format!("{}_b.png", moving_prefix)).unwrap()]; + let stopped_tiles = vec![SpriteAtlas::get_tile(atlas, &format!("{moving_prefix}_b.png")).unwrap()]; textures.insert(direction, AnimatedTexture::new(moving_tiles, 0.08)); stopped_textures.insert(direction, AnimatedTexture::new(stopped_tiles, 0.1)); diff --git a/src/game.rs b/src/game.rs index bd8448b..35cbfd7 100644 --- a/src/game.rs +++ b/src/game.rs @@ -36,7 +36,6 @@ pub struct Game { atlas: SpriteAtlas, map_texture: AtlasTile, text_texture: TextTexture, - debug_text_texture: TextTexture, // Audio pub audio: Audio, @@ -71,9 +70,9 @@ impl Game { map_texture.color = Some(Color::RGB(0x20, 0x20, 0xf9)); let text_texture = TextTexture::new(1.0); - let debug_text_texture = TextTexture::new(0.5); let audio = Audio::new(); let pacman = Pacman::new(&map.graph, pacman_start_node, &atlas); + Game { score: 0, map, @@ -81,7 +80,6 @@ impl Game { debug_mode: false, map_texture, text_texture, - debug_text_texture, audio, atlas, } @@ -92,7 +90,6 @@ impl Game { if keycode == Keycode::M { self.audio.set_mute(!self.audio.is_muted()); - return; } } @@ -122,7 +119,6 @@ impl Game { } fn draw_hud(&mut self, canvas: &mut Canvas) -> Result<()> { - let score_text = self.score.to_string(); let lives = 3; let score_text = format!("{:02}", self.score); let x_offset = 4; diff --git a/src/map/builder.rs b/src/map/builder.rs index 86e9e24..d62b00f 100644 --- a/src/map/builder.rs +++ b/src/map/builder.rs @@ -81,7 +81,7 @@ impl Map { // Iterate over the queue, adding nodes to the graph and connecting them to their neighbors while let Some(source_position) = queue.pop_front() { for &dir in DIRECTIONS.iter() { - let new_position = source_position + dir.to_ivec2(); + let new_position = source_position + dir.as_ivec2(); // Skip if the new position is out of bounds if new_position.x < 0 @@ -114,7 +114,7 @@ impl Map { // Connect the new node to the source node let source_node_id = grid_to_node .get(&source_position) - .expect(&format!("Source node not found for {source_position}")); + .unwrap_or_else(|| panic!("Source node not found for {source_position}")); // Connect the new node to the source node graph @@ -129,7 +129,7 @@ impl Map { for dir in DIRECTIONS { // If the node doesn't have an edge in this direction, look for a neighbor in that direction if graph.adjacency_list[node_id].get(dir).is_none() { - let neighbor = grid_pos + dir.to_ivec2(); + let neighbor = grid_pos + dir.as_ivec2(); // If the neighbor exists, connect the node to it if let Some(&neighbor_id) = grid_to_node.get(&neighbor) { graph @@ -198,10 +198,10 @@ impl Map { let (house_entrance_node_id, house_entrance_node_position) = { // Translate the grid positions to the actual node ids let left_node = grid_to_node - .get(&(house_door[0].expect("First house door position not acquired") + Direction::Left.to_ivec2())) + .get(&(house_door[0].expect("First house door position not acquired") + Direction::Left.as_ivec2())) .expect("Left house door node not found"); let right_node = grid_to_node - .get(&(house_door[1].expect("Second house door position not acquired") + Direction::Right.to_ivec2())) + .get(&(house_door[1].expect("Second house door position not acquired") + Direction::Right.as_ivec2())) .expect("Right house door node not found"); // Calculate the position of the house node @@ -230,10 +230,10 @@ impl Map { // Place the nodes at, above, and below the center position let center_node_id = graph.add_node(Node { position: center_pos }); let top_node_id = graph.add_node(Node { - position: center_pos + (Direction::Up.to_ivec2() * (CELL_SIZE as i32 / 2)).as_vec2(), + position: center_pos + (Direction::Up.as_ivec2() * (CELL_SIZE as i32 / 2)).as_vec2(), }); let bottom_node_id = graph.add_node(Node { - position: center_pos + (Direction::Down.to_ivec2() * (CELL_SIZE as i32 / 2)).as_vec2(), + position: center_pos + (Direction::Down.as_ivec2() * (CELL_SIZE as i32 / 2)).as_vec2(), }); // Connect the center node to the top and bottom nodes @@ -249,7 +249,7 @@ impl Map { // Calculate the position of the center line's center node let center_line_center_position = - house_entrance_node_position + (Direction::Down.to_ivec2() * (3 * CELL_SIZE as i32)).as_vec2(); + house_entrance_node_position + (Direction::Down.as_ivec2() * (3 * CELL_SIZE as i32)).as_vec2(); // Create the center line let (center_center_node_id, center_top_node_id) = create_house_line(graph, center_line_center_position); @@ -262,13 +262,13 @@ impl Map { // Create the left line let (left_center_node_id, _) = create_house_line( graph, - center_line_center_position + (Direction::Left.to_ivec2() * (CELL_SIZE as i32 * 2)).as_vec2(), + center_line_center_position + (Direction::Left.as_ivec2() * (CELL_SIZE as i32 * 2)).as_vec2(), ); // Create the right line let (right_center_node_id, _) = create_house_line( graph, - center_line_center_position + (Direction::Right.to_ivec2() * (CELL_SIZE as i32 * 2)).as_vec2(), + center_line_center_position + (Direction::Right.as_ivec2() * (CELL_SIZE as i32 * 2)).as_vec2(), ); debug!("Left center node id: {left_center_node_id}"); @@ -300,7 +300,7 @@ impl Map { Direction::Left, Node { position: left_tunnel_entrance_node.position - + (Direction::Left.to_ivec2() * (CELL_SIZE as i32 * 2)).as_vec2(), + + (Direction::Left.as_ivec2() * (CELL_SIZE as i32 * 2)).as_vec2(), }, ) .expect("Failed to connect left tunnel entrance to left tunnel hidden node") @@ -319,7 +319,7 @@ impl Map { Direction::Right, Node { position: right_tunnel_entrance_node.position - + (Direction::Right.to_ivec2() * (CELL_SIZE as i32 * 2)).as_vec2(), + + (Direction::Right.as_ivec2() * (CELL_SIZE as i32 * 2)).as_vec2(), }, ) .expect("Failed to connect right tunnel entrance to right tunnel hidden node") diff --git a/src/texture/animated.rs b/src/texture/animated.rs index 24576bd..84161fa 100644 --- a/src/texture/animated.rs +++ b/src/texture/animated.rs @@ -35,7 +35,7 @@ impl AnimatedTexture { } pub fn render(&self, canvas: &mut Canvas, atlas: &mut SpriteAtlas, dest: Rect) -> Result<()> { - let mut tile = self.current_tile().clone(); + let mut tile = *self.current_tile(); tile.render(canvas, atlas, dest) } } diff --git a/src/texture/blinking.rs b/src/texture/blinking.rs index 58eeda7..6176b9c 100644 --- a/src/texture/blinking.rs +++ b/src/texture/blinking.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] use crate::texture::sprite::AtlasTile; #[derive(Clone)] diff --git a/src/texture/sprite.rs b/src/texture/sprite.rs index 65a577e..5cea681 100644 --- a/src/texture/sprite.rs +++ b/src/texture/sprite.rs @@ -76,15 +76,30 @@ impl SpriteAtlas { }) } + #[allow(dead_code)] pub fn set_color(&mut self, color: Color) { self.default_color = Some(color); } + #[allow(dead_code)] pub fn texture(&self) -> &Texture<'static> { &self.texture } } +/// Converts a `Texture` to a `Texture<'static>` using transmute. +/// +/// # Safety +/// +/// This function is unsafe because it uses `std::mem::transmute` to change the lifetime +/// of the texture from the original lifetime to `'static`. The caller must ensure that: +/// +/// - The original `Texture` will live for the entire duration of the program +/// - No references to the original texture exist that could become invalid +/// - The texture is not dropped while still being used as a `'static` reference +/// +/// This is typically used when you have a texture that you know will live for the entire +/// program duration and need to store it in a structure that requires a `'static` lifetime. pub unsafe fn texture_to_static(texture: Texture) -> Texture<'static> { std::mem::transmute(texture) } diff --git a/src/texture/text.rs b/src/texture/text.rs index fce516b..e568237 100644 --- a/src/texture/text.rs +++ b/src/texture/text.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + //! This module provides text rendering using the texture atlas. //! //! The TextTexture system renders text from the atlas using character mapping.