From a07ba21a5c34cbd817555e9146171f415494b58d Mon Sep 17 00:00:00 2001 From: AmadeusWM <63149896+AmadeusWM@users.noreply.github.com> Date: Sun, 6 Apr 2025 18:45:43 +0200 Subject: [PATCH 1/6] better world generation --- src/level_instantiation/mod.rs | 70 ++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/src/level_instantiation/mod.rs b/src/level_instantiation/mod.rs index 043fc81..55d2961 100644 --- a/src/level_instantiation/mod.rs +++ b/src/level_instantiation/mod.rs @@ -12,6 +12,8 @@ pub fn map_plugin(app: &mut App) { fn spawn_level( mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, models: Res>, gltf_assets: Res ) { @@ -74,7 +76,7 @@ fn spawn_level( // Transform::from_xyz(-500.0, 3.0, -500.0), // )); // let map = GameMap::test(); - let map = GameMap::new(100); + let map = GameMap::new(10); map.print_map(); for ((x, z), node) in map.nodes.into_iter() { @@ -203,6 +205,14 @@ fn spawn_level( }); } } + let (x,z) = map.end_node; + commands.spawn(( + Mesh3d(meshes.add(Cuboid::new(3.0, 3.0, 3.0))), + MeshMaterial3d(materials.add(Color::srgb_u8(255, 0, 0))), + Transform::from_xyz(2.0*x as f32, 0.5, -2.0*z as f32), + RigidBody::Fixed, + Collider::cuboid(0.5, 0.5, 0.5), + )); } #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -218,7 +228,6 @@ struct MapNode { south: Side, east: Side, west: Side, - collapsed: bool, } impl MapNode { @@ -228,18 +237,18 @@ impl MapNode { south: Side::Empty, east: Side::Empty, west: Side::Empty, - collapsed: false, } } } struct GameMap { nodes: HashMap<(i32, i32), MapNode>, - max_nodes: i32 + end_node: (i32, i32), + grid_size: i32 } impl GameMap { - fn new(max_nodes: i32) -> Self { + fn new(grid_size: i32) -> Self { let mut nodes = HashMap::new(); let mut start_node = MapNode::new(); start_node.north = Side::Connection; @@ -247,7 +256,7 @@ impl GameMap { start_node.east = Side::Connection; start_node.west = Side::Connection; nodes.insert((0, 0), start_node); - let mut m = GameMap { nodes, max_nodes }; + let mut m = GameMap { nodes, grid_size, end_node: (0, 0) }; m.generate_map(); m } @@ -305,7 +314,11 @@ impl GameMap { wall_node5.south = Side::Connection; nodes.insert((3, 2), wall_node5); - GameMap { nodes, max_nodes: 7 } + GameMap { + nodes, + grid_size: 7, + end_node: (0, 0) + } } fn generate_map(&mut self) { @@ -315,17 +328,38 @@ impl GameMap { // self.create_node(&(-1, 0)); // West } - fn choose_side(&self) -> Side { - if self.nodes.len() > self.max_nodes as usize { + fn choose_side(&self, pos: (i32, i32)) -> Side { + if pos.0 > self.grid_size || pos.1 > self.grid_size || pos.0 < 0 || pos.1 < 0 { Side::Closed } else { if rand::rng().random_bool(0.5) { Side::Connection } else { Side::Closed } } } + fn ensure_connection(&self, node: &mut MapNode) { + let am_connections = (node.north == Side::Connection) as u8 + + (node.south == Side::Connection) as u8 + + (node.east == Side::Connection) as u8 + + (node.west == Side::Connection) as u8; + + if am_connections <= 2 { + if node.north != Side::Connection { + node.north = Side::Connection + } + else if node.south != Side::Connection { + node.south = Side::Connection + } + else if node.east != Side::Connection { + node.east = Side::Connection + } + else if node.west != Side::Connection { + node.west = Side::Connection + } + } + } + fn create_node(&mut self, idx: &(i32, i32)) { let mut nodes_to_process = vec![*idx]; - let mut nodes_created = 0; while let Some(current_idx) = nodes_to_process.pop() { if self.nodes.contains_key(¤t_idx) { @@ -335,16 +369,23 @@ impl GameMap { let (x, y) = current_idx; let mut new_node = MapNode::new(); + if x >= self.end_node.0 && y >= self.end_node.1 { + self.end_node = (x, y); + } + let north = self.nodes.get(&(x, y + 1)); let south = self.nodes.get(&(x, y - 1)); let east = self.nodes.get(&(x + 1, y)); let west = self.nodes.get(&(x - 1, y)); - new_node.north = north.map_or_else(|| self.choose_side(), |n| n.south); - new_node.south = south.map_or_else(|| self.choose_side(), |s| s.north); - new_node.east = east.map_or_else(|| self.choose_side(), |e| e.west); - new_node.west = west.map_or_else(|| self.choose_side(), |w| w.east); + new_node.north = north.map_or_else(|| self.choose_side(current_idx), |n| n.south); + new_node.south = south.map_or_else(|| self.choose_side(current_idx), |s| s.north); + new_node.east = east.map_or_else(|| self.choose_side(current_idx), |e| e.west); + new_node.west = west.map_or_else(|| self.choose_side(current_idx), |w| w.east); + if !(current_idx.0 > self.grid_size || current_idx.1 > self.grid_size || current_idx.0 < 0 || current_idx.1 < 0) { + self.ensure_connection(&mut new_node); + } if new_node.north == Side::Connection && !self.nodes.contains_key(&(x, y + 1)) { nodes_to_process.push((x, y + 1)); } @@ -359,7 +400,6 @@ impl GameMap { } self.nodes.insert(current_idx, new_node); - nodes_created += 1; } } From 4b5b5915496125a98c5ad5fc95e1c7cfc9adf279 Mon Sep 17 00:00:00 2001 From: Back777space Date: Sun, 6 Apr 2025 19:37:47 +0200 Subject: [PATCH 2/6] fog --- src/main.rs | 7 ++++++- src/player.rs | 20 ++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index ebcbc51..9f4f1cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,11 +20,16 @@ fn main() { level_instantiation::map_plugin, interaction::plugin, RapierPhysicsPlugin::::default(), - RapierDebugRenderPlugin::default(), + // RapierDebugRenderPlugin::default(), player::plugin, // debugging::plugin )) .init_state::() + .insert_resource(AmbientLight { + color: Color::srgba(0.8, 0.8, 1.0, 1.0), + // brightness: 10.0, + brightness: 80 + }) .add_systems(OnEnter(GameState::Playing), setup) .run(); } diff --git a/src/player.rs b/src/player.rs index a006396..97e84be 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,6 +1,6 @@ use bevy::{ - input::mouse::AccumulatedMouseMotion, prelude::*, render::view::RenderLayers, window::{PrimaryWindow, WindowResized} + input::mouse::AccumulatedMouseMotion, pbr::VolumetricFog, prelude::*, render::view::RenderLayers, window::{PrimaryWindow, WindowResized} }; use bevy_kira_audio::{Audio, AudioControl}; use bevy_rapier3d::prelude::*; @@ -127,6 +127,14 @@ pub fn init_player( fov: 90.0_f32.to_radians(), ..default() }), + DistanceFog { + color: Color::srgba(0.12, 0.08, 0.08, 0.65), + falloff: FogFalloff::Linear { + start: 3.0, + end: 12.0, + }, + ..default() + }, )); // camera voor pitslampke @@ -153,10 +161,10 @@ pub fn init_player( Flashlight, SpotLight { intensity: 0.0, - color: Color::WHITE, - range: 4.0, - outer_angle: 30.0_f32.to_radians(), // wide cone for flashlight - inner_angle: 10.0_f32.to_radians(), // narrower inner cone + color: Color::srgba(0.9, 0.628, 0.392, 1.0), + range: 5.0, + outer_angle: 28.0_f32.to_radians(), // wide cone for flashlight + inner_angle: 12.0_f32.to_radians(), // narrower inner cone shadows_enabled: false, // (set to true for realism) radius: 0.35, // low value for hard light ..default() @@ -390,7 +398,7 @@ pub fn handle_flashlight( spotlight.intensity = if spotlight.intensity > 0.0 { 0.0 } else { - 300_000.0 + 320_000.0 }; } } From be906db22c6537e8e9cd8dd8853df02d1dbebf9c Mon Sep 17 00:00:00 2001 From: Back777space Date: Sun, 6 Apr 2025 19:38:08 +0200 Subject: [PATCH 3/6] fix --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 9f4f1cd..20de4b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,7 +28,7 @@ fn main() { .insert_resource(AmbientLight { color: Color::srgba(0.8, 0.8, 1.0, 1.0), // brightness: 10.0, - brightness: 80 + brightness: 80, }) .add_systems(OnEnter(GameState::Playing), setup) .run(); From 282ae1195802c6f0da2eb2f285ab181bc717ddd5 Mon Sep 17 00:00:00 2001 From: Back777space Date: Sun, 6 Apr 2025 19:38:36 +0200 Subject: [PATCH 4/6] fix --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 20de4b3..4554a3a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,7 +28,7 @@ fn main() { .insert_resource(AmbientLight { color: Color::srgba(0.8, 0.8, 1.0, 1.0), // brightness: 10.0, - brightness: 80, + brightness: 80.0, }) .add_systems(OnEnter(GameState::Playing), setup) .run(); From 45ed9f6d54ed6baadc3ea5f327aad368474c3d53 Mon Sep 17 00:00:00 2001 From: AmadeusWM <63149896+AmadeusWM@users.noreply.github.com> Date: Sun, 6 Apr 2025 19:00:17 +0200 Subject: [PATCH 5/6] fix broken maps --- src/level_instantiation/mod.rs | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/level_instantiation/mod.rs b/src/level_instantiation/mod.rs index 55d2961..c7ee6d5 100644 --- a/src/level_instantiation/mod.rs +++ b/src/level_instantiation/mod.rs @@ -76,7 +76,7 @@ fn spawn_level( // Transform::from_xyz(-500.0, 3.0, -500.0), // )); // let map = GameMap::test(); - let map = GameMap::new(10); + let map = GameMap::new((0, 0), 5); map.print_map(); for ((x, z), node) in map.nodes.into_iter() { @@ -207,11 +207,9 @@ fn spawn_level( } let (x,z) = map.end_node; commands.spawn(( - Mesh3d(meshes.add(Cuboid::new(3.0, 3.0, 3.0))), + Mesh3d(meshes.add(Cuboid::new(1.0, 3.0, 1.0))), MeshMaterial3d(materials.add(Color::srgb_u8(255, 0, 0))), Transform::from_xyz(2.0*x as f32, 0.5, -2.0*z as f32), - RigidBody::Fixed, - Collider::cuboid(0.5, 0.5, 0.5), )); } @@ -248,15 +246,15 @@ struct GameMap { } impl GameMap { - fn new(grid_size: i32) -> Self { + fn new(initial_point: (i32, i32), grid_size: i32) -> Self { let mut nodes = HashMap::new(); let mut start_node = MapNode::new(); start_node.north = Side::Connection; start_node.south = Side::Connection; start_node.east = Side::Connection; start_node.west = Side::Connection; - nodes.insert((0, 0), start_node); - let mut m = GameMap { nodes, grid_size, end_node: (0, 0) }; + nodes.insert(initial_point, start_node); + let mut m = GameMap { nodes, grid_size, end_node: initial_point }; m.generate_map(); m } @@ -336,23 +334,23 @@ impl GameMap { } } - fn ensure_connection(&self, node: &mut MapNode) { + fn ensure_connection(&self, node: &mut MapNode, (x, y): (i32, i32)) { let am_connections = (node.north == Side::Connection) as u8 + (node.south == Side::Connection) as u8 + (node.east == Side::Connection) as u8 + (node.west == Side::Connection) as u8; if am_connections <= 2 { - if node.north != Side::Connection { + if node.north != Side::Connection && !self.nodes.contains_key(&(x, y + 1)) { node.north = Side::Connection } - else if node.south != Side::Connection { + else if node.south != Side::Connection && !self.nodes.contains_key(&(x, y - 1)) { node.south = Side::Connection } - else if node.east != Side::Connection { + else if node.east != Side::Connection && !self.nodes.contains_key(&(x + 1, y)) { node.east = Side::Connection } - else if node.west != Side::Connection { + else if node.west != Side::Connection && !self.nodes.contains_key(&(x - 1, y)) { node.west = Side::Connection } } @@ -384,7 +382,7 @@ impl GameMap { new_node.west = west.map_or_else(|| self.choose_side(current_idx), |w| w.east); if !(current_idx.0 > self.grid_size || current_idx.1 > self.grid_size || current_idx.0 < 0 || current_idx.1 < 0) { - self.ensure_connection(&mut new_node); + self.ensure_connection(&mut new_node, current_idx); } if new_node.north == Side::Connection && !self.nodes.contains_key(&(x, y + 1)) { nodes_to_process.push((x, y + 1)); @@ -401,6 +399,14 @@ impl GameMap { self.nodes.insert(current_idx, new_node); } + + let end_node = self.nodes.get_mut(&self.end_node).unwrap(); + if self.end_node.1 >= self.end_node.0 { + end_node.north = Side::Connection; + } + else if self.end_node.0 >= self.end_node.1 { + end_node.east = Side::Connection; + } } fn print_map(&self) { From b06bde43f883841c3edc80a613818618268598a8 Mon Sep 17 00:00:00 2001 From: AmadeusWM <63149896+AmadeusWM@users.noreply.github.com> Date: Sun, 6 Apr 2025 19:40:13 +0200 Subject: [PATCH 6/6] multiple maps --- src/level_instantiation/mod.rs | 396 ++++++++++++++++----------------- 1 file changed, 191 insertions(+), 205 deletions(-) diff --git a/src/level_instantiation/mod.rs b/src/level_instantiation/mod.rs index c7ee6d5..828a395 100644 --- a/src/level_instantiation/mod.rs +++ b/src/level_instantiation/mod.rs @@ -76,141 +76,185 @@ fn spawn_level( // Transform::from_xyz(-500.0, 3.0, -500.0), // )); // let map = GameMap::test(); - let map = GameMap::new((0, 0), 5); - map.print_map(); - for ((x, z), node) in map.nodes.into_iter() { - let values = { - // corners are handled later, for now just a wall to test - let node = node.clone(); - let pos = Transform::from_xyz(2.0*x as f32, 0.0, -2.0*z as f32); + let maps = create_maps(3); - use Side::{Connection, Closed}; - match (node.north, node.east, node.south, node.west) { - // hallway horizontal - (Closed, Connection, Closed, Connection) => { - vec![ - (wall.clone(), pos), - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) - ] - }, - // hallway vertical - (Connection, Closed, Connection, Closed) => { - vec![ - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) - ] + for map in maps { + for ((x, z), node) in map.nodes.into_iter() { + let values = { + // corners are handled later, for now just a wall to test + let node = node.clone(); + let pos = Transform::from_xyz(2.0*x as f32, 0.0, -2.0*z as f32); + + use Side::{Connection, Closed}; + match (node.north, node.east, node.south, node.west) { + // hallway horizontal + (Closed, Connection, Closed, Connection) => { + vec![ + (wall.clone(), pos), + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) + ] + }, + // hallway vertical + (Connection, Closed, Connection, Closed) => { + vec![ + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) + ] + } + // dead ends + (Connection, Closed, Closed, Closed) => { + vec![ + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), + (round_door.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))), + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) + ] + } + (Closed, Closed, Connection, Closed) => { + vec![ + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), + (round_door.clone(), pos.with_rotation(Quat::from_rotation_y(0.0_f32.to_radians()))), + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) + ] + } + (Closed, Connection, Closed, Closed) => { + vec![ + (wall.clone(), pos), + (round_door.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) + ] + }, + (Closed, Closed, Closed, Connection) => { + vec![ + (wall.clone(), pos), + (round_door.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))), + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) + ] + }, + // T hallways + (Closed, Connection, Connection, Connection) => { + vec![ + (wall.clone(), pos), + (round_hole.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) + ] + }, + (Connection, Closed, Connection, Connection) => { + vec![ + (round_hole.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) + ] + }, + (Connection, Connection, Closed, Connection) => { + vec![ + (round_hole.clone(), pos), + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) + ] + }, + (Connection, Connection, Connection, Closed) => { + vec![ + (wall.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), + (round_hole.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) + ] + }, + // fourway + (Connection, Connection, Connection, Connection) => { + vec![ + (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(0.0_f32.to_radians()))), + (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), + (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))), + (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) + ] + }, + // corners + (Connection, Connection, Closed, Closed) => { + vec![ + (corner_outside.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), + (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), + ] + }, + (Closed, Connection, Connection, Closed) => { + vec![ + (corner_outside.clone(), pos.with_rotation(Quat::from_rotation_y(0.0_f32.to_radians()))), + (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(0.0_f32.to_radians()))), + ] + }, + (Closed, Closed, Connection, Connection) => { + vec![ + (corner_outside.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))), + (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))), + ] + }, + (Connection, Closed, Closed, Connection) => { + vec![ + (corner_outside.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))), + (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))), + ] + } + _ => vec![] } - // dead ends - (Connection, Closed, Closed, Closed) => { - vec![ - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), - (round_door.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))), - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) - ] - } - (Closed, Closed, Connection, Closed) => { - vec![ - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), - (round_door.clone(), pos.with_rotation(Quat::from_rotation_y(0.0_f32.to_radians()))), - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) - ] - } - (Closed, Connection, Closed, Closed) => { - vec![ - (wall.clone(), pos), - (round_door.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) - ] - }, - (Closed, Closed, Closed, Connection) => { - vec![ - (wall.clone(), pos), - (round_door.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))), - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) - ] - }, - // T hallways - (Closed, Connection, Connection, Connection) => { - vec![ - (wall.clone(), pos), - (round_hole.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) - ] - }, - (Connection, Closed, Connection, Connection) => { - vec![ - (round_hole.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) - ] - }, - (Connection, Connection, Closed, Connection) => { - vec![ - (round_hole.clone(), pos), - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) - ] - }, - (Connection, Connection, Connection, Closed) => { - vec![ - (wall.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), - (round_hole.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) - ] - }, - // fourway - (Connection, Connection, Connection, Connection) => { - vec![ - (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(0.0_f32.to_radians()))), - (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), - (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))), - (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) - ] - }, - // corners - (Connection, Connection, Closed, Closed) => { - vec![ - (corner_outside.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), - (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))), - ] - }, - (Closed, Connection, Connection, Closed) => { - vec![ - (corner_outside.clone(), pos.with_rotation(Quat::from_rotation_y(0.0_f32.to_radians()))), - (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(0.0_f32.to_radians()))), - ] - }, - (Closed, Closed, Connection, Connection) => { - vec![ - (corner_outside.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))), - (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))), - ] - }, - (Connection, Closed, Closed, Connection) => { - vec![ - (corner_outside.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))), - (corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))), - ] - } - _ => vec![] + }; + + for ((scene_root, colliders), pos) in values { + commands.spawn(( + RigidBody::Fixed, + scene_root, + pos, + )).with_children(|parent| { + for (collider, transform) in colliders { + parent.spawn((collider, transform)); + } + }); } - }; - - for ((scene_root, colliders), pos) in values { - commands.spawn(( - RigidBody::Fixed, - scene_root, - pos, - )).with_children(|parent| { - for (collider, transform) in colliders { - parent.spawn((collider, transform)); - } - }); } + let (x,z) = map.end_node; + commands.spawn(( + Mesh3d(meshes.add(Cuboid::new(1.0, 20.0, 1.0))), + MeshMaterial3d(materials.add(Color::srgb_u8(255, 0, 0))), + Transform::from_xyz(2.0*x as f32, 0.5, -2.0*z as f32), + )); } - let (x,z) = map.end_node; - commands.spawn(( - Mesh3d(meshes.add(Cuboid::new(1.0, 3.0, 1.0))), - MeshMaterial3d(materials.add(Color::srgb_u8(255, 0, 0))), - Transform::from_xyz(2.0*x as f32, 0.5, -2.0*z as f32), - )); +} + +fn create_maps(n: i32) -> Vec { + let mut maps = Vec::new(); + let mut initial_node = MapNode::new(); + initial_node.east = Side::Closed; + initial_node.south = Side::Closed; + initial_node.west = Side::Closed; + initial_node.north = Side::Connection; + + let pos = (0, 0); + + let map = GameMap::new(pos, initial_node.clone(), 5); + + maps.push(map); + + for _ in 0..n-1 { + let map = maps.last().unwrap(); + let mut pos = map.end_node.clone(); + + let mut next_node = MapNode::new(); + next_node.east = Side::Connection; + next_node.south = Side::Connection; + next_node.west = Side::Connection; + next_node.north = Side::Connection; + + if map.end_node.0 >= map.end_node.1 { + next_node.south = Side::Closed; + next_node.north = Side::Closed; + pos.0 += 1; + } else { + next_node.east = Side::Closed; + next_node.west = Side::Closed; + pos.1 += 1; + } + + initial_node = next_node; + let map = GameMap::new(pos, initial_node.clone(), 5); + maps.push(map); + } + + maps } #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -242,92 +286,34 @@ impl MapNode { struct GameMap { nodes: HashMap<(i32, i32), MapNode>, end_node: (i32, i32), - grid_size: i32 + grid_size: i32, + initial_point: (i32, i32) } impl GameMap { - fn new(initial_point: (i32, i32), grid_size: i32) -> Self { + fn new(initial_point: (i32, i32), node: MapNode, grid_size: i32) -> Self { let mut nodes = HashMap::new(); - let mut start_node = MapNode::new(); - start_node.north = Side::Connection; - start_node.south = Side::Connection; - start_node.east = Side::Connection; - start_node.west = Side::Connection; - nodes.insert(initial_point, start_node); - let mut m = GameMap { nodes, grid_size, end_node: initial_point }; + nodes.insert(initial_point, node); + let mut m = GameMap { initial_point, nodes, grid_size, end_node: initial_point}; m.generate_map(); m } - fn test() -> Self { - let mut nodes = HashMap::new(); - - let mut wall_node0 = MapNode::new(); - wall_node0.north = Side::Connection; - wall_node0.south = Side::Closed; - wall_node0.east = Side::Closed; - wall_node0.west = Side::Closed; - nodes.insert((0, -1), wall_node0); - - - let mut wall_node1 = MapNode::new(); - wall_node1.north = Side::Connection; - wall_node1.south = Side::Connection; - wall_node1.east = Side::Connection; - wall_node1.west = Side::Closed; - nodes.insert((0, 0), wall_node1); - - let mut wall_node2 = MapNode::new(); - wall_node2.north = Side::Connection; - wall_node2.south = Side::Connection; - wall_node2.east = Side::Closed; - wall_node2.west = Side::Connection; - nodes.insert((0, 1), wall_node2); - - let mut corner_node = MapNode::new(); - corner_node.south = Side::Connection; - corner_node.east = Side::Connection; - corner_node.north = Side::Closed; - corner_node.west = Side::Closed; - nodes.insert((0, 2), corner_node); - - let mut wall_node3 = MapNode::new(); - wall_node3.west = Side::Connection; - wall_node3.east = Side::Connection; - wall_node3.north = Side::Closed; - wall_node3.south = Side::Connection; - nodes.insert((1, 2), wall_node3); - - let mut wall_node4 = MapNode::new(); - wall_node4.west = Side::Connection; - wall_node4.east = Side::Connection; - wall_node4.north = Side::Connection; - wall_node4.south = Side::Closed; - nodes.insert((2, 2), wall_node4); - - let mut wall_node5 = MapNode::new(); - wall_node5.west = Side::Connection; - wall_node5.east = Side::Closed; - wall_node5.north = Side::Closed; - wall_node5.south = Side::Connection; - nodes.insert((3, 2), wall_node5); - - GameMap { - nodes, - grid_size: 7, - end_node: (0, 0) - } + fn generate_map(&mut self) { + let mut first_point = self.initial_point.clone(); + first_point.1 += 1; + self.create_node(first_point); // North } - fn generate_map(&mut self) { - self.create_node(&(0, 1)); // North - // self.create_node(&(0, -1)); // South - // self.create_node(&(1, 0)); // East - // self.create_node(&(-1, 0)); // West + fn pos_within_boundaries(&self, pos: (i32, i32)) -> bool { + pos.0 > self.grid_size + self.initial_point.0 + || pos.1 > self.grid_size + self.initial_point.1 + || pos.0 < self.initial_point.0 + || pos.1 < self.initial_point.1 } fn choose_side(&self, pos: (i32, i32)) -> Side { - if pos.0 > self.grid_size || pos.1 > self.grid_size || pos.0 < 0 || pos.1 < 0 { + if self.pos_within_boundaries(pos) { Side::Closed } else { if rand::rng().random_bool(0.5) { Side::Connection } else { Side::Closed } @@ -356,8 +342,8 @@ impl GameMap { } } - fn create_node(&mut self, idx: &(i32, i32)) { - let mut nodes_to_process = vec![*idx]; + fn create_node(&mut self, idx: (i32, i32)) { + let mut nodes_to_process = vec![idx]; while let Some(current_idx) = nodes_to_process.pop() { if self.nodes.contains_key(¤t_idx) { @@ -381,7 +367,7 @@ impl GameMap { new_node.east = east.map_or_else(|| self.choose_side(current_idx), |e| e.west); new_node.west = west.map_or_else(|| self.choose_side(current_idx), |w| w.east); - if !(current_idx.0 > self.grid_size || current_idx.1 > self.grid_size || current_idx.0 < 0 || current_idx.1 < 0) { + if !self.pos_within_boundaries(current_idx) { self.ensure_connection(&mut new_node, current_idx); } if new_node.north == Side::Connection && !self.nodes.contains_key(&(x, y + 1)) {