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)) {