diff --git a/src/game.rs b/src/game.rs index 483b798..37e9847 100644 --- a/src/game.rs +++ b/src/game.rs @@ -6,6 +6,7 @@ use sdl2::render::{Texture, TextureCreator}; use sdl2::ttf::{Font, FontStyle}; use sdl2::video::WindowContext; use sdl2::{pixels::Color, render::Canvas, video::Window}; +use tracing::event; use crate::constants::{MapTile, BOARD_HEIGHT, BOARD_WIDTH, RAW_BOARD}; use crate::direction::Direction; @@ -20,7 +21,7 @@ pub struct Game<'a> { power_pellet_texture: Texture<'a>, font: Font<'a, 'static>, pacman: Pacman<'a>, - map: Rc, + map: Rc>, debug: bool, score: u32, } @@ -31,7 +32,7 @@ impl Game<'_> { texture_creator: &'a TextureCreator, ttf_context: &'a sdl2::ttf::Sdl2TtfContext, ) -> Game<'a> { - let map = Rc::new(Map::new(RAW_BOARD)); + let map = Rc::new(std::cell::RefCell::new(Map::new(RAW_BOARD))); let pacman_atlas = texture_creator .load_texture("assets/32/pacman.png") .expect("Could not load pacman texture"); @@ -72,11 +73,6 @@ impl Game<'_> { if keycode == Keycode::Space { self.debug = !self.debug; } - - // Test score increase - if keycode == Keycode::S { - self.add_score(10); - } } pub fn add_score(&mut self, points: u32) { @@ -85,6 +81,51 @@ impl Game<'_> { pub fn tick(&mut self) { self.pacman.tick(); + self.check_pellet_eating(); + } + + fn check_pellet_eating(&mut self) { + let cell_pos = self.pacman.cell_position(); + + // Check if there's a pellet at the current position + let tile = { + let map = self.map.borrow(); + map.get_tile((cell_pos.0 as i32, cell_pos.1 as i32)) + }; + + if let Some(tile) = tile { + match tile { + MapTile::Pellet => { + // Eat the pellet and add score + { + let mut map = self.map.borrow_mut(); + map.set_tile((cell_pos.0 as i32, cell_pos.1 as i32), MapTile::Empty); + } + self.add_score(10); + event!( + tracing::Level::DEBUG, + "Pellet eaten at ({}, {})", + cell_pos.0, + cell_pos.1 + ); + } + MapTile::PowerPellet => { + // Eat the power pellet and add score + { + let mut map = self.map.borrow_mut(); + map.set_tile((cell_pos.0 as i32, cell_pos.1 as i32), MapTile::Empty); + } + self.add_score(50); + event!( + tracing::Level::DEBUG, + "Power pellet eaten at ({}, {})", + cell_pos.0, + cell_pos.1 + ); + } + _ => {} + } + } } pub fn draw(&mut self) { @@ -112,6 +153,7 @@ impl Game<'_> { for y in 0..BOARD_HEIGHT { let tile = self .map + .borrow() .get_tile((x as i32, y as i32)) .unwrap_or(MapTile::Empty); let mut color = None; @@ -162,6 +204,7 @@ impl Game<'_> { for y in 0..BOARD_HEIGHT { let tile = self .map + .borrow() .get_tile((x as i32, y as i32)) .unwrap_or(MapTile::Empty); @@ -187,9 +230,8 @@ impl Game<'_> { } fn render_score(&mut self) { - let score = 0; let lives = 3; - let score_text = format!("{:02}", score); + let score_text = format!("{:02}", self.score); let x_offset = 12; let y_offset = 2; diff --git a/src/map.rs b/src/map.rs index 18609f5..35c126f 100644 --- a/src/map.rs +++ b/src/map.rs @@ -53,6 +53,18 @@ impl Map { Some(self.inner[x][y]) } + pub fn set_tile(&mut self, cell: (i32, i32), tile: MapTile) -> bool { + let x = cell.0 as usize; + let y = cell.1 as usize; + + if x >= BOARD_WIDTH as usize || y >= BOARD_HEIGHT as usize { + return false; + } + + self.inner[x][y] = tile; + true + } + pub fn cell_to_pixel(cell: (u32, u32)) -> (i32, i32) { ((cell.0 as i32) * 24, ((cell.1 + 3) as i32) * 24) } diff --git a/src/pacman.rs b/src/pacman.rs index 003505e..a48d4c7 100644 --- a/src/pacman.rs +++ b/src/pacman.rs @@ -1,3 +1,4 @@ +use std::cell::RefCell; use std::rc::Rc; use sdl2::{ @@ -22,14 +23,18 @@ pub struct Pacman<'a> { pub direction: Direction, pub next_direction: Option, pub stopped: bool, - map: Rc, + map: Rc>, speed: u32, modulation: SimpleTickModulator, sprite: AnimatedTexture<'a>, } impl Pacman<'_> { - pub fn new<'a>(starting_position: (u32, u32), atlas: Texture<'a>, map: Rc) -> Pacman<'a> { + pub fn new<'a>( + starting_position: (u32, u32), + atlas: Texture<'a>, + map: Rc>, + ) -> Pacman<'a> { Pacman { position: Map::cell_to_pixel(starting_position), direction: Direction::Right, @@ -70,6 +75,7 @@ impl Pacman<'_> { let proposed_next_cell = self.next_cell(self.next_direction); let proposed_next_tile = self .map + .borrow() .get_tile(proposed_next_cell) .unwrap_or(MapTile::Empty); if proposed_next_tile != MapTile::Wall { @@ -79,7 +85,7 @@ impl Pacman<'_> { } fn internal_position_even(&self) -> (u32, u32) { - let (x, y ) = self.internal_position(); + let (x, y) = self.internal_position(); ((x / 2u32) * 2u32, (y / 2u32) * 2u32) } } @@ -115,7 +121,7 @@ impl Entity for Pacman<'_> { self.handle_requested_direction(); let next = self.next_cell(None); - let next_tile = self.map.get_tile(next).unwrap_or(MapTile::Empty); + let next_tile = self.map.borrow().get_tile(next).unwrap_or(MapTile::Empty); if !self.stopped && next_tile == MapTile::Wall { event!(tracing::Level::DEBUG, "Wall collision. Stopping."); @@ -125,7 +131,7 @@ impl Entity for Pacman<'_> { self.stopped = false; } } - + if !self.stopped && self.modulation.next() { let speed = self.speed as i32; match self.direction {