Merge branch 'main' into toolbar

This commit is contained in:
lorrens
2025-04-06 19:55:57 +02:00
committed by GitHub
3 changed files with 262 additions and 331 deletions

View File

@@ -18,7 +18,14 @@ pub fn map_plugin(app: &mut App) {
);
}
fn spawn_level(mut commands: Commands, models: Res<Assets<Gltf>>, gltf_assets: Res<GltfAssets>) {
fn spawn_level(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
models: Res<Assets<Gltf>>,
gltf_assets: Res<GltfAssets>
) {
println!("LIBRARY: {:?}", gltf_assets.library);
let mesh_names = [
"corner_inside",
@@ -112,226 +119,186 @@ fn spawn_level(mut commands: Commands, models: Res<Assets<Gltf>>, gltf_assets: R
// Transform::from_xyz(-500.0, 3.0, -500.0),
// ));
// let map = GameMap::test();
let map = GameMap::new(100);
map.print_map();
let maps = create_maps(3);
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);
let pos = Transform::from_xyz(2.0*x as f32, 0.0, -2.0*z as f32);
use Side::{Closed, Connection};
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())),
),
(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())),
),
(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())),
),
(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())),
),
(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())),
),
(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())),
),
(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())),
),
(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())),
),
(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())),
),
(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())),
),
(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())),
),
(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())),
),
(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())),
),
(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())),
),
(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())),
),
(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![],
_ => vec![]
}
};
for ((scene_root, colliders), pos) in values {
commands
.spawn((RigidBody::Fixed, scene_root, pos))
.with_children(|parent| {
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),
));
}
}
fn create_maps(n: i32) -> Vec<GameMap> {
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)]
@@ -347,7 +314,6 @@ struct MapNode {
south: Side,
east: Side,
west: Side,
collapsed: bool,
}
impl MapNode {
@@ -357,97 +323,40 @@ 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,
initial_point: (i32, i32)
}
impl GameMap {
fn new(max_nodes: 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((0, 0), start_node);
let mut m = GameMap { nodes, max_nodes };
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,
max_nodes: 7,
}
}
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
let mut first_point = self.initial_point.clone();
first_point.1 += 1;
self.create_node(first_point); // North
}
fn choose_side(&self) -> Side {
if self.nodes.len() > self.max_nodes as usize {
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 self.pos_within_boundaries(pos) {
Side::Closed
} else {
if rand::rng().random_bool(0.5) {
@@ -458,9 +367,30 @@ impl GameMap {
}
}
fn create_node(&mut self, idx: &(i32, i32)) {
let mut nodes_to_process = vec![*idx];
let mut nodes_created = 0;
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 && !self.nodes.contains_key(&(x, y + 1)) {
node.north = 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 && !self.nodes.contains_key(&(x + 1, y)) {
node.east = Side::Connection
}
else if node.west != Side::Connection && !self.nodes.contains_key(&(x - 1, y)) {
node.west = Side::Connection
}
}
}
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(&current_idx) {
@@ -470,16 +400,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 !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)) {
nodes_to_process.push((x, y + 1));
}
@@ -494,7 +431,14 @@ impl GameMap {
}
self.nodes.insert(current_idx, new_node);
nodes_created += 1;
}
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;
}
}
@@ -529,29 +473,6 @@ fn spawn_objects(
gltf_assets: Res<GltfAssets>,
image_assets: Res<ImageAssets>,
) {
// let hammer = gltf_assets
// .library
// .get("meshes/library/hammer.glb")
// .unwrap();
// let hammer = models.get(hammer).unwrap();
// let asset = hammer.default_scene.as_ref().unwrap();
// // hammer
// commands
// .spawn((
// Transform::from_xyz(0.0, 100.0, 0.0).with_scale(Vec3::splat(0.1)),
// Interact,
// RigidBody::Dynamic,
// SceneRoot(asset.clone()),
// ))
// .with_children(|parent| {
// parent
// .spawn(Collider::cuboid(0.8, 10f32, 0.8))
// .insert(Transform::from_xyz(0.0, -5.0, 0.0));
// parent
// .spawn(Collider::cuboid(1.0, 1.0, 4.5))
// .insert(Transform::from_xyz(0.0, 4.2, 1.0));
// });
// id card
let card = models.get(&gltf_assets.card).unwrap();

View File

@@ -20,11 +20,16 @@ fn main() {
level_instantiation::map_plugin,
interaction::plugin,
RapierPhysicsPlugin::<NoUserData>::default(),
RapierDebugRenderPlugin::default(),
// RapierDebugRenderPlugin::default(),
player::plugin,
// debugging::plugin
))
.init_state::<GameState>()
.insert_resource(AmbientLight {
color: Color::srgba(0.8, 0.8, 1.0, 1.0),
// brightness: 10.0,
brightness: 80.0,
})
.add_systems(OnEnter(GameState::Playing), setup)
.run();
}

View File

@@ -1,8 +1,5 @@
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::*;
@@ -132,6 +129,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
@@ -158,10 +163,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()
@@ -408,7 +413,7 @@ pub fn handle_flashlight(
spotlight.intensity = if spotlight.intensity > 0.0 {
0.0
} else {
300_000.0
320_000.0
};
}
}