mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-06 01:15:42 -06:00
feat: only present/render canvas when renderables change
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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<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 (x, &tile_index) in row.iter().enumerate() {
|
||||
let mut tile = map_tiles[tile_index];
|
||||
|
||||
@@ -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<BackbufferResource>,
|
||||
mut atlas: NonSendMut<SpriteAtlas>,
|
||||
map: Res<Map>,
|
||||
renderables: Query<(Entity, &mut Renderable, &Position)>,
|
||||
renderables: Query<(Entity, &Renderable, &Position)>,
|
||||
changed_renderables: Query<(), Or<(Changed<Renderable>, Changed<Position>)>>,
|
||||
removed_renderables: RemovedComponents<Renderable>,
|
||||
mut errors: EventWriter<GameError>,
|
||||
) {
|
||||
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) => {
|
||||
|
||||
@@ -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<C: RenderTarget>(
|
||||
&mut self,
|
||||
&self,
|
||||
canvas: &mut Canvas<C>,
|
||||
atlas: &mut SpriteAtlas,
|
||||
dest: Rect,
|
||||
@@ -41,7 +41,7 @@ impl AtlasTile {
|
||||
}
|
||||
|
||||
pub fn render_with_color<C: RenderTarget>(
|
||||
&mut self,
|
||||
&self,
|
||||
canvas: &mut Canvas<C>,
|
||||
atlas: &mut SpriteAtlas,
|
||||
dest: Rect,
|
||||
|
||||
@@ -103,9 +103,9 @@ impl TextTexture {
|
||||
&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) {
|
||||
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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user