mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-09 14:07:57 -06:00
Compare commits
1 Commits
ced4e87d41
...
v0.37.0
| Author | SHA1 | Date | |
|---|---|---|---|
| db8cd6220a |
@@ -9,15 +9,18 @@ use sdl2::{
|
|||||||
video::WindowContext,
|
video::WindowContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::entity::r#trait::Entity;
|
||||||
use crate::error::{EntityError, GameError, GameResult};
|
use crate::error::{EntityError, GameError, GameResult};
|
||||||
|
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
collision::{Collidable, CollisionSystem, EntityId},
|
collision::{Collidable, CollisionSystem, EntityId},
|
||||||
ghost::{Ghost, GhostType},
|
ghost::{Ghost, GhostType},
|
||||||
pacman::Pacman,
|
pacman::Pacman,
|
||||||
r#trait::Entity,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::map::render::MapRenderer;
|
||||||
|
use crate::{constants, texture::sprite::SpriteAtlas};
|
||||||
|
|
||||||
pub mod state;
|
pub mod state;
|
||||||
use state::GameState;
|
use state::GameState;
|
||||||
|
|
||||||
@@ -168,13 +171,36 @@ impl Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw<T: RenderTarget>(&mut self, canvas: &mut Canvas<T>, backbuffer: &mut Texture) -> GameResult<()> {
|
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
|
canvas
|
||||||
.with_texture_canvas(backbuffer, |canvas| {
|
.with_texture_canvas(backbuffer, |canvas| {
|
||||||
canvas.set_draw_color(Color::BLACK);
|
canvas.set_draw_color(Color::BLACK);
|
||||||
canvas.clear();
|
canvas.clear();
|
||||||
self.state
|
if let Some(ref map_texture) = self.state.map_texture {
|
||||||
.map
|
canvas.copy(map_texture, None, None).unwrap();
|
||||||
.render(canvas, &mut self.state.atlas, &mut self.state.map_tiles);
|
}
|
||||||
|
|
||||||
// Render all items
|
// Render all items
|
||||||
for item in &self.state.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 smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -15,7 +19,7 @@ use crate::{
|
|||||||
game::EntityId,
|
game::EntityId,
|
||||||
map::Map,
|
map::Map,
|
||||||
texture::{
|
texture::{
|
||||||
sprite::{AtlasMapper, AtlasTile, SpriteAtlas},
|
sprite::{AtlasMapper, SpriteAtlas},
|
||||||
text::TextTexture,
|
text::TextTexture,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -31,7 +35,6 @@ include!(concat!(env!("OUT_DIR"), "/atlas_data.rs"));
|
|||||||
pub struct GameState {
|
pub struct GameState {
|
||||||
pub score: u32,
|
pub score: u32,
|
||||||
pub map: Map,
|
pub map: Map,
|
||||||
pub map_tiles: Vec<AtlasTile>,
|
|
||||||
pub pacman: Pacman,
|
pub pacman: Pacman,
|
||||||
pub pacman_id: EntityId,
|
pub pacman_id: EntityId,
|
||||||
pub ghosts: SmallVec<[Ghost; 4]>,
|
pub ghosts: SmallVec<[Ghost; 4]>,
|
||||||
@@ -49,6 +52,11 @@ pub struct GameState {
|
|||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
pub audio: 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 {
|
impl GameState {
|
||||||
@@ -60,7 +68,7 @@ impl GameState {
|
|||||||
pub fn new(texture_creator: &'static TextureCreator<WindowContext>) -> GameResult<Self> {
|
pub fn new(texture_creator: &'static TextureCreator<WindowContext>) -> GameResult<Self> {
|
||||||
let map = Map::new(RAW_BOARD)?;
|
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_bytes = get_asset_bytes(Asset::Atlas)?;
|
||||||
let atlas_texture = texture_creator.load_texture_bytes(&atlas_bytes).map_err(|e| {
|
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 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 text_texture = TextTexture::new(1.0);
|
||||||
let audio = Audio::new();
|
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)
|
// Generate items (pellets and energizers)
|
||||||
let items = map.generate_items(&atlas)?;
|
let items = map.generate_items(&atlas)?;
|
||||||
@@ -127,7 +127,6 @@ impl GameState {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
map,
|
map,
|
||||||
atlas,
|
atlas,
|
||||||
map_tiles,
|
|
||||||
pacman,
|
pacman,
|
||||||
pacman_id,
|
pacman_id,
|
||||||
ghosts,
|
ghosts,
|
||||||
@@ -139,6 +138,9 @@ impl GameState {
|
|||||||
score: 0,
|
score: 0,
|
||||||
debug_mode: false,
|
debug_mode: false,
|
||||||
collision_system,
|
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::entity::item::{Item, ItemType};
|
||||||
use crate::map::parser::MapTileParser;
|
use crate::map::parser::MapTileParser;
|
||||||
use crate::map::render::MapRenderer;
|
use crate::map::render::MapRenderer;
|
||||||
use crate::texture::sprite::{AtlasTile, Sprite, SpriteAtlas};
|
use crate::texture::sprite::{Sprite, SpriteAtlas};
|
||||||
use glam::{IVec2, Vec2};
|
use glam::{IVec2, Vec2};
|
||||||
use sdl2::render::{Canvas, RenderTarget};
|
use sdl2::render::{Canvas, RenderTarget};
|
||||||
use std::collections::{HashMap, VecDeque};
|
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.
|
/// Generates Item entities for pellets and energizers from the parsed map.
|
||||||
pub fn generate_items(&self, atlas: &SpriteAtlas) -> GameResult<Vec<Item>> {
|
pub fn generate_items(&self, atlas: &SpriteAtlas) -> GameResult<Vec<Item>> {
|
||||||
// Pre-load sprites to avoid repeated texture lookups
|
// Pre-load sprites to avoid repeated texture lookups
|
||||||
|
|||||||
Reference in New Issue
Block a user