mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-07 07:15:45 -06:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b88895e82f | |||
| 2f0c734d13 |
@@ -14,13 +14,13 @@ use crate::systems::{
|
|||||||
collision::collision_system,
|
collision::collision_system,
|
||||||
components::{
|
components::{
|
||||||
Collider, CollisionLayer, DeltaTime, DirectionalAnimated, EntityType, GlobalState, ItemBundle, ItemCollider,
|
Collider, CollisionLayer, DeltaTime, DirectionalAnimated, EntityType, GlobalState, ItemBundle, ItemCollider,
|
||||||
PacmanCollider, PlayerBundle, PlayerControlled, Renderable, Score, ScoreResource,
|
PacmanCollider, PlayerBundle, PlayerControlled, RenderDirty, Renderable, Score, ScoreResource,
|
||||||
},
|
},
|
||||||
control::player_system,
|
control::player_system,
|
||||||
input::input_system,
|
input::input_system,
|
||||||
movement::movement_system,
|
movement::movement_system,
|
||||||
profiling::{profile, SystemTimings},
|
profiling::{profile, SystemTimings},
|
||||||
render::{directional_render_system, render_system, BackbufferResource, MapTextureResource},
|
render::{directional_render_system, dirty_render_system, render_system, BackbufferResource, MapTextureResource},
|
||||||
};
|
};
|
||||||
use crate::texture::animated::AnimatedTexture;
|
use crate::texture::animated::AnimatedTexture;
|
||||||
use bevy_ecs::schedule::IntoScheduleConfigs;
|
use bevy_ecs::schedule::IntoScheduleConfigs;
|
||||||
@@ -100,7 +100,7 @@ impl Game {
|
|||||||
// Render map to texture
|
// Render map to texture
|
||||||
canvas
|
canvas
|
||||||
.with_texture_canvas(&mut map_texture, |map_canvas| {
|
.with_texture_canvas(&mut map_texture, |map_canvas| {
|
||||||
MapRenderer::render_map(map_canvas, &mut atlas, &mut map_tiles);
|
MapRenderer::render_map(map_canvas, &mut atlas, &map_tiles);
|
||||||
})
|
})
|
||||||
.map_err(|e| GameError::Sdl(e.to_string()))?;
|
.map_err(|e| GameError::Sdl(e.to_string()))?;
|
||||||
|
|
||||||
@@ -175,6 +175,7 @@ impl Game {
|
|||||||
world.insert_resource(SystemTimings::default());
|
world.insert_resource(SystemTimings::default());
|
||||||
world.insert_resource(Bindings::default());
|
world.insert_resource(Bindings::default());
|
||||||
world.insert_resource(DeltaTime(0f32));
|
world.insert_resource(DeltaTime(0f32));
|
||||||
|
world.insert_resource(RenderDirty::default());
|
||||||
|
|
||||||
world.add_observer(
|
world.add_observer(
|
||||||
|event: Trigger<GameEvent>, mut state: ResMut<GlobalState>, _score: ResMut<ScoreResource>| match *event {
|
|event: Trigger<GameEvent>, mut state: ResMut<GlobalState>, _score: ResMut<ScoreResource>| match *event {
|
||||||
@@ -196,10 +197,10 @@ impl Game {
|
|||||||
profile("collision", collision_system),
|
profile("collision", collision_system),
|
||||||
profile("blinking", blinking_system),
|
profile("blinking", blinking_system),
|
||||||
profile("directional_render", directional_render_system),
|
profile("directional_render", directional_render_system),
|
||||||
profile("render", render_system),
|
|
||||||
)
|
)
|
||||||
.chain(),
|
.chain(),
|
||||||
);
|
);
|
||||||
|
schedule.add_systems((profile("dirty_render", dirty_render_system), profile("render", render_system)).chain());
|
||||||
|
|
||||||
// Spawn player
|
// Spawn player
|
||||||
world.spawn(player);
|
world.spawn(player);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ impl MapRenderer {
|
|||||||
///
|
///
|
||||||
/// This function draws the static map texture to the screen at the correct
|
/// This function draws the static map texture to the screen at the correct
|
||||||
/// position and scale.
|
/// position and scale.
|
||||||
pub fn render_map<T: RenderTarget>(canvas: &mut Canvas<T>, atlas: &mut SpriteAtlas, map_tiles: &mut [AtlasTile]) {
|
pub fn render_map<T: RenderTarget>(canvas: &mut Canvas<T>, atlas: &mut SpriteAtlas, map_tiles: &[AtlasTile]) {
|
||||||
for (y, row) in TILE_MAP.iter().enumerate() {
|
for (y, row) in TILE_MAP.iter().enumerate() {
|
||||||
for (x, &tile_index) in row.iter().enumerate() {
|
for (x, &tile_index) in row.iter().enumerate() {
|
||||||
let mut tile = map_tiles[tile_index];
|
let mut tile = map_tiles[tile_index];
|
||||||
|
|||||||
@@ -109,3 +109,6 @@ pub struct ScoreResource(pub u32);
|
|||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct DeltaTime(pub f32);
|
pub struct DeltaTime(pub f32);
|
||||||
|
|
||||||
|
#[derive(Resource, Default)]
|
||||||
|
pub struct RenderDirty(pub bool);
|
||||||
|
|||||||
@@ -1,14 +1,25 @@
|
|||||||
use crate::error::{GameError, TextureError};
|
use crate::error::{GameError, TextureError};
|
||||||
use crate::map::builder::Map;
|
use crate::map::builder::Map;
|
||||||
use crate::systems::components::{DeltaTime, DirectionalAnimated, Renderable};
|
use crate::systems::components::{DeltaTime, DirectionalAnimated, RenderDirty, Renderable};
|
||||||
use crate::systems::movement::{Movable, MovementState, Position};
|
use crate::systems::movement::{Movable, MovementState, Position};
|
||||||
use crate::texture::sprite::SpriteAtlas;
|
use crate::texture::sprite::SpriteAtlas;
|
||||||
use bevy_ecs::entity::Entity;
|
use bevy_ecs::entity::Entity;
|
||||||
use bevy_ecs::event::EventWriter;
|
use bevy_ecs::event::EventWriter;
|
||||||
use bevy_ecs::system::{NonSendMut, Query, Res};
|
use bevy_ecs::prelude::{Changed, Or, RemovedComponents};
|
||||||
|
use bevy_ecs::system::{NonSendMut, Query, Res, ResMut};
|
||||||
use sdl2::render::{Canvas, Texture};
|
use sdl2::render::{Canvas, Texture};
|
||||||
use sdl2::video::Window;
|
use sdl2::video::Window;
|
||||||
|
|
||||||
|
pub fn dirty_render_system(
|
||||||
|
mut dirty: ResMut<RenderDirty>,
|
||||||
|
changed_renderables: Query<(), Or<(Changed<Renderable>, Changed<Position>)>>,
|
||||||
|
removed_renderables: RemovedComponents<Renderable>,
|
||||||
|
) {
|
||||||
|
if !changed_renderables.is_empty() || !removed_renderables.is_empty() {
|
||||||
|
dirty.0 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates the directional animated texture of an entity.
|
/// Updates the directional animated texture of an entity.
|
||||||
///
|
///
|
||||||
/// This runs before the render system so it can update the sprite based on the current direction of travel, as well as whether the entity is moving.
|
/// This runs before the render system so it can update the sprite based on the current direction of travel, as well as whether the entity is moving.
|
||||||
@@ -31,7 +42,10 @@ pub fn directional_render_system(
|
|||||||
if !stopped {
|
if !stopped {
|
||||||
texture.tick(dt.0);
|
texture.tick(dt.0);
|
||||||
}
|
}
|
||||||
renderable.sprite = *texture.current_tile();
|
let new_tile = *texture.current_tile();
|
||||||
|
if renderable.sprite != new_tile {
|
||||||
|
renderable.sprite = new_tile;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
errors.write(TextureError::RenderFailed(format!("Entity has no texture")).into());
|
errors.write(TextureError::RenderFailed(format!("Entity has no texture")).into());
|
||||||
continue;
|
continue;
|
||||||
@@ -51,9 +65,13 @@ pub fn render_system(
|
|||||||
mut backbuffer: NonSendMut<BackbufferResource>,
|
mut backbuffer: NonSendMut<BackbufferResource>,
|
||||||
mut atlas: NonSendMut<SpriteAtlas>,
|
mut atlas: NonSendMut<SpriteAtlas>,
|
||||||
map: Res<Map>,
|
map: Res<Map>,
|
||||||
renderables: Query<(Entity, &mut Renderable, &Position)>,
|
mut dirty: ResMut<RenderDirty>,
|
||||||
|
renderables: Query<(Entity, &Renderable, &Position)>,
|
||||||
mut errors: EventWriter<GameError>,
|
mut errors: EventWriter<GameError>,
|
||||||
) {
|
) {
|
||||||
|
if !dirty.0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Clear the main canvas first
|
// Clear the main canvas first
|
||||||
canvas.set_draw_color(sdl2::pixels::Color::BLACK);
|
canvas.set_draw_color(sdl2::pixels::Color::BLACK);
|
||||||
canvas.clear();
|
canvas.clear();
|
||||||
@@ -66,17 +84,12 @@ pub fn render_system(
|
|||||||
backbuffer_canvas.clear();
|
backbuffer_canvas.clear();
|
||||||
|
|
||||||
// Copy the pre-rendered map texture to the backbuffer
|
// Copy the pre-rendered map texture to the backbuffer
|
||||||
backbuffer_canvas
|
if let Err(e) = backbuffer_canvas.copy(&map_texture.0, None, None) {
|
||||||
.copy(&map_texture.0, None, None)
|
errors.write(TextureError::RenderFailed(e.to_string()).into());
|
||||||
.err()
|
}
|
||||||
.map(|e| errors.write(TextureError::RenderFailed(e.to_string()).into()));
|
|
||||||
|
|
||||||
// Render all entities to the backbuffer
|
// Render all entities to the backbuffer
|
||||||
for (_, mut renderable, position) in renderables
|
for (_, renderable, position) in renderables.iter() {
|
||||||
// .iter_mut()
|
|
||||||
// .sort_by_key::<&mut Renderable, _, _>(|(renderable, renderable, renderable)| renderable.layer)
|
|
||||||
// .collect()
|
|
||||||
{
|
|
||||||
let pos = position.get_pixel_pos(&map.graph);
|
let pos = position.get_pixel_pos(&map.graph);
|
||||||
match pos {
|
match pos {
|
||||||
Ok(pos) => {
|
Ok(pos) => {
|
||||||
@@ -107,4 +120,6 @@ pub fn render_system(
|
|||||||
.map(|e| errors.write(TextureError::RenderFailed(e.to_string()).into()));
|
.map(|e| errors.write(TextureError::RenderFailed(e.to_string()).into()));
|
||||||
|
|
||||||
canvas.present();
|
canvas.present();
|
||||||
|
|
||||||
|
dirty.0 = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ pub struct MapperFrame {
|
|||||||
pub height: u16,
|
pub height: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub struct AtlasTile {
|
pub struct AtlasTile {
|
||||||
pub pos: U16Vec2,
|
pub pos: U16Vec2,
|
||||||
pub size: U16Vec2,
|
pub size: U16Vec2,
|
||||||
@@ -30,7 +30,7 @@ pub struct AtlasTile {
|
|||||||
|
|
||||||
impl AtlasTile {
|
impl AtlasTile {
|
||||||
pub fn render<C: RenderTarget>(
|
pub fn render<C: RenderTarget>(
|
||||||
&mut self,
|
&self,
|
||||||
canvas: &mut Canvas<C>,
|
canvas: &mut Canvas<C>,
|
||||||
atlas: &mut SpriteAtlas,
|
atlas: &mut SpriteAtlas,
|
||||||
dest: Rect,
|
dest: Rect,
|
||||||
@@ -41,7 +41,7 @@ impl AtlasTile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_with_color<C: RenderTarget>(
|
pub fn render_with_color<C: RenderTarget>(
|
||||||
&mut self,
|
&self,
|
||||||
canvas: &mut Canvas<C>,
|
canvas: &mut Canvas<C>,
|
||||||
atlas: &mut SpriteAtlas,
|
atlas: &mut SpriteAtlas,
|
||||||
dest: Rect,
|
dest: Rect,
|
||||||
|
|||||||
@@ -103,9 +103,9 @@ impl TextTexture {
|
|||||||
&self.char_map
|
&self.char_map
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tile(&mut self, c: char, atlas: &mut SpriteAtlas) -> Result<Option<&mut AtlasTile>> {
|
pub fn get_tile(&mut self, c: char, atlas: &mut SpriteAtlas) -> Result<Option<&AtlasTile>> {
|
||||||
if self.char_map.contains_key(&c) {
|
if self.char_map.contains_key(&c) {
|
||||||
return Ok(self.char_map.get_mut(&c));
|
return Ok(self.char_map.get(&c));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(tile_name) = char_to_tile_name(c) {
|
if let Some(tile_name) = char_to_tile_name(c) {
|
||||||
@@ -113,7 +113,7 @@ impl TextTexture {
|
|||||||
.get_tile(&tile_name)
|
.get_tile(&tile_name)
|
||||||
.ok_or(GameError::Texture(TextureError::AtlasTileNotFound(tile_name)))?;
|
.ok_or(GameError::Texture(TextureError::AtlasTileNotFound(tile_name)))?;
|
||||||
self.char_map.insert(c, tile);
|
self.char_map.insert(c, tile);
|
||||||
Ok(self.char_map.get_mut(&c))
|
Ok(self.char_map.get(&c))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user