Added random room and corridors generation :D
This commit is contained in:
@@ -5,3 +5,6 @@ First running programm with an empty map
|
||||
|
||||
Added Player movement and render
|
||||
<img src="./screenshots/EmptyMap_and_Player.png" width="80%">
|
||||
|
||||
Added randomly generated rooms and tunnels :D
|
||||
<img src="./screenshots/Map_Generated.png" width="80%">
|
||||
|
||||
BIN
doc/screenshots/Map_Generated.png
Normal file
BIN
doc/screenshots/Map_Generated.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
11
src/main.rs
11
src/main.rs
@@ -4,6 +4,7 @@
|
||||
/// date : 26/04/2022
|
||||
/// brief : Main game file
|
||||
mod map;
|
||||
mod map_builder;
|
||||
mod player;
|
||||
|
||||
mod prelude {
|
||||
@@ -12,6 +13,7 @@ mod prelude {
|
||||
pub const SCREEN_HEIGHT: i32 = 50;
|
||||
pub use crate::map::*;
|
||||
pub use crate::player::*;
|
||||
pub use crate::map_builder::*;
|
||||
}
|
||||
use prelude::*;
|
||||
|
||||
@@ -23,12 +25,11 @@ struct State {
|
||||
}
|
||||
impl State {
|
||||
fn new() -> Self {
|
||||
let mut rng = RandomNumberGenerator::new();
|
||||
let map_builder = MapBuilder::new(&mut rng);
|
||||
Self {
|
||||
map: Map::new(),
|
||||
player: Player::new(
|
||||
//spawns the player in the middle of the map
|
||||
Point::new(SCREEN_WIDTH / 2,SCREEN_HEIGHT / 2)
|
||||
)
|
||||
map: map_builder.map,
|
||||
player: Player::new(map_builder.player_start),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
91
src/map_builder.rs
Normal file
91
src/map_builder.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
/// file : map_builder.rs
|
||||
/// author : Maxime Rohmer (from Herbet Wolverson book)
|
||||
/// version : 0.1.0
|
||||
/// date : 26/04/2022
|
||||
/// brief : File that contains all the map and dungeons generations stuff
|
||||
|
||||
use crate::prelude::*;
|
||||
const NUM_ROOMS: usize = 20;
|
||||
const ROOM_SIZE_REDUCTOR :i32 = 10;
|
||||
|
||||
pub struct MapBuilder {
|
||||
pub map : Map,
|
||||
pub rooms : Vec<Rect>,
|
||||
pub player_start : Point,
|
||||
}
|
||||
//please dont ask me too much on how this EXACTLY works because my brain is likely going to shut down
|
||||
impl MapBuilder{
|
||||
pub fn new(rng: &mut RandomNumberGenerator) -> Self{
|
||||
let mut mb = MapBuilder{
|
||||
map : Map::new(),
|
||||
rooms : Vec::new(),
|
||||
player_start : Point::zero(),
|
||||
};
|
||||
mb.fill(TileType::Wall);
|
||||
mb.build_random_rooms(rng);
|
||||
mb.build_corridors(rng);
|
||||
mb.player_start = mb.rooms[0].center();
|
||||
mb
|
||||
}
|
||||
fn fill(& mut self, tile : TileType){
|
||||
self.map.tiles.iter_mut().for_each(|t| *t = tile);
|
||||
}
|
||||
fn build_random_rooms(&mut self, rng : &mut RandomNumberGenerator){
|
||||
while self.rooms.len() < NUM_ROOMS{
|
||||
let room = Rect::with_size(
|
||||
rng.range(1, SCREEN_WIDTH - ROOM_SIZE_REDUCTOR),
|
||||
rng.range(1, SCREEN_HEIGHT - ROOM_SIZE_REDUCTOR),
|
||||
rng.range(2,10),
|
||||
rng.range(2,10),
|
||||
);
|
||||
let mut overlap = false;
|
||||
for r in self.rooms.iter(){
|
||||
if r.intersect(&room){
|
||||
overlap = true;
|
||||
}
|
||||
}
|
||||
if !overlap {
|
||||
room.for_each(|p|{
|
||||
if p.x > 0 && p.x < SCREEN_WIDTH && p.y > 0 && p.y < SCREEN_HEIGHT{
|
||||
let idx = map_idx(p.x,p.y);
|
||||
self.map.tiles[idx] = TileType::Floor;
|
||||
}
|
||||
});
|
||||
self.rooms.push(room)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn apply_vertical_tunnel(&mut self, y1:i32,y2:i32,x:i32){
|
||||
use std::cmp::{min,max};
|
||||
for y in min(y1,y2) ..= max(y1,y2){
|
||||
if let Some(idx) = self.map.try_idx(Point::new(x,y)){
|
||||
self.map.tiles[idx as usize] = TileType::Floor;
|
||||
}
|
||||
}
|
||||
}
|
||||
fn apply_horizontal_tunnel(&mut self,x1:i32,x2:i32,y:i32){
|
||||
use std::cmp::{min,max};
|
||||
for x in min(x1,x2) ..= max(x1,x2){
|
||||
if let Some(idx) = self.map.try_idx(Point::new(x,y)){
|
||||
self.map.tiles[idx as usize] = TileType::Floor;
|
||||
}
|
||||
}
|
||||
}
|
||||
fn build_corridors(&mut self, rng: &mut RandomNumberGenerator){
|
||||
let mut rooms = self.rooms.clone();
|
||||
rooms.sort_by(|a,b| a.center().x.cmp(&b.center().x));
|
||||
|
||||
for (i,room) in rooms.iter().enumerate().skip(1){
|
||||
let prev = rooms[i-1].center();
|
||||
let new = room.center();
|
||||
|
||||
if rng.range(0,2) == 1{
|
||||
self.apply_horizontal_tunnel(prev.x,new.x,prev.y);
|
||||
self.apply_vertical_tunnel(prev.y,new.y,new.x);
|
||||
}else{
|
||||
self.apply_vertical_tunnel(prev.y,new.y,prev.x);
|
||||
self.apply_horizontal_tunnel(prev.x,new.x,new.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user