diff --git a/src/game/mod.rs b/src/game/mod.rs index 9a29d3a..a8d992d 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -100,7 +100,7 @@ impl Game { // Render map to texture 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()))?; @@ -196,10 +196,10 @@ impl Game { profile("collision", collision_system), profile("blinking", blinking_system), profile("directional_render", directional_render_system), - profile("render", render_system), ) .chain(), ); + schedule.add_systems(profile("render", render_system)); // Spawn player world.spawn(player); diff --git a/src/map/render.rs b/src/map/render.rs index aa16f66..cf86766 100644 --- a/src/map/render.rs +++ b/src/map/render.rs @@ -19,7 +19,7 @@ impl MapRenderer { /// /// This function draws the static map texture to the screen at the correct /// position and scale. - pub fn render_map(canvas: &mut Canvas, atlas: &mut SpriteAtlas, map_tiles: &mut [AtlasTile]) { + pub fn render_map(canvas: &mut Canvas, atlas: &mut SpriteAtlas, map_tiles: &[AtlasTile]) { for (y, row) in TILE_MAP.iter().enumerate() { for (x, &tile_index) in row.iter().enumerate() { let mut tile = map_tiles[tile_index]; diff --git a/src/systems/render.rs b/src/systems/render.rs index c5d8847..1e73c66 100644 --- a/src/systems/render.rs +++ b/src/systems/render.rs @@ -5,6 +5,7 @@ use crate::systems::movement::{Movable, MovementState, Position}; use crate::texture::sprite::SpriteAtlas; use bevy_ecs::entity::Entity; use bevy_ecs::event::EventWriter; +use bevy_ecs::prelude::{Changed, Or, RemovedComponents}; use bevy_ecs::system::{NonSendMut, Query, Res}; use sdl2::render::{Canvas, Texture}; use sdl2::video::Window; @@ -31,7 +32,10 @@ pub fn directional_render_system( if !stopped { 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 { errors.write(TextureError::RenderFailed(format!("Entity has no texture")).into()); continue; @@ -51,9 +55,14 @@ pub fn render_system( mut backbuffer: NonSendMut, mut atlas: NonSendMut, map: Res, - renderables: Query<(Entity, &mut Renderable, &Position)>, + renderables: Query<(Entity, &Renderable, &Position)>, + changed_renderables: Query<(), Or<(Changed, Changed)>>, + removed_renderables: RemovedComponents, mut errors: EventWriter, ) { + if changed_renderables.is_empty() && removed_renderables.is_empty() { + return; + } // Clear the main canvas first canvas.set_draw_color(sdl2::pixels::Color::BLACK); canvas.clear(); @@ -66,17 +75,12 @@ pub fn render_system( backbuffer_canvas.clear(); // Copy the pre-rendered map texture to the backbuffer - backbuffer_canvas - .copy(&map_texture.0, None, None) - .err() - .map(|e| errors.write(TextureError::RenderFailed(e.to_string()).into())); + if let Err(e) = backbuffer_canvas.copy(&map_texture.0, None, None) { + errors.write(TextureError::RenderFailed(e.to_string()).into()); + } // Render all entities to the backbuffer - for (_, mut renderable, position) in renderables - // .iter_mut() - // .sort_by_key::<&mut Renderable, _, _>(|(renderable, renderable, renderable)| renderable.layer) - // .collect() - { + for (_, renderable, position) in renderables.iter() { let pos = position.get_pixel_pos(&map.graph); match pos { Ok(pos) => { diff --git a/src/texture/sprite.rs b/src/texture/sprite.rs index 6e7111b..d3ec876 100644 --- a/src/texture/sprite.rs +++ b/src/texture/sprite.rs @@ -21,7 +21,7 @@ pub struct MapperFrame { pub height: u16, } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq)] pub struct AtlasTile { pub pos: U16Vec2, pub size: U16Vec2, @@ -30,7 +30,7 @@ pub struct AtlasTile { impl AtlasTile { pub fn render( - &mut self, + &self, canvas: &mut Canvas, atlas: &mut SpriteAtlas, dest: Rect, @@ -41,7 +41,7 @@ impl AtlasTile { } pub fn render_with_color( - &mut self, + &self, canvas: &mut Canvas, atlas: &mut SpriteAtlas, dest: Rect, diff --git a/src/texture/text.rs b/src/texture/text.rs index c6059dc..abea508 100644 --- a/src/texture/text.rs +++ b/src/texture/text.rs @@ -103,9 +103,9 @@ impl TextTexture { &self.char_map } - pub fn get_tile(&mut self, c: char, atlas: &mut SpriteAtlas) -> Result> { + pub fn get_tile(&mut self, c: char, atlas: &mut SpriteAtlas) -> Result> { 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) { @@ -113,7 +113,7 @@ impl TextTexture { .get_tile(&tile_name) .ok_or(GameError::Texture(TextureError::AtlasTileNotFound(tile_name)))?; self.char_map.insert(c, tile); - Ok(self.char_map.get_mut(&c)) + Ok(self.char_map.get(&c)) } else { Ok(None) }