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
|
Added Player movement and render
|
||||||
<img src="./screenshots/EmptyMap_and_Player.png" width="80%">
|
<img src="./screenshots/EmptyMap_and_Player.png" width="80%">
|
||||||
|
|
||||||
|
Added randomly generated rooms and tunnels :D
|
||||||
|
<img src="./screenshots/Map_Generated.png" width="80%">
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
+6
-5
@@ -4,6 +4,7 @@
|
|||||||
/// date : 26/04/2022
|
/// date : 26/04/2022
|
||||||
/// brief : Main game file
|
/// brief : Main game file
|
||||||
mod map;
|
mod map;
|
||||||
|
mod map_builder;
|
||||||
mod player;
|
mod player;
|
||||||
|
|
||||||
mod prelude {
|
mod prelude {
|
||||||
@@ -12,6 +13,7 @@ mod prelude {
|
|||||||
pub const SCREEN_HEIGHT: i32 = 50;
|
pub const SCREEN_HEIGHT: i32 = 50;
|
||||||
pub use crate::map::*;
|
pub use crate::map::*;
|
||||||
pub use crate::player::*;
|
pub use crate::player::*;
|
||||||
|
pub use crate::map_builder::*;
|
||||||
}
|
}
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
|
|
||||||
@@ -23,12 +25,11 @@ struct State {
|
|||||||
}
|
}
|
||||||
impl State {
|
impl State {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
let mut rng = RandomNumberGenerator::new();
|
||||||
|
let map_builder = MapBuilder::new(&mut rng);
|
||||||
Self {
|
Self {
|
||||||
map: Map::new(),
|
map: map_builder.map,
|
||||||
player: Player::new(
|
player: Player::new(map_builder.player_start),
|
||||||
//spawns the player in the middle of the map
|
|
||||||
Point::new(SCREEN_WIDTH / 2,SCREEN_HEIGHT / 2)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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