mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-06 09:15:46 -06:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| db8cd6220a |
@@ -9,15 +9,18 @@ use sdl2::{
|
||||
video::WindowContext,
|
||||
};
|
||||
|
||||
use crate::entity::r#trait::Entity;
|
||||
use crate::error::{EntityError, GameError, GameResult};
|
||||
|
||||
use crate::entity::{
|
||||
collision::{Collidable, CollisionSystem, EntityId},
|
||||
ghost::{Ghost, GhostType},
|
||||
pacman::Pacman,
|
||||
r#trait::Entity,
|
||||
};
|
||||
|
||||
use crate::map::render::MapRenderer;
|
||||
use crate::{constants, texture::sprite::SpriteAtlas};
|
||||
|
||||
pub mod state;
|
||||
use state::GameState;
|
||||
|
||||
@@ -168,13 +171,36 @@ impl Game {
|
||||
}
|
||||
|
||||
pub fn draw<T: RenderTarget>(&mut self, canvas: &mut Canvas<T>, backbuffer: &mut Texture) -> GameResult<()> {
|
||||
// Only render the map texture once and cache it
|
||||
if !self.state.map_rendered {
|
||||
let mut map_texture = self
|
||||
.state
|
||||
.texture_creator
|
||||
.create_texture_target(None, constants::CANVAS_SIZE.x, constants::CANVAS_SIZE.y)
|
||||
.map_err(|e| GameError::Sdl(e.to_string()))?;
|
||||
|
||||
canvas
|
||||
.with_texture_canvas(&mut map_texture, |map_canvas| {
|
||||
let mut map_tiles = Vec::with_capacity(35);
|
||||
for i in 0..35 {
|
||||
let tile_name = format!("maze/tiles/{}.png", i);
|
||||
let tile = SpriteAtlas::get_tile(&self.state.atlas, &tile_name).unwrap();
|
||||
map_tiles.push(tile);
|
||||
}
|
||||
MapRenderer::render_map(map_canvas, &mut self.state.atlas, &mut map_tiles);
|
||||
})
|
||||
.map_err(|e| GameError::Sdl(e.to_string()))?;
|
||||
self.state.map_texture = Some(map_texture);
|
||||
self.state.map_rendered = true;
|
||||
}
|
||||
|
||||
canvas
|
||||
.with_texture_canvas(backbuffer, |canvas| {
|
||||
canvas.set_draw_color(Color::BLACK);
|
||||
canvas.clear();
|
||||
self.state
|
||||
.map
|
||||
.render(canvas, &mut self.state.atlas, &mut self.state.map_tiles);
|
||||
if let Some(ref map_texture) = self.state.map_texture {
|
||||
canvas.copy(map_texture, None, None).unwrap();
|
||||
}
|
||||
|
||||
// Render all items
|
||||
for item in &self.state.items {
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
use sdl2::{image::LoadTexture, render::TextureCreator, video::WindowContext};
|
||||
use sdl2::{
|
||||
image::LoadTexture,
|
||||
render::{Texture, TextureCreator},
|
||||
video::WindowContext,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{
|
||||
@@ -15,7 +19,7 @@ use crate::{
|
||||
game::EntityId,
|
||||
map::Map,
|
||||
texture::{
|
||||
sprite::{AtlasMapper, AtlasTile, SpriteAtlas},
|
||||
sprite::{AtlasMapper, SpriteAtlas},
|
||||
text::TextTexture,
|
||||
},
|
||||
};
|
||||
@@ -31,7 +35,6 @@ include!(concat!(env!("OUT_DIR"), "/atlas_data.rs"));
|
||||
pub struct GameState {
|
||||
pub score: u32,
|
||||
pub map: Map,
|
||||
pub map_tiles: Vec<AtlasTile>,
|
||||
pub pacman: Pacman,
|
||||
pub pacman_id: EntityId,
|
||||
pub ghosts: SmallVec<[Ghost; 4]>,
|
||||
@@ -49,6 +52,11 @@ pub struct GameState {
|
||||
|
||||
// Audio
|
||||
pub audio: Audio,
|
||||
|
||||
// Map texture pre-rendering
|
||||
pub(crate) map_texture: Option<Texture<'static>>,
|
||||
pub(crate) map_rendered: bool,
|
||||
pub(crate) texture_creator: &'static TextureCreator<WindowContext>,
|
||||
}
|
||||
|
||||
impl GameState {
|
||||
@@ -60,7 +68,7 @@ impl GameState {
|
||||
pub fn new(texture_creator: &'static TextureCreator<WindowContext>) -> GameResult<Self> {
|
||||
let map = Map::new(RAW_BOARD)?;
|
||||
|
||||
let pacman_start_node = map.start_positions.pacman;
|
||||
let start_node = map.start_positions.pacman;
|
||||
|
||||
let atlas_bytes = get_asset_bytes(Asset::Atlas)?;
|
||||
let atlas_texture = texture_creator.load_texture_bytes(&atlas_bytes).map_err(|e| {
|
||||
@@ -76,17 +84,9 @@ impl GameState {
|
||||
};
|
||||
let atlas = SpriteAtlas::new(atlas_texture, atlas_mapper);
|
||||
|
||||
let mut map_tiles = Vec::with_capacity(35);
|
||||
for i in 0..35 {
|
||||
let tile_name = format!("maze/tiles/{}.png", i);
|
||||
let tile = SpriteAtlas::get_tile(&atlas, &tile_name)
|
||||
.ok_or(GameError::Texture(TextureError::AtlasTileNotFound(tile_name)))?;
|
||||
map_tiles.push(tile);
|
||||
}
|
||||
|
||||
let text_texture = TextTexture::new(1.0);
|
||||
let audio = Audio::new();
|
||||
let pacman = Pacman::new(&map.graph, pacman_start_node, &atlas)?;
|
||||
let pacman = Pacman::new(&map.graph, start_node, &atlas)?;
|
||||
|
||||
// Generate items (pellets and energizers)
|
||||
let items = map.generate_items(&atlas)?;
|
||||
@@ -127,7 +127,6 @@ impl GameState {
|
||||
Ok(Self {
|
||||
map,
|
||||
atlas,
|
||||
map_tiles,
|
||||
pacman,
|
||||
pacman_id,
|
||||
ghosts,
|
||||
@@ -139,6 +138,9 @@ impl GameState {
|
||||
score: 0,
|
||||
debug_mode: false,
|
||||
collision_system,
|
||||
map_texture: None,
|
||||
map_rendered: false,
|
||||
texture_creator,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::entity::graph::{EdgePermissions, Graph, Node, NodeId};
|
||||
use crate::entity::item::{Item, ItemType};
|
||||
use crate::map::parser::MapTileParser;
|
||||
use crate::map::render::MapRenderer;
|
||||
use crate::texture::sprite::{AtlasTile, Sprite, SpriteAtlas};
|
||||
use crate::texture::sprite::{Sprite, SpriteAtlas};
|
||||
use glam::{IVec2, Vec2};
|
||||
use sdl2::render::{Canvas, RenderTarget};
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
@@ -154,14 +154,6 @@ impl Map {
|
||||
})
|
||||
}
|
||||
|
||||
/// Renders the map to the given canvas.
|
||||
///
|
||||
/// This function draws the static map texture to the screen at the correct
|
||||
/// position and scale.
|
||||
pub fn render<T: RenderTarget>(&self, canvas: &mut Canvas<T>, atlas: &mut SpriteAtlas, map_tiles: &mut [AtlasTile]) {
|
||||
MapRenderer::render_map(canvas, atlas, map_tiles);
|
||||
}
|
||||
|
||||
/// Generates Item entities for pellets and energizers from the parsed map.
|
||||
pub fn generate_items(&self, atlas: &SpriteAtlas) -> GameResult<Vec<Item>> {
|
||||
// Pre-load sprites to avoid repeated texture lookups
|
||||
|
||||
Reference in New Issue
Block a user