simple_map.rs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. use super::{MapBuilder, Map, Rect, apply_room_to_map,
  2. apply_horizontal_tunnel, apply_vertical_tunnel, TileType,
  3. Position, spawner};
  4. use rltk::RandomNumberGenerator;
  5. use specs::prelude::*;
  6. pub struct SimpleMapBuilder {}
  7. impl MapBuilder for SimpleMapBuilder {
  8. fn build(new_depth: i32) -> (Map, Position) {
  9. let mut map = Map::new(new_depth);
  10. let playerpos = SimpleMapBuilder::rooms_and_corridors(&mut map);
  11. (map, playerpos)
  12. }
  13. fn spawn(map : &Map, ecs : &mut World, new_depth: i32) {
  14. for room in map.rooms.iter().skip(1) {
  15. spawner::spawn_room(ecs, room, new_depth);
  16. }
  17. }
  18. }
  19. impl SimpleMapBuilder {
  20. fn rooms_and_corridors(map : &mut Map) -> Position {
  21. const MAX_ROOMS : i32 = 30;
  22. const MIN_SIZE : i32 = 6;
  23. const MAX_SIZE : i32 = 10;
  24. let mut rng = RandomNumberGenerator::new();
  25. for _i in 0..MAX_ROOMS {
  26. let w = rng.range(MIN_SIZE, MAX_SIZE);
  27. let h = rng.range(MIN_SIZE, MAX_SIZE);
  28. let x = rng.roll_dice(1, map.width - w - 1) - 1;
  29. let y = rng.roll_dice(1, map.height - h - 1) - 1;
  30. let new_room = Rect::new(x, y, w, h);
  31. let mut ok = true;
  32. for other_room in map.rooms.iter() {
  33. if new_room.intersect(other_room) { ok = false }
  34. }
  35. if ok {
  36. apply_room_to_map(map, &new_room);
  37. if !map.rooms.is_empty() {
  38. let (new_x, new_y) = new_room.center();
  39. let (prev_x, prev_y) = map.rooms[map.rooms.len()-1].center();
  40. if rng.range(0,1) == 1 {
  41. apply_horizontal_tunnel(map, prev_x, new_x, prev_y);
  42. apply_vertical_tunnel(map, prev_y, new_y, new_x);
  43. } else {
  44. apply_vertical_tunnel(map, prev_y, new_y, prev_x);
  45. apply_horizontal_tunnel(map, prev_x, new_x, new_y);
  46. }
  47. }
  48. map.rooms.push(new_room);
  49. }
  50. }
  51. let stairs_position = map.rooms[map.rooms.len()-1].center();
  52. let stairs_idx = map.xy_idx(stairs_position.0, stairs_position.1);
  53. map.tiles[stairs_idx] = TileType::DownStairs;
  54. let start_pos = map.rooms[0].center();
  55. Position{ x: start_pos.0, y: start_pos.1 }
  56. }
  57. }