key cards

This commit is contained in:
LorrensP-2158466
2025-04-06 20:45:16 +02:00
parent dfd14abab8
commit afa4c37729

View File

@@ -2,7 +2,7 @@ use std::collections::HashMap;
use bevy::prelude::*; use bevy::prelude::*;
use bevy_rapier3d::prelude::*; use bevy_rapier3d::prelude::*;
use rand::Rng; use rand::{Rng, seq::IteratorRandom};
use crate::{ use crate::{
GameState, GameState,
@@ -18,13 +18,12 @@ pub fn map_plugin(app: &mut App) {
); );
} }
fn spawn_level( fn spawn_level(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
models: Res<Assets<Gltf>>, models: Res<Assets<Gltf>>,
gltf_assets: Res<GltfAssets> gltf_assets: Res<GltfAssets>,
) { ) {
println!("LIBRARY: {:?}", gltf_assets.library); println!("LIBRARY: {:?}", gltf_assets.library);
let mesh_names = [ let mesh_names = [
@@ -129,120 +128,211 @@ fn spawn_level(
let node = node.clone(); let node = node.clone();
let pos = Transform::from_xyz(2.0 * (*x) as f32, 0.0, -2.0 * (*z) as f32); let pos = Transform::from_xyz(2.0 * (*x) as f32, 0.0, -2.0 * (*z) as f32);
use Side::{Connection, Closed}; use Side::{Closed, Connection};
match (node.north, node.east, node.south, node.west) { match (node.north, node.east, node.south, node.west) {
// hallway horizontal // hallway horizontal
(Closed, Connection, Closed, Connection) => { (Closed, Connection, Closed, Connection) => {
vec![ vec![
(wall.clone(), pos), (wall.clone(), pos),
(wall.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) (
wall.clone(),
pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians())),
),
] ]
}, }
// hallway vertical // hallway vertical
(Connection, Closed, Connection, Closed) => { (Connection, Closed, Connection, Closed) => {
vec![ 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()))) 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 // dead ends
(Connection, Closed, Closed, Closed) => { (Connection, Closed, Closed, Closed) => {
vec![ 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(),
(wall.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) 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) => { (Closed, Closed, Connection, Closed) => {
vec![ 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(),
(wall.clone(), pos.with_rotation(Quat::from_rotation_y(270.0_f32.to_radians()))) 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) => { (Closed, Connection, Closed, Closed) => {
vec![ vec![
(wall.clone(), pos), (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()))) 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) => { (Closed, Closed, Closed, Connection) => {
vec![ vec![
(wall.clone(), pos), (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()))) 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 // T hallways
(Closed, Connection, Connection, Connection) => { (Closed, Connection, Connection, Connection) => {
vec![ vec![
(wall.clone(), pos), (wall.clone(), pos),
(round_hole.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) (
round_hole.clone(),
pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians())),
),
] ]
}, }
(Connection, Closed, Connection, Connection) => { (Connection, Closed, Connection, Connection) => {
vec![ 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()))) 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) => { (Connection, Connection, Closed, Connection) => {
vec![ vec![
(round_hole.clone(), pos), (round_hole.clone(), pos),
(wall.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))) (
wall.clone(),
pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians())),
),
] ]
}, }
(Connection, Connection, Connection, Closed) => { (Connection, Connection, Connection, Closed) => {
vec![ 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()))) 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 // fourway
(Connection, Connection, Connection, Connection) => { (Connection, Connection, Connection, Connection) => {
vec![ 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(),
(corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(180.0_f32.to_radians()))), pos.with_rotation(Quat::from_rotation_y(0.0_f32.to_radians())),
(corner_inside.clone(), pos.with_rotation(Quat::from_rotation_y(270.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 // corners
(Connection, Connection, Closed, Closed) => { (Connection, Connection, Closed, Closed) => {
vec![ 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()))), corner_outside.clone(),
] pos.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians())),
}, ),
(Closed, Connection, Connection, Closed) => { (
vec![ corner_inside.clone(),
(corner_outside.clone(), pos.with_rotation(Quat::from_rotation_y(0.0_f32.to_radians()))), pos.with_rotation(Quat::from_rotation_y(90.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![] (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 { for ((scene_root, colliders), pos) in values {
commands.spawn(( commands
RigidBody::Fixed, .spawn((RigidBody::Fixed, scene_root, pos))
scene_root, .with_children(|parent| {
pos,
)).with_children(|parent| {
for (collider, transform) in colliders { for (collider, transform) in colliders {
parent.spawn((collider, transform)); parent.spawn((collider, transform));
} }
@@ -259,7 +349,6 @@ fn spawn_level(
commands.insert_resource(GameLevels { levels }); commands.insert_resource(GameLevels { levels });
} }
fn create_levels(n: i32) -> Vec<GameLevel> { fn create_levels(n: i32) -> Vec<GameLevel> {
let mut maps = Vec::new(); let mut maps = Vec::new();
let mut initial_node = LevelNode::new(); let mut initial_node = LevelNode::new();
@@ -330,21 +419,26 @@ impl LevelNode {
#[derive(Resource)] #[derive(Resource)]
struct GameLevels { struct GameLevels {
pub levels: Vec<GameLevel> pub levels: Vec<GameLevel>,
} }
struct GameLevel { struct GameLevel {
nodes: HashMap<(i32, i32), LevelNode>, nodes: HashMap<(i32, i32), LevelNode>,
end_node: (i32, i32), end_node: (i32, i32),
grid_size: i32, grid_size: i32,
initial_point: (i32, i32) initial_point: (i32, i32),
} }
impl GameLevel { impl GameLevel {
fn new(initial_point: (i32, i32), node: LevelNode, grid_size: i32) -> Self { fn new(initial_point: (i32, i32), node: LevelNode, grid_size: i32) -> Self {
let mut nodes = HashMap::new(); let mut nodes = HashMap::new();
nodes.insert(initial_point, node); nodes.insert(initial_point, node);
let mut m = GameLevel { initial_point, nodes, grid_size, end_node: initial_point}; let mut m = GameLevel {
initial_point,
nodes,
grid_size,
end_node: initial_point,
};
m.generate_map(); m.generate_map();
m m
} }
@@ -374,22 +468,19 @@ impl GameLevel {
} }
fn ensure_connection(&self, node: &mut LevelNode, (x, y): (i32, i32)) { fn ensure_connection(&self, node: &mut LevelNode, (x, y): (i32, i32)) {
let am_connections = (node.north == Side::Connection) as u8 + let am_connections = (node.north == Side::Connection) as u8
(node.south == Side::Connection) as u8 + + (node.south == Side::Connection) as u8
(node.east == Side::Connection) as u8 + + (node.east == Side::Connection) as u8
(node.west == Side::Connection) as u8; + (node.west == Side::Connection) as u8;
if am_connections <= 2 { if am_connections <= 2 {
if node.north != Side::Connection && !self.nodes.contains_key(&(x, y + 1)) { if node.north != Side::Connection && !self.nodes.contains_key(&(x, y + 1)) {
node.north = Side::Connection node.north = Side::Connection
} } else if node.south != Side::Connection && !self.nodes.contains_key(&(x, y - 1)) {
else if node.south != Side::Connection && !self.nodes.contains_key(&(x, y - 1)) {
node.south = Side::Connection node.south = Side::Connection
} } else if node.east != Side::Connection && !self.nodes.contains_key(&(x + 1, y)) {
else if node.east != Side::Connection && !self.nodes.contains_key(&(x + 1, y)) {
node.east = Side::Connection node.east = Side::Connection
} } else if node.west != Side::Connection && !self.nodes.contains_key(&(x - 1, y)) {
else if node.west != Side::Connection && !self.nodes.contains_key(&(x - 1, y)) {
node.west = Side::Connection node.west = Side::Connection
} }
} }
@@ -442,8 +533,7 @@ impl GameLevel {
let end_node = self.nodes.get_mut(&self.end_node).unwrap(); let end_node = self.nodes.get_mut(&self.end_node).unwrap();
if self.end_node.1 >= self.end_node.0 { if self.end_node.1 >= self.end_node.0 {
end_node.north = Side::Connection; end_node.north = Side::Connection;
} } else if self.end_node.0 >= self.end_node.1 {
else if self.end_node.0 >= self.end_node.1 {
end_node.east = Side::Connection; end_node.east = Side::Connection;
} }
} }
@@ -475,6 +565,7 @@ impl GameLevel {
fn spawn_objects( fn spawn_objects(
mut commands: Commands, mut commands: Commands,
levels: Res<GameLevels>,
models: Res<Assets<Gltf>>, models: Res<Assets<Gltf>>,
gltf_assets: Res<GltfAssets>, gltf_assets: Res<GltfAssets>,
image_assets: Res<ImageAssets>, image_assets: Res<ImageAssets>,
@@ -483,12 +574,29 @@ fn spawn_objects(
let card = models.get(&gltf_assets.card).unwrap(); let card = models.get(&gltf_assets.card).unwrap();
let asset = card.default_scene.as_ref().unwrap(); let asset = card.default_scene.as_ref().unwrap();
for (i, level) in levels.levels.iter().enumerate() {
let begin_node = level.initial_point;
let end_node = level.end_node;
// take a random position that is not the beginning or end_node
let (x, z) = loop {
let positions = level.nodes.keys();
let random_pos = positions.choose(&mut rand::rng()).unwrap().clone();
if random_pos != begin_node && random_pos != end_node {
break random_pos;
}
};
let transform = if x <= z {
Transform::from_xyz(2.0 * x as f32, 0.5, -2.0 * z as f32)
.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians()))
} else {
Transform::from_xyz(2.0 * x as f32, 0.5, -2.0 * z as f32)
};
commands commands
.spawn(( .spawn((
Transform::from_xyz(0.0, 2.0, 2.0), transform,
Interact, Interact,
RigidBody::Dynamic, RigidBody::Dynamic,
Name::new("Id Card 1"), Name::new(format!("Id Card {i}")),
Visibility::Visible, Visibility::Visible,
ItemIcon::new(image_assets.id_card.clone()), ItemIcon::new(image_assets.id_card.clone()),
SceneRoot(asset.clone()), SceneRoot(asset.clone()),
@@ -512,53 +620,48 @@ fn spawn_objects(
)); ));
}); });
} }
}
fn spawn_doors( fn spawn_doors(
mut commands: Commands, mut commands: Commands,
levels: Res<GameLevels>, levels: Res<GameLevels>,
models: Res<Assets<Gltf>>, models: Res<Assets<Gltf>>,
gltf_assets: Res<GltfAssets> gltf_assets: Res<GltfAssets>,
) { ) {
let collider: Vec<(Collider, Transform)> = vec![( let collider: Vec<(Collider, Transform)> = vec![(
Collider::cuboid(1.0, 1.0, 0.1), Collider::cuboid(1.0, 1.0, 0.1),
Transform::from_xyz(0.0, 1.0, -1.0), Transform::from_xyz(0.0, 1.0, -1.0),
)]; )];
let path = format!("meshes/library/space_round_door.glb",); let path = format!("meshes/library/space_round_door.glb",);
let handle = gltf_assets let handle = gltf_assets.library.get(&path).unwrap();
.library let gltf = models.get(handle).unwrap();
.get(&path)
.unwrap();
let gltf = models
.get(handle)
.unwrap();
let asset = gltf let asset = gltf.default_scene.as_ref().unwrap();
.default_scene
.as_ref()
.unwrap();
let scene_root = SceneRoot(asset.clone()); let scene_root = SceneRoot(asset.clone());
for level in levels.levels.iter() { for level in levels.levels.iter() {
let (x, z) = level.end_node; let (x, z) = level.end_node;
if x <= z { if x <= z {
commands.spawn(( commands
.spawn((
RigidBody::Fixed, RigidBody::Fixed,
Transform::from_xyz(2.0 * x as f32, 0.0, -2.0 * z as f32) Transform::from_xyz(2.0 * x as f32, 0.0, -2.0 * z as f32)
.with_rotation(Quat::from_rotation_y(90.0_f32.to_radians())), .with_rotation(Quat::from_rotation_y(90.0_f32.to_radians())),
scene_root.clone(), scene_root.clone(),
)).with_children(|parent| { ))
.with_children(|parent| {
for (collider, transform) in collider.clone() { for (collider, transform) in collider.clone() {
parent.spawn((collider, transform)); parent.spawn((collider, transform));
} }
}); });
} else { } else {
commands.spawn(( commands
.spawn((
RigidBody::Dynamic, RigidBody::Dynamic,
Transform::from_xyz(2.0 * x as f32, 0.0, -2.0 * z as f32), Transform::from_xyz(2.0 * x as f32, 0.0, -2.0 * z as f32),
scene_root.clone(), scene_root.clone(),
)).with_children(|parent| { ))
.with_children(|parent| {
for (collider, transform) in collider.clone() { for (collider, transform) in collider.clone() {
parent.spawn((collider, transform)); parent.spawn((collider, transform));
} }