#[macro_use] extern crate specs_derive; #[macro_use] extern crate specs_system_macro; use ggez::GameError; use specs::prelude::*; #[derive(Component)] pub struct Pos { x: usize, y: usize, } #[derive(Component)] pub struct Renderable { glyph: carpet::CP437, color: carpet::Color, } #[derive(Component)] pub struct MoveLeft; #[derive(Component)] pub struct Player; impl Player { fn get_entity(world: &mut specs::World) -> Entity { let storage = (&world.read_component::(), &world.entities()); storage .join() .next() .expect("No entities tagged as Player") .1 } } #[derive(Component)] pub struct Motion { down: i8, right: i8, } impl Motion { fn move_player(world: &mut specs::World, down: i8, right: i8) { let player = Player::get_entity(world); world .write_component::() .insert(player, Motion { down, right }) .unwrap(); } } system_impl! { Draw( resource mut board: carpet::GameBoard, renderable: Renderable, pos: Pos, ) { board.clear(); for (p, r) in (&pos, &renderable).join() { board.set_with_color([p.x, p.y], r.glyph, r.color); } } } system! { Leftward ( _left: MoveLeft, mut pos: Pos, ) { if pos.x == 0 { pos.x = 79; } else { pos.x -= 1; } } } system! { Move ( mut motion: Motion, mut pos: Pos, ) { pos.x = (pos.x as i8 + motion.right) as usize; pos.y = (pos.y as i8 + motion.down) as usize; } finally { motion.clear(); } } fn main() -> Result<(), GameError> { let mut game = carpet::GameBuilder::new() .name("game") .author("me") .resource_path({ let base = std::env::var("CARGO_MANIFEST_DIR").unwrap(); let mut path = std::path::PathBuf::from(base); path.pop(); path.push("resources"); path }) .tileset("/haberdash.gif", [12, 12]) .map_size(80, 50) .build()?; game.register::(); game.register::(); game.register::(); game.register::(); game.register::(); game.world.print([1, 1], "Hello, world!"); game.create_entity() .with(Pos { x: 40, y: 25 }) .with(Player) .with(Renderable { glyph: carpet::CP437::from_char('A'), color: carpet::Color::Blue, }) .build(); for i in 0..10 { game.create_entity() .with(Pos { x: i * 7, y: 20 }) .with(Renderable { glyph: carpet::CP437::from_char('X'), color: carpet::Color::Red, }) .with(MoveLeft) .build(); } game.on_key( (carpet::VirtualKeyCode::W, carpet::KeyMods::NONE), |world| { Motion::move_player(world, -1, 0); }, ); game.on_key( (carpet::VirtualKeyCode::A, carpet::KeyMods::NONE), |world| { Motion::move_player(world, 0, -1); }, ); game.on_key( (carpet::VirtualKeyCode::S, carpet::KeyMods::NONE), |world| { Motion::move_player(world, 1, 0); }, ); game.on_key( (carpet::VirtualKeyCode::D, carpet::KeyMods::NONE), |world| { Motion::move_player(world, 0, 1); }, ); game.run_with_systems(|world| { Draw.run_now(&world); Leftward.run_now(&world); Move.run_now(&world); }) }