fix(maze): spawning

This commit is contained in:
Kristofers Solo 2024-12-23 13:39:06 +02:00
parent a76cbdc02b
commit 45511e4d80
3 changed files with 40 additions and 85 deletions

View File

@ -1,5 +1,3 @@
use bevy::prelude::*;
use crate::{ use crate::{
floor::{ floor::{
components::{CurrentFloor, NextFloor}, components::{CurrentFloor, NextFloor},
@ -8,12 +6,13 @@ use crate::{
maze::{components::Maze, GlobalMazeConfig}, maze::{components::Maze, GlobalMazeConfig},
player::components::{MovementSpeed, Player}, player::components::{MovementSpeed, Player},
}; };
use bevy::prelude::*;
pub(super) fn floor_movement( pub(super) fn floor_movement(
mut commands: Commands, mut commands: Commands,
mut maze_transforms: Query<(Entity, &mut Transform), With<Maze>>, mut maze_query: Query<(Entity, &mut Transform), With<Maze>>,
current_floor: Query<Entity, With<CurrentFloor>>, current_query: Query<Entity, With<CurrentFloor>>,
next_floor: Query<Entity, With<NextFloor>>, next_query: Query<Entity, With<NextFloor>>,
player_query: Query<&MovementSpeed, With<Player>>, player_query: Query<&MovementSpeed, With<Player>>,
time: Res<Time>, time: Res<Time>,
global_config: Res<GlobalMazeConfig>, global_config: Res<GlobalMazeConfig>,
@ -23,37 +22,31 @@ pub(super) fn floor_movement(
let movement_distance = speed * time.delta_secs(); let movement_distance = speed * time.delta_secs();
for event in event_reader.read() { for event in event_reader.read() {
let (direction, target_y) = match event { let y_offset = match event {
TransitionFloor::Ascend => (Vec3::Y, -global_config.height), TransitionFloor::Ascend => -global_config.height,
TransitionFloor::Descend => (Vec3::NEG_Y, global_config.height), TransitionFloor::Descend => global_config.height,
}; };
let movement = direction * movement_distance; for (_, mut transforms) in maze_query.iter_mut() {
let target_y = transforms.translation.y + y_offset;
for (_, mut transform) in maze_transforms.iter_mut() { let delta = target_y - transforms.translation.y;
transform.translation += movement; if delta.abs() > 0.001 {
let movement = delta.signum() * movement_distance.min(delta.abs());
transforms.translation.y += movement;
} else {
transforms.translation.y = target_y;
}
} }
let is_movement_complete = maze_transforms // Update current/next floor
.iter() if let (Ok(current_entity), Ok(next_entity)) =
.any(|(_, t)| t.translation.y.abs() >= target_y.abs()); (current_query.get_single(), next_query.get_single())
{
if is_movement_complete { commands.entity(current_entity).remove::<CurrentFloor>();
if let Ok(current_floor_entity) = current_floor.get_single() { commands
commands .entity(next_entity)
.entity(current_floor_entity) .remove::<NextFloor>()
.remove::<CurrentFloor>(); .insert(CurrentFloor);
}
if let Ok(next_floor_entity) = next_floor.get_single() {
if let Ok((entity, mut transform)) = maze_transforms.get_mut(next_floor_entity) {
transform.translation.y = 0.;
commands
.entity(entity)
.remove::<NextFloor>()
.insert(CurrentFloor);
}
}
} }
} }
} }

View File

@ -1,53 +1,6 @@
use crate::{ use crate::maze::events::SpawnMaze;
floor::components::{CurrentFloor, Floor},
maze::{
assets::MazeAssets,
components::Maze,
events::SpawnMaze,
triggers::{
common::generate_maze,
spawn::{spawn_maze_tiles, FLOOR_Y_OFFSET},
},
GlobalMazeConfig,
},
};
use bevy::prelude::*; use bevy::prelude::*;
pub(crate) fn setup( pub(crate) fn setup(mut commands: Commands) {
mut commands: Commands, commands.trigger(SpawnMaze::default());
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
maze_query: Query<(Entity, &Floor, &Maze)>,
global_config: Res<GlobalMazeConfig>,
) {
let SpawnMaze { floor, config } = SpawnMaze::default();
if maze_query.iter().any(|(_, f, _)| f.0 == floor) {
warn!("Floor {} already exists, skipping creation", floor);
return;
}
let maze = generate_maze(&config).expect("Failed to generate maze during spawn");
let y_offset = (floor - 1) * FLOOR_Y_OFFSET;
let entity = commands
.spawn((
Name::new(format!("Floor {}", floor)),
Maze(maze.clone()),
Floor(floor),
CurrentFloor,
config.clone(),
Transform::from_translation(Vec3::ZERO.with_y(y_offset as f32)),
Visibility::Visible,
))
.id();
let assets = MazeAssets::new(&mut meshes, &mut materials, &global_config);
spawn_maze_tiles(
&mut commands,
entity,
&maze,
&assets,
&config,
&global_config,
);
} }

View File

@ -25,12 +25,20 @@ pub(super) fn spawn_maze(
global_config: Res<GlobalMazeConfig>, global_config: Res<GlobalMazeConfig>,
) { ) {
let SpawnMaze { floor, config } = trigger.event(); let SpawnMaze { floor, config } = trigger.event();
if maze_query.iter().any(|(_, f, _)| f.0 == *floor) { if maze_query.iter().any(|(_, f, _)| f.0 == *floor) {
warn!("Floor {} already exists, skipping creation", floor); warn!("Floor {} already exists, skipping creation", floor);
return; return;
} }
let maze = generate_maze(config).expect("Failed to generate maze during spawn"); let maze = match generate_maze(&config) {
Ok(m) => m,
Err(e) => {
error!("Failed to generate maze for floor {floor}: {:?}", e);
return;
}
};
let y_offset = (floor - 1) * FLOOR_Y_OFFSET; let y_offset = (floor - 1) * FLOOR_Y_OFFSET;
let entity = commands let entity = commands
@ -38,11 +46,12 @@ pub(super) fn spawn_maze(
Name::new(format!("Floor {}", floor)), Name::new(format!("Floor {}", floor)),
Maze(maze.clone()), Maze(maze.clone()),
Floor(*floor), Floor(*floor),
NextFloor,
config.clone(), config.clone(),
Transform::from_translation(Vec3::ZERO.with_y(y_offset as f32)), Transform::from_translation(Vec3::ZERO.with_y(y_offset as f32)),
Visibility::Visible, Visibility::Visible,
)) ))
.insert_if(CurrentFloor, || *floor == 1)
.insert_if(NextFloor, || *floor != 1)
.id(); .id();
let assets = MazeAssets::new(&mut meshes, &mut materials, &global_config); let assets = MazeAssets::new(&mut meshes, &mut materials, &global_config);
@ -51,7 +60,7 @@ pub(super) fn spawn_maze(
entity, entity,
&maze, &maze,
&assets, &assets,
config, &config,
&global_config, &global_config,
); );
} }