use anyhow::{anyhow, Result};
use blit::{blit_buffer, Color};
use minifb::*;
use specs::prelude::*;
use specs_blit::{PixelBuffer, RenderSystem, Sprite};
use std::thread::sleep;
use std::time::Duration;
const WIDTH: usize = 250;
const HEIGHT: usize = 250;
const MASK_COLOR: u32 = 0xFF_00_FF;
#[derive(Debug, Default)]
pub struct Rotation(pub f64);
pub struct RotationSystem;
impl<'a> System<'a> for RotationSystem {
type SystemData = (Read<'a, Rotation>, WriteStorage<'a, Sprite>);
fn run(&mut self, (rot, mut sprite): Self::SystemData) {
for (sprite,) in (&mut sprite,).join() {
sprite.set_rot(rot.0 as i16);
}
}
}
fn main() -> Result<()> {
let mut world = World::new();
world.register::<Sprite>();
world.insert(PixelBuffer::new(WIDTH, HEIGHT));
world.insert(Rotation(0.0));
let sprite_ref = {
let img = image::open("examples/smiley.png")?;
let sprite = blit_buffer(&img, Color::from_u32(MASK_COLOR));
specs_blit::load_rotations_range(sprite, 16, (-270, 90))?
};
world.create_entity().with(Sprite::new(sprite_ref)).build();
let mut dispatcher = DispatcherBuilder::new()
.with(RotationSystem, "rotation", &[])
.with_thread_local(RenderSystem)
.build();
let options = WindowOptions {
scale: Scale::X2,
..WindowOptions::default()
};
let mut window = Window::new("Specs Blit Example - ESC to exit", WIDTH, HEIGHT, options)
.map_err(|err| anyhow!("{}", err))?;
let mut rotation = 0.0;
while window.is_open() && !window.is_key_down(Key::Escape) {
{
let mut buffer = world.write_resource::<PixelBuffer>();
buffer.clear(0);
let mut rot_resource = world.write_resource::<Rotation>();
rot_resource.0 = rotation;
rotation += 1.0;
}
dispatcher.dispatch(&world);
world.maintain();
let buffer = world.read_resource::<PixelBuffer>();
window
.update_with_buffer(&buffer.pixels(), buffer.width(), buffer.height())
.unwrap();
sleep(Duration::from_millis(12));
}
Ok(())
}