mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-06 09:15:46 -06:00
chore: configure rustfmt, switch to LF line endings
This commit is contained in:
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* text=auto eol=lf
|
||||||
6
rustfmt.toml
Normal file
6
rustfmt.toml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Rustfmt configuration
|
||||||
|
edition = "2021"
|
||||||
|
max_width = 130
|
||||||
|
tab_spaces = 4
|
||||||
|
newline_style = "Unix"
|
||||||
|
use_small_heuristics = "Default"
|
||||||
@@ -9,13 +9,7 @@ use crate::direction::Direction;
|
|||||||
|
|
||||||
/// Trait for drawable atlas-based textures
|
/// Trait for drawable atlas-based textures
|
||||||
pub trait FrameDrawn {
|
pub trait FrameDrawn {
|
||||||
fn render(
|
fn render(&self, canvas: &mut Canvas<Window>, position: (i32, i32), direction: Direction, frame: Option<u32>);
|
||||||
&self,
|
|
||||||
canvas: &mut Canvas<Window>,
|
|
||||||
position: (i32, i32),
|
|
||||||
direction: Direction,
|
|
||||||
frame: Option<u32>,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A texture atlas abstraction for static (non-animated) rendering.
|
/// A texture atlas abstraction for static (non-animated) rendering.
|
||||||
@@ -28,13 +22,7 @@ pub struct AtlasTexture<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AtlasTexture<'a> {
|
impl<'a> AtlasTexture<'a> {
|
||||||
pub fn new(
|
pub fn new(texture: Texture<'a>, frame_count: u32, frame_width: u32, frame_height: u32, offset: Option<(i32, i32)>) -> Self {
|
||||||
texture: Texture<'a>,
|
|
||||||
frame_count: u32,
|
|
||||||
frame_width: u32,
|
|
||||||
frame_height: u32,
|
|
||||||
offset: Option<(i32, i32)>,
|
|
||||||
) -> Self {
|
|
||||||
AtlasTexture {
|
AtlasTexture {
|
||||||
raw_texture: texture,
|
raw_texture: texture,
|
||||||
frame_count,
|
frame_count,
|
||||||
@@ -62,13 +50,7 @@ impl<'a> AtlasTexture<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FrameDrawn for AtlasTexture<'a> {
|
impl<'a> FrameDrawn for AtlasTexture<'a> {
|
||||||
fn render(
|
fn render(&self, canvas: &mut Canvas<Window>, position: (i32, i32), direction: Direction, frame: Option<u32>) {
|
||||||
&self,
|
|
||||||
canvas: &mut Canvas<Window>,
|
|
||||||
position: (i32, i32),
|
|
||||||
direction: Direction,
|
|
||||||
frame: Option<u32>,
|
|
||||||
) {
|
|
||||||
let texture_source_frame_rect = self.get_frame_rect(frame.unwrap_or(0));
|
let texture_source_frame_rect = self.get_frame_rect(frame.unwrap_or(0));
|
||||||
let canvas_destination_rect = Rect::new(
|
let canvas_destination_rect = Rect::new(
|
||||||
position.0 + self.offset.0,
|
position.0 + self.offset.0,
|
||||||
@@ -157,13 +139,7 @@ impl<'a> AnimatedAtlasTexture<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FrameDrawn for AnimatedAtlasTexture<'a> {
|
impl<'a> FrameDrawn for AnimatedAtlasTexture<'a> {
|
||||||
fn render(
|
fn render(&self, canvas: &mut Canvas<Window>, position: (i32, i32), direction: Direction, frame: Option<u32>) {
|
||||||
&self,
|
|
||||||
canvas: &mut Canvas<Window>,
|
|
||||||
position: (i32, i32),
|
|
||||||
direction: Direction,
|
|
||||||
frame: Option<u32>,
|
|
||||||
) {
|
|
||||||
let frame = frame.unwrap_or_else(|| self.current_frame());
|
let frame = frame.unwrap_or_else(|| self.current_frame());
|
||||||
self.atlas.render(canvas, position, direction, Some(frame));
|
self.atlas.render(canvas, position, direction, Some(frame));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,7 @@ impl Audio {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, asset)| {
|
.map(|(i, asset)| {
|
||||||
let data = get_asset_bytes(*asset).expect("Failed to load sound asset");
|
let data = get_asset_bytes(*asset).expect("Failed to load sound asset");
|
||||||
let rwops = RWops::from_bytes(&data)
|
let rwops = RWops::from_bytes(&data).unwrap_or_else(|_| panic!("Failed to create RWops for sound {}", i + 1));
|
||||||
.unwrap_or_else(|_| panic!("Failed to create RWops for sound {}", i + 1));
|
|
||||||
rwops
|
rwops
|
||||||
.load_wav()
|
.load_wav()
|
||||||
.unwrap_or_else(|_| panic!("Failed to load sound {} from asset API", i + 1))
|
.unwrap_or_else(|_| panic!("Failed to load sound {} from asset API", i + 1))
|
||||||
@@ -61,11 +60,7 @@ impl Audio {
|
|||||||
if let Some(chunk) = self.sounds.get(self.next_sound_index) {
|
if let Some(chunk) = self.sounds.get(self.next_sound_index) {
|
||||||
match mixer::Channel(0).play(chunk, 0) {
|
match mixer::Channel(0).play(chunk, 0) {
|
||||||
Ok(channel) => {
|
Ok(channel) => {
|
||||||
tracing::info!(
|
tracing::info!("Playing sound #{} on channel {:?}", self.next_sound_index + 1, channel);
|
||||||
"Playing sound #{} on channel {:?}",
|
|
||||||
self.next_sound_index + 1,
|
|
||||||
channel
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::warn!("Could not play sound #{}: {}", self.next_sound_index + 1, e);
|
tracing::warn!("Could not play sound #{}: {}", self.next_sound_index + 1, e);
|
||||||
|
|||||||
@@ -64,18 +64,10 @@ pub fn reconstruct_edibles<'a>(
|
|||||||
let cell = (x, y);
|
let cell = (x, y);
|
||||||
match tile {
|
match tile {
|
||||||
Some(MapTile::Pellet) => {
|
Some(MapTile::Pellet) => {
|
||||||
edibles.push(Edible::new(
|
edibles.push(Edible::new(EdibleKind::Pellet, cell, Rc::clone(&pellet_sprite)));
|
||||||
EdibleKind::Pellet,
|
|
||||||
cell,
|
|
||||||
Rc::clone(&pellet_sprite),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
Some(MapTile::PowerPellet) => {
|
Some(MapTile::PowerPellet) => {
|
||||||
edibles.push(Edible::new(
|
edibles.push(Edible::new(EdibleKind::PowerPellet, cell, Rc::clone(&power_pellet_sprite)));
|
||||||
EdibleKind::PowerPellet,
|
|
||||||
cell,
|
|
||||||
Rc::clone(&power_pellet_sprite),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
// Fruits can be added here if you have fruit positions
|
// Fruits can be added here if you have fruit positions
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@@ -108,10 +108,7 @@ impl Moving for MovableEntity {
|
|||||||
}
|
}
|
||||||
fn next_cell(&self, direction: Option<Direction>) -> (i32, i32) {
|
fn next_cell(&self, direction: Option<Direction>) -> (i32, i32) {
|
||||||
let (x, y) = direction.unwrap_or(self.direction).offset();
|
let (x, y) = direction.unwrap_or(self.direction).offset();
|
||||||
(
|
(self.base.cell_position.0 as i32 + x, self.base.cell_position.1 as i32 + y)
|
||||||
self.base.cell_position.0 as i32 + x,
|
|
||||||
self.base.cell_position.1 as i32 + y,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
fn is_wall_ahead(&self, direction: Option<Direction>) -> bool {
|
fn is_wall_ahead(&self, direction: Option<Direction>) -> bool {
|
||||||
let next_cell = self.next_cell(direction);
|
let next_cell = self.next_cell(direction);
|
||||||
@@ -119,10 +116,10 @@ impl Moving for MovableEntity {
|
|||||||
}
|
}
|
||||||
fn handle_tunnel(&mut self) -> bool {
|
fn handle_tunnel(&mut self) -> bool {
|
||||||
if !self.in_tunnel {
|
if !self.in_tunnel {
|
||||||
let current_tile = self.map.borrow().get_tile((
|
let current_tile = self
|
||||||
self.base.cell_position.0 as i32,
|
.map
|
||||||
self.base.cell_position.1 as i32,
|
.borrow()
|
||||||
));
|
.get_tile((self.base.cell_position.0 as i32, self.base.cell_position.1 as i32));
|
||||||
if matches!(current_tile, Some(MapTile::Tunnel)) {
|
if matches!(current_tile, Some(MapTile::Tunnel)) {
|
||||||
self.in_tunnel = true;
|
self.in_tunnel = true;
|
||||||
}
|
}
|
||||||
@@ -130,14 +127,12 @@ impl Moving for MovableEntity {
|
|||||||
if self.in_tunnel {
|
if self.in_tunnel {
|
||||||
if self.base.cell_position.0 == 0 {
|
if self.base.cell_position.0 == 0 {
|
||||||
self.base.cell_position.0 = BOARD_WIDTH - 2;
|
self.base.cell_position.0 = BOARD_WIDTH - 2;
|
||||||
self.base.pixel_position =
|
self.base.pixel_position = Map::cell_to_pixel((self.base.cell_position.0, self.base.cell_position.1));
|
||||||
Map::cell_to_pixel((self.base.cell_position.0, self.base.cell_position.1));
|
|
||||||
self.in_tunnel = false;
|
self.in_tunnel = false;
|
||||||
true
|
true
|
||||||
} else if self.base.cell_position.0 == BOARD_WIDTH - 1 {
|
} else if self.base.cell_position.0 == BOARD_WIDTH - 1 {
|
||||||
self.base.cell_position.0 = 1;
|
self.base.cell_position.0 = 1;
|
||||||
self.base.pixel_position =
|
self.base.pixel_position = Map::cell_to_pixel((self.base.cell_position.0, self.base.cell_position.1));
|
||||||
Map::cell_to_pixel((self.base.cell_position.0, self.base.cell_position.1));
|
|
||||||
self.in_tunnel = false;
|
self.in_tunnel = false;
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
34
src/game.rs
34
src/game.rs
@@ -64,11 +64,7 @@ impl<'a> Game<'a> {
|
|||||||
let pacman_atlas = texture_creator
|
let pacman_atlas = texture_creator
|
||||||
.load_texture_bytes(&pacman_bytes)
|
.load_texture_bytes(&pacman_bytes)
|
||||||
.expect("Could not load pacman texture from asset API");
|
.expect("Could not load pacman texture from asset API");
|
||||||
let pacman = Rc::new(RefCell::new(Pacman::new(
|
let pacman = Rc::new(RefCell::new(Pacman::new((1, 1), pacman_atlas, Rc::clone(&map))));
|
||||||
(1, 1),
|
|
||||||
pacman_atlas,
|
|
||||||
Rc::clone(&map),
|
|
||||||
)));
|
|
||||||
|
|
||||||
// Load ghost textures
|
// Load ghost textures
|
||||||
let ghost_body_bytes = get_asset_bytes(Asset::GhostBody).expect("Failed to load asset");
|
let ghost_body_bytes = get_asset_bytes(Asset::GhostBody).expect("Failed to load asset");
|
||||||
@@ -113,12 +109,9 @@ impl<'a> Game<'a> {
|
|||||||
|
|
||||||
// Load font from asset API
|
// Load font from asset API
|
||||||
let font = {
|
let font = {
|
||||||
let font_bytes = get_asset_bytes(Asset::FontKonami)
|
let font_bytes = get_asset_bytes(Asset::FontKonami).expect("Failed to load asset").into_owned();
|
||||||
.expect("Failed to load asset")
|
|
||||||
.into_owned();
|
|
||||||
let font_bytes_static: &'static [u8] = Box::leak(font_bytes.into_boxed_slice());
|
let font_bytes_static: &'static [u8] = Box::leak(font_bytes.into_boxed_slice());
|
||||||
let font_rwops =
|
let font_rwops = RWops::from_bytes(font_bytes_static).expect("Failed to create RWops for font");
|
||||||
RWops::from_bytes(font_bytes_static).expect("Failed to create RWops for font");
|
|
||||||
ttf_context
|
ttf_context
|
||||||
.load_font_from_rwops(font_rwops, 24)
|
.load_font_from_rwops(font_rwops, 24)
|
||||||
.expect("Could not load font from asset API")
|
.expect("Could not load font from asset API")
|
||||||
@@ -306,18 +299,9 @@ impl<'a> Game<'a> {
|
|||||||
// Draw the debug grid
|
// Draw the debug grid
|
||||||
match self.debug_mode {
|
match self.debug_mode {
|
||||||
DebugMode::Grid => {
|
DebugMode::Grid => {
|
||||||
DebugRenderer::draw_debug_grid(
|
DebugRenderer::draw_debug_grid(self.canvas, &self.map.borrow(), self.pacman.borrow().base.base.cell_position);
|
||||||
self.canvas,
|
let next_cell = <Pacman as crate::entity::Moving>::next_cell(&*self.pacman.borrow(), None);
|
||||||
&self.map.borrow(),
|
DebugRenderer::draw_next_cell(self.canvas, &self.map.borrow(), (next_cell.0 as u32, next_cell.1 as u32));
|
||||||
self.pacman.borrow().base.base.cell_position,
|
|
||||||
);
|
|
||||||
let next_cell =
|
|
||||||
<Pacman as crate::entity::Moving>::next_cell(&*self.pacman.borrow(), None);
|
|
||||||
DebugRenderer::draw_next_cell(
|
|
||||||
self.canvas,
|
|
||||||
&self.map.borrow(),
|
|
||||||
(next_cell.0 as u32, next_cell.1 as u32),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
DebugMode::ValidPositions => {
|
DebugMode::ValidPositions => {
|
||||||
DebugRenderer::draw_valid_positions(self.canvas, &mut self.map.borrow_mut());
|
DebugRenderer::draw_valid_positions(self.canvas, &mut self.map.borrow_mut());
|
||||||
@@ -358,11 +342,7 @@ impl<'a> Game<'a> {
|
|||||||
|
|
||||||
/// Renders text to the screen at the given position.
|
/// Renders text to the screen at the given position.
|
||||||
fn render_text(&mut self, text: &str, position: (i32, i32), color: Color) {
|
fn render_text(&mut self, text: &str, position: (i32, i32), color: Color) {
|
||||||
let surface = self
|
let surface = self.font.render(text).blended(color).expect("Could not render text surface");
|
||||||
.font
|
|
||||||
.render(text)
|
|
||||||
.blended(color)
|
|
||||||
.expect("Could not render text surface");
|
|
||||||
|
|
||||||
let texture_creator = self.canvas.texture_creator();
|
let texture_creator = self.canvas.texture_creator();
|
||||||
let texture = texture_creator
|
let texture = texture_creator
|
||||||
|
|||||||
34
src/ghost.rs
34
src/ghost.rs
@@ -121,22 +121,14 @@ impl Ghost<'_> {
|
|||||||
let mut possible_moves = Vec::new();
|
let mut possible_moves = Vec::new();
|
||||||
|
|
||||||
// Check all four directions
|
// Check all four directions
|
||||||
for dir in &[
|
for dir in &[Direction::Up, Direction::Down, Direction::Left, Direction::Right] {
|
||||||
Direction::Up,
|
|
||||||
Direction::Down,
|
|
||||||
Direction::Left,
|
|
||||||
Direction::Right,
|
|
||||||
] {
|
|
||||||
// Don't allow reversing direction
|
// Don't allow reversing direction
|
||||||
if *dir == self.base.direction.opposite() {
|
if *dir == self.base.direction.opposite() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_cell = self.base.next_cell(Some(*dir));
|
let next_cell = self.base.next_cell(Some(*dir));
|
||||||
if !matches!(
|
if !matches!(self.base.map.borrow().get_tile(next_cell), Some(MapTile::Wall)) {
|
||||||
self.base.map.borrow().get_tile(next_cell),
|
|
||||||
Some(MapTile::Wall)
|
|
||||||
) {
|
|
||||||
possible_moves.push(next_cell);
|
possible_moves.push(next_cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,12 +177,7 @@ impl Ghost<'_> {
|
|||||||
successors.push(((1, p.1), 1));
|
successors.push(((1, p.1), 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for dir in &[
|
for dir in &[Direction::Up, Direction::Down, Direction::Left, Direction::Right] {
|
||||||
Direction::Up,
|
|
||||||
Direction::Down,
|
|
||||||
Direction::Left,
|
|
||||||
Direction::Right,
|
|
||||||
] {
|
|
||||||
let (dx, dy) = dir.offset();
|
let (dx, dy) = dir.offset();
|
||||||
let next_p = (p.0 as i32 + dx, p.1 as i32 + dy);
|
let next_p = (p.0 as i32 + dx, p.1 as i32 + dy);
|
||||||
if let Some(tile) = map.get_tile(next_p) {
|
if let Some(tile) = map.get_tile(next_p) {
|
||||||
@@ -209,9 +196,8 @@ impl Ghost<'_> {
|
|||||||
/// Changes the ghost's mode and handles direction reversal
|
/// Changes the ghost's mode and handles direction reversal
|
||||||
pub fn set_mode(&mut self, new_mode: GhostMode) {
|
pub fn set_mode(&mut self, new_mode: GhostMode) {
|
||||||
// Don't reverse if going to/from frightened or if in house
|
// Don't reverse if going to/from frightened or if in house
|
||||||
let should_reverse = self.mode != GhostMode::House
|
let should_reverse =
|
||||||
&& new_mode != GhostMode::Frightened
|
self.mode != GhostMode::House && new_mode != GhostMode::Frightened && self.mode != GhostMode::Frightened;
|
||||||
&& self.mode != GhostMode::Frightened;
|
|
||||||
|
|
||||||
self.mode = new_mode;
|
self.mode = new_mode;
|
||||||
|
|
||||||
@@ -224,8 +210,7 @@ impl Ghost<'_> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if should_reverse {
|
if should_reverse {
|
||||||
self.base
|
self.base.set_direction_if_valid(self.base.direction.opposite());
|
||||||
.set_direction_if_valid(self.base.direction.opposite());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,9 +226,7 @@ impl Ghost<'_> {
|
|||||||
if !self.base.handle_tunnel() {
|
if !self.base.handle_tunnel() {
|
||||||
// Pathfinding logic (only if not in tunnel)
|
// Pathfinding logic (only if not in tunnel)
|
||||||
let target_tile = self.get_target_tile();
|
let target_tile = self.get_target_tile();
|
||||||
if let Some((path, _)) =
|
if let Some((path, _)) = self.get_path_to_target((target_tile.0 as u32, target_tile.1 as u32)) {
|
||||||
self.get_path_to_target((target_tile.0 as u32, target_tile.1 as u32))
|
|
||||||
{
|
|
||||||
if path.len() > 1 {
|
if path.len() > 1 {
|
||||||
let next_move = path[1];
|
let next_move = path[1];
|
||||||
let (x, y) = self.base.base.cell_position;
|
let (x, y) = self.base.base.cell_position;
|
||||||
@@ -318,7 +301,6 @@ impl<'a> Renderable for Ghost<'a> {
|
|||||||
Direction::Down => 3,
|
Direction::Down => 3,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.eyes_sprite
|
self.eyes_sprite.render(canvas, pos, Direction::Right, Some(eye_frame));
|
||||||
.render(canvas, pos, Direction::Right, Some(eye_frame));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,14 +23,7 @@ impl<'a> Blinky<'a> {
|
|||||||
pacman: Rc<RefCell<Pacman<'a>>>,
|
pacman: Rc<RefCell<Pacman<'a>>>,
|
||||||
) -> Blinky<'a> {
|
) -> Blinky<'a> {
|
||||||
Blinky {
|
Blinky {
|
||||||
ghost: Ghost::new(
|
ghost: Ghost::new(GhostType::Blinky, starting_position, body_texture, eyes_texture, map, pacman),
|
||||||
GhostType::Blinky,
|
|
||||||
starting_position,
|
|
||||||
body_texture,
|
|
||||||
eyes_texture,
|
|
||||||
map,
|
|
||||||
pacman,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,14 +94,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_commutative_property() {
|
fn test_commutative_property() {
|
||||||
// The function should work the same regardless of parameter order
|
// The function should work the same regardless of parameter order
|
||||||
assert_eq!(
|
assert_eq!(is_adjacent((1, 2), (2, 2), false), is_adjacent((2, 2), (1, 2), false));
|
||||||
is_adjacent((1, 2), (2, 2), false),
|
|
||||||
is_adjacent((2, 2), (1, 2), false)
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(is_adjacent((1, 2), (2, 3), true), is_adjacent((2, 3), (1, 2), true));
|
||||||
is_adjacent((1, 2), (2, 3), true),
|
|
||||||
is_adjacent((2, 3), (1, 2), true)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/main.rs
24
src/main.rs
@@ -53,6 +53,7 @@ unsafe fn attach_console() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod animation;
|
mod animation;
|
||||||
|
mod asset;
|
||||||
mod audio;
|
mod audio;
|
||||||
mod constants;
|
mod constants;
|
||||||
mod debug;
|
mod debug;
|
||||||
@@ -66,7 +67,6 @@ mod helper;
|
|||||||
mod map;
|
mod map;
|
||||||
mod modulation;
|
mod modulation;
|
||||||
mod pacman;
|
mod pacman;
|
||||||
mod asset;
|
|
||||||
|
|
||||||
/// The main entry point of the application.
|
/// The main entry point of the application.
|
||||||
///
|
///
|
||||||
@@ -99,26 +99,16 @@ pub fn main() {
|
|||||||
.build()
|
.build()
|
||||||
.expect("Could not initialize window");
|
.expect("Could not initialize window");
|
||||||
|
|
||||||
let mut canvas = window
|
let mut canvas = window.into_canvas().build().expect("Could not build canvas");
|
||||||
.into_canvas()
|
|
||||||
.build()
|
|
||||||
.expect("Could not build canvas");
|
|
||||||
|
|
||||||
canvas
|
canvas
|
||||||
.set_logical_size(WINDOW_WIDTH, WINDOW_HEIGHT)
|
.set_logical_size(WINDOW_WIDTH, WINDOW_HEIGHT)
|
||||||
.expect("Could not set logical size");
|
.expect("Could not set logical size");
|
||||||
|
|
||||||
let texture_creator = canvas.texture_creator();
|
let texture_creator = canvas.texture_creator();
|
||||||
let mut game = Game::new(
|
let mut game = Game::new(&mut canvas, &texture_creator, &ttf_context, &audio_subsystem);
|
||||||
&mut canvas,
|
|
||||||
&texture_creator,
|
|
||||||
&ttf_context,
|
|
||||||
&audio_subsystem,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut event_pump = sdl_context
|
let mut event_pump = sdl_context.event_pump().expect("Could not get SDL EventPump");
|
||||||
.event_pump()
|
|
||||||
.expect("Could not get SDL EventPump");
|
|
||||||
|
|
||||||
// Initial draw and tick
|
// Initial draw and tick
|
||||||
game.draw();
|
game.draw();
|
||||||
@@ -169,11 +159,7 @@ pub fn main() {
|
|||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
paused = !paused;
|
paused = !paused;
|
||||||
event!(
|
event!(tracing::Level::INFO, "{}", if paused { "Paused" } else { "Unpaused" });
|
||||||
tracing::Level::INFO,
|
|
||||||
"{}",
|
|
||||||
if paused { "Paused" } else { "Unpaused" }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Event::KeyDown { keycode, .. } => {
|
Event::KeyDown { keycode, .. } => {
|
||||||
game.keyboard_event(keycode.unwrap());
|
game.keyboard_event(keycode.unwrap());
|
||||||
|
|||||||
19
src/map.rs
19
src/map.rs
@@ -75,9 +75,7 @@ impl Map {
|
|||||||
'o' => MapTile::PowerPellet,
|
'o' => MapTile::PowerPellet,
|
||||||
' ' => MapTile::Empty,
|
' ' => MapTile::Empty,
|
||||||
'T' => MapTile::Tunnel,
|
'T' => MapTile::Tunnel,
|
||||||
c @ '0' | c @ '1' | c @ '2' | c @ '3' | c @ '4' => {
|
c @ '0' | c @ '1' | c @ '2' | c @ '3' | c @ '4' => MapTile::StartingPosition(c.to_digit(10).unwrap() as u8),
|
||||||
MapTile::StartingPosition(c.to_digit(10).unwrap() as u8)
|
|
||||||
}
|
|
||||||
'=' => MapTile::Empty,
|
'=' => MapTile::Empty,
|
||||||
_ => panic!("Unknown character in board: {character}"),
|
_ => panic!("Unknown character in board: {character}"),
|
||||||
};
|
};
|
||||||
@@ -94,12 +92,7 @@ impl Map {
|
|||||||
/// Resets the map to its original state.
|
/// Resets the map to its original state.
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
// Restore the map to its original state
|
// Restore the map to its original state
|
||||||
for (x, col) in self
|
for (x, col) in self.current.iter_mut().enumerate().take(BOARD_WIDTH as usize) {
|
||||||
.current
|
|
||||||
.iter_mut()
|
|
||||||
.enumerate()
|
|
||||||
.take(BOARD_WIDTH as usize)
|
|
||||||
{
|
|
||||||
for (y, cell) in col.iter_mut().enumerate().take(BOARD_HEIGHT as usize) {
|
for (y, cell) in col.iter_mut().enumerate().take(BOARD_HEIGHT as usize) {
|
||||||
*cell = self.default[x][y];
|
*cell = self.default[x][y];
|
||||||
}
|
}
|
||||||
@@ -146,10 +139,7 @@ impl Map {
|
|||||||
///
|
///
|
||||||
/// * `cell` - The cell coordinates, in grid coordinates.
|
/// * `cell` - The cell coordinates, in grid coordinates.
|
||||||
pub fn cell_to_pixel(cell: (u32, u32)) -> (i32, i32) {
|
pub fn cell_to_pixel(cell: (u32, u32)) -> (i32, i32) {
|
||||||
(
|
((cell.0 * CELL_SIZE) as i32, ((cell.1 + BOARD_OFFSET.1) * CELL_SIZE) as i32)
|
||||||
(cell.0 * CELL_SIZE) as i32,
|
|
||||||
((cell.1 + BOARD_OFFSET.1) * CELL_SIZE) as i32,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to a cached vector of all valid playable positions in the maze.
|
/// Returns a reference to a cached vector of all valid playable positions in the maze.
|
||||||
@@ -198,8 +188,7 @@ impl Map {
|
|||||||
] {
|
] {
|
||||||
let neighbor = pos + offset;
|
let neighbor = pos + offset;
|
||||||
if neighbor.x < BOARD_WIDTH && neighbor.y < BOARD_HEIGHT {
|
if neighbor.x < BOARD_WIDTH && neighbor.y < BOARD_HEIGHT {
|
||||||
let neighbor_tile =
|
let neighbor_tile = self.current[neighbor.x as usize][neighbor.y as usize];
|
||||||
self.current[neighbor.x as usize][neighbor.y as usize];
|
|
||||||
if matches!(neighbor_tile, Empty | Pellet | PowerPellet) {
|
if matches!(neighbor_tile, Empty | Pellet | PowerPellet) {
|
||||||
queue.push_back(neighbor);
|
queue.push_back(neighbor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,11 +58,7 @@ impl<'a> Moving for Pacman<'a> {
|
|||||||
|
|
||||||
impl Pacman<'_> {
|
impl Pacman<'_> {
|
||||||
/// Creates a new `Pacman` instance.
|
/// Creates a new `Pacman` instance.
|
||||||
pub fn new<'a>(
|
pub fn new<'a>(starting_position: (u32, u32), atlas: Texture<'a>, map: Rc<RefCell<Map>>) -> Pacman<'a> {
|
||||||
starting_position: (u32, u32),
|
|
||||||
atlas: Texture<'a>,
|
|
||||||
map: Rc<RefCell<Map>>,
|
|
||||||
) -> Pacman<'a> {
|
|
||||||
let pixel_position = Map::cell_to_pixel(starting_position);
|
let pixel_position = Map::cell_to_pixel(starting_position);
|
||||||
Pacman {
|
Pacman {
|
||||||
base: MovableEntity::new(
|
base: MovableEntity::new(
|
||||||
|
|||||||
Reference in New Issue
Block a user