diff --git a/src/main.rs b/src/main.rs index 0b49d56..90aae53 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,9 +16,6 @@ struct Renderable { bg: RGB, } -#[derive(Component)] -struct LeftMover {} - #[derive(Component, Debug)] struct Player {} @@ -26,13 +23,23 @@ struct State { ecs: World, } +#[derive(PartialEq, Copy, Clone)] +enum TileType { + Wall, + Floor, +} + fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) { let mut positions = ecs.write_storage::(); let mut players = ecs.write_storage::(); + let map = ecs.fetch::>(); for (_player, pos) in (&mut players, &mut positions).join() { - pos.x = min(79, max(0, pos.x + delta_x)); - pos.y = min(49, max(0, pos.y + delta_y)); + let destination_idx = xy_idx(pos.x + delta_x, pos.y + delta_y); + if map[destination_idx] != TileType::Wall { + pos.x = min(79, max(0, pos.x + delta_x)); + pos.y = min(49, max(0, pos.y + delta_y)); + } } } @@ -45,11 +52,76 @@ fn player_input(gs: &mut State, ctx: &mut Rltk) { VirtualKeyCode::Right => try_move_player(1, 0, &mut gs.ecs), VirtualKeyCode::Up => try_move_player(0, -1, &mut gs.ecs), VirtualKeyCode::Down => try_move_player(0, 1, &mut gs.ecs), - _ => {}, + _ => {} }, } } +fn new_map() -> Vec { + let mut map = vec![TileType::Floor; 80 * 50]; + + // Make the boundary walls + for x in 0..80 { + map[xy_idx(x, 0)] = TileType::Wall; + map[xy_idx(x, 49)] = TileType::Wall; + } + for y in 0..50 { + map[xy_idx(0, y)] = TileType::Wall; + map[xy_idx(79, y)] = TileType::Wall; + } + + // Now randomly add a bunch of walls. + // First get the random number generator + let mut rng = rltk::RandomNumberGenerator::new(); + + for _i in 0..400 { + let x = rng.roll_dice(1, 79); + let y = rng.roll_dice(1, 49); + + let idx = xy_idx(x, y); + if idx != xy_idx(40, 25) { + map[idx] = TileType::Wall; + } + } + + map +} + +fn draw_map(map: &[TileType], ctx: &mut Rltk) { + let mut y = 0; + let mut x = 0; + + for tile in map.iter() { + match tile { + TileType::Floor => { + ctx.set( + x, + y, + RGB::from_f32(0.5, 0.5, 0.5), + RGB::from_f32(0., 0., 0.), + rltk::to_cp437('.'), + ); + } + TileType::Wall => { + ctx.set( + x, + y, + RGB::from_f32(0.0, 1.0, 0.0), + RGB::from_f32(0., 0., 0.), + rltk::to_cp437('#'), + ); + } + } + + // Move to the next set of coordinates + x += 1; + if x > 79 { + x = 0; + y += 1; + } + } +} + impl GameState for State { fn tick(&mut self, ctx: &mut Rltk) { ctx.cls(); @@ -57,6 +129,9 @@ impl GameState for State { player_input(self, ctx); self.run_systems(); + let map = self.ecs.fetch::>(); + draw_map(&map, ctx); + let positions = self.ecs.read_storage::(); let renderables = self.ecs.read_storage::(); @@ -66,28 +141,14 @@ impl GameState for State { } } -struct LeftWalker {} - -impl<'a> System<'a> for LeftWalker { - type SystemData = (ReadStorage<'a, LeftMover>, WriteStorage<'a, Position>); - - fn run(&mut self, (lefty, mut pos): Self::SystemData) { - for (_lefty, pos) in (&lefty, &mut pos).join() { - pos.x -= 1; - - if pos.x < 0 { - pos.x = 79; - } - } +impl State { + fn run_systems(&mut self) { + self.ecs.maintain(); } } -impl State { - fn run_systems(&mut self) { - let mut lw = LeftWalker{}; - lw.run_now(&self.ecs); - self.ecs.maintain(); - } +pub fn xy_idx(x: i32, y: i32) -> usize { + (y as usize * 80) + x as usize } fn main() -> rltk::BError { @@ -101,9 +162,10 @@ fn main() -> rltk::BError { gs.ecs.register::(); gs.ecs.register::(); - gs.ecs.register::(); gs.ecs.register::(); + gs.ecs.insert(new_map()); + gs.ecs .create_entity() .with(Position { x: 40, y: 25 }) @@ -115,18 +177,5 @@ fn main() -> rltk::BError { .with(Player {}) .build(); - for i in 0..10 { - gs.ecs - .create_entity() - .with(Position { x: i * 7, y: 20 }) - .with(Renderable { - glyph: rltk::to_cp437('☺'), - fg: RGB::named(rltk::RED), - bg: RGB::named(rltk::BLACK), - }) - .with(LeftMover {}) - .build(); - } - rltk::main_loop(context, gs) }