Building a Dungeon
Learn how to place rooms randomly, connect them with corridors, and build a dungeon for the adventurer to explore.
Create a map builder module
Let’s create a new map_builder.rs
file. This file contains the map building module. Add it to prelude
in main.rs
:
mod map;mod map_builder;mod player;mod prelude {pub use bracket_lib::prelude::*;pub const SCREEN_WIDTH: i32 = 80;pub const SCREEN_HEIGHT: i32 = 50;pub use crate::map::*;pub use crate::player::*;pub use crate::map_builder::*;}
Start by importing the main prelude and defining a constant in map_builder.rs
that represents the maximum number of rooms we’d like in our dungeon. 20 rooms produces a nice-looking dungeon.
use crate::prelude::*;const NUM_ROOMS: usize = 20
Define a new structure to hold the MapBuilder
:
pub struct MapBuilder {pub map : Map,pub rooms : Vec<Rect>,pub player_start : Point,}
The structure contains its own Map
. It works on its own copy and passes the result to the game. The rooms
vector is a list of the rooms that are added to the map. Each room is represented with the Rect structure from bracket-lib. The Rect
structure is a helper for calculations involving rectangles. Finally, player_start
stores the location at which the player enters the map.
Let’s start adding some details to the map.
Fill the map with walls
The previous example started with a dungeon composed entirely of floors. A room-carving algorithm works the other way around, starting with a solid block of rock and carving rooms and corridors from the stone.
Add the following to MapBuilder
implementation:
fn fill(&mut self, tile : TileType) {self.map.tiles.iter_mut().for_each(|t| *t = tile);}
This function obtains a mutable iterator with iter_mut()
and then uses for_each()
to ...