rust-sokoban/src/systems/rendering_system.rs

46 lines
1.8 KiB
Rust

use ggez::graphics::DrawParam;
use ggez::graphics::Image;
use ggez::nalgebra as na;
use ggez::{graphics, Context};
use specs::{Join, ReadStorage, System};
use crate::components::{Position, Renderable};
use crate::constants::TILE_WIDTH;
pub struct RenderingSystem<'a> {
pub context: &'a mut Context,
}
impl<'a> System<'a> for RenderingSystem<'a> {
type SystemData = (ReadStorage<'a, Position>, ReadStorage<'a, Renderable>);
fn run(&mut self, data: Self::SystemData) {
let (positions, renderables) = data;
// Clear the screen/set the background
graphics::clear(self.context, graphics::Color::new(0.95, 0.95, 0.95, 1.0));
// Get all the renderables with their positions and sort by the position z
// This will allow us to have entities layered visually.
let mut rendering_data = (&positions, &renderables).join().collect::<Vec<_>>();
rendering_data.sort_by(|&a, &b| a.0.z.partial_cmp(&b.0.z).expect("expected comparison"));
// Iterate through all paris of positions & renderables, load the image
// and draw it at the specified position.
for (position, renderable) in rendering_data.iter() {
// Load the image
let image = Image::new(self.context, renderable.path.clone()).expect("expected image");
let x = position.x as f32 * TILE_WIDTH;
let y = position.y as f32 * TILE_WIDTH;
// draw
let draw_params = DrawParam::new().dest(na::Point2::new(x, y));
graphics::draw(self.context, &image, draw_params).expect("expected render");
}
// Finally, present the context, this will actually display everything
// on the screen.
graphics::present(self.context).expect("expected to present");
}
}