Compare commits

...

1 Commits

Author SHA1 Message Date
8808a1aa3b feat: pellet consumption, score & map mutation 2025-07-18 20:15:50 -05:00
3 changed files with 74 additions and 14 deletions

View File

@@ -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>,
map: Rc<std::cell::RefCell<Map>>,
debug: bool,
score: u32,
}
@@ -31,7 +32,7 @@ impl Game<'_> {
texture_creator: &'a TextureCreator<WindowContext>,
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;

View File

@@ -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)
}

View File

@@ -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<Direction>,
pub stopped: bool,
map: Rc<Map>,
map: Rc<RefCell<Map>>,
speed: u32,
modulation: SimpleTickModulator,
sprite: AnimatedTexture<'a>,
}
impl Pacman<'_> {
pub fn new<'a>(starting_position: (u32, u32), atlas: Texture<'a>, map: Rc<Map>) -> Pacman<'a> {
pub fn new<'a>(
starting_position: (u32, u32),
atlas: Texture<'a>,
map: Rc<RefCell<Map>>,
) -> 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 {