mirror of
https://github.com/kristoferssolo/maze-ascension.git
synced 2025-10-21 19:20:34 +00:00
refactor: move to [observer](https://bevyengine.org/examples/ecs-entity-component-system/observers/) based systems
This commit is contained in:
parent
e65790c743
commit
cec07c9069
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -3083,7 +3083,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "maze-ascension"
|
||||
version = "0.2.0"
|
||||
version = "0.2.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bevy",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "maze-ascension"
|
||||
authors = ["Kristofers Solo <dev@kristofers.xyz>"]
|
||||
version = "0.2.0"
|
||||
version = "0.2.2"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
floor::components::{CurrentFloor, Floor},
|
||||
maze::{components::MazeConfig, events::MazeEvent, GlobalMazeConfig, MazePluginLoaded},
|
||||
player::events::PlayerEvent,
|
||||
maze::{components::MazeConfig, events::RespawnMaze, GlobalMazeConfig, MazePluginLoaded},
|
||||
player::events::RespawnPlayer,
|
||||
};
|
||||
use bevy::{prelude::*, window::PrimaryWindow};
|
||||
use bevy_egui::{
|
||||
@ -58,16 +58,11 @@ pub(crate) fn maze_controls_ui(world: &mut World) {
|
||||
// Handle updates
|
||||
if changed {
|
||||
maze_config.update(&global_config);
|
||||
|
||||
if let Some(mut event_writer) = world.get_resource_mut::<Events<MazeEvent>>() {
|
||||
event_writer.send(MazeEvent::Recreate {
|
||||
floor: floor_value,
|
||||
config: maze_config,
|
||||
});
|
||||
}
|
||||
if let Some(mut event_writer) = world.get_resource_mut::<Events<PlayerEvent>>() {
|
||||
event_writer.send(PlayerEvent::Respawn);
|
||||
}
|
||||
world.trigger(RespawnMaze {
|
||||
floor: floor_value,
|
||||
config: maze_config,
|
||||
});
|
||||
world.trigger(RespawnPlayer);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
20
src/floor/events.rs
Normal file
20
src/floor/events.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::maze::components::MazeConfig;
|
||||
|
||||
#[derive(Debug, Reflect, Event)]
|
||||
pub struct SpawnFloor {
|
||||
pub floor: u8,
|
||||
pub config: MazeConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Reflect, Event)]
|
||||
pub struct RespawnFloor {
|
||||
pub floor: u8,
|
||||
pub config: MazeConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Reflect, Event)]
|
||||
pub struct DespawnFloor {
|
||||
pub floor: u8,
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
pub mod components;
|
||||
pub mod events;
|
||||
mod systems;
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {}
|
||||
pub(super) fn plugin(_app: &mut App) {}
|
||||
|
||||
@ -1 +1 @@
|
||||
mod spawn;
|
||||
|
||||
|
||||
@ -62,6 +62,7 @@ impl Plugin for AppPlugin {
|
||||
screens::plugin,
|
||||
theme::plugin,
|
||||
maze::plugin,
|
||||
floor::plugin,
|
||||
player::plugin,
|
||||
));
|
||||
|
||||
|
||||
@ -2,9 +2,19 @@ use bevy::prelude::*;
|
||||
|
||||
use super::components::MazeConfig;
|
||||
|
||||
#[derive(Debug, Event)]
|
||||
pub enum MazeEvent {
|
||||
Create { floor: u8, config: MazeConfig },
|
||||
Recreate { floor: u8, config: MazeConfig },
|
||||
Remove { floor: u8 },
|
||||
#[derive(Debug, Reflect, Event)]
|
||||
pub struct SpawnMaze {
|
||||
pub floor: u8,
|
||||
pub config: MazeConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Reflect, Event)]
|
||||
pub struct RespawnMaze {
|
||||
pub floor: u8,
|
||||
pub config: MazeConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Reflect, Event)]
|
||||
pub struct DespawnMaze {
|
||||
pub floor: u8,
|
||||
}
|
||||
|
||||
@ -4,17 +4,20 @@ pub mod errors;
|
||||
pub mod events;
|
||||
pub mod resources;
|
||||
mod systems;
|
||||
mod triggers;
|
||||
|
||||
use bevy::{ecs::system::RunSystemOnce, prelude::*};
|
||||
use components::Maze;
|
||||
use events::MazeEvent;
|
||||
use events::{DespawnMaze, RespawnMaze, SpawnMaze};
|
||||
pub use resources::{GlobalMazeConfig, MazePluginLoaded};
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.init_resource::<GlobalMazeConfig>()
|
||||
.add_event::<MazeEvent>()
|
||||
.add_event::<SpawnMaze>()
|
||||
.add_event::<RespawnMaze>()
|
||||
.add_event::<DespawnMaze>()
|
||||
.register_type::<Maze>()
|
||||
.add_plugins(systems::plugin);
|
||||
.add_plugins((systems::plugin, triggers::plugin));
|
||||
}
|
||||
|
||||
pub fn spawn_level_command(world: &mut World) {
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
use super::{spawn::spawn_floor, update::update_floor};
|
||||
use crate::{
|
||||
floor::components::Floor,
|
||||
maze::{components::Maze, events::MazeEvent, GlobalMazeConfig},
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(crate) fn handle_maze_events(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
mut event_reader: EventReader<MazeEvent>,
|
||||
mut maze_query: Query<(Entity, &Floor, &mut Maze)>,
|
||||
global_config: Res<GlobalMazeConfig>,
|
||||
) {
|
||||
for event in event_reader.read() {
|
||||
match event {
|
||||
MazeEvent::Create { floor, config } => {
|
||||
if maze_query.iter().any(|(_, f, _)| f.0 == *floor) {
|
||||
warn!("Floor {} already exists, skipping creation", floor);
|
||||
continue;
|
||||
}
|
||||
spawn_floor(
|
||||
&mut commands,
|
||||
&mut meshes,
|
||||
&mut materials,
|
||||
*floor,
|
||||
config,
|
||||
&global_config,
|
||||
);
|
||||
}
|
||||
MazeEvent::Recreate { floor, config } => {
|
||||
let result = update_floor(
|
||||
&mut commands,
|
||||
&mut meshes,
|
||||
&mut materials,
|
||||
&mut maze_query,
|
||||
*floor,
|
||||
config,
|
||||
&global_config,
|
||||
);
|
||||
if let Err(e) = result {
|
||||
warn!("Failed to update floor {}: {}", floor, e);
|
||||
}
|
||||
}
|
||||
MazeEvent::Remove { floor } => {
|
||||
match maze_query.iter().find(|(_, f, _)| f.0 == *floor) {
|
||||
Some((entity, _, _)) => commands.entity(entity).despawn_recursive(),
|
||||
_ => warn!("Floor {} not found for removal", floor),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,5 @@
|
||||
pub mod common;
|
||||
pub mod event_handler;
|
||||
pub mod setup;
|
||||
pub mod spawn;
|
||||
pub mod update;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use event_handler::handle_maze_events;
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_systems(Update, handle_maze_events);
|
||||
}
|
||||
pub(super) fn plugin(_app: &mut App) {}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::maze::{components::MazeConfig, events::MazeEvent};
|
||||
use crate::maze::{components::MazeConfig, events::SpawnMaze};
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(crate) fn setup(mut event_writer: EventWriter<MazeEvent>) {
|
||||
pub(crate) fn setup(mut commands: Commands) {
|
||||
let config = MazeConfig::default();
|
||||
event_writer.send(MazeEvent::Create { floor: 1, config });
|
||||
commands.trigger(SpawnMaze { floor: 1, config });
|
||||
}
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
use super::{common::generate_maze, spawn::spawn_maze_tiles};
|
||||
use crate::{
|
||||
floor::components::Floor,
|
||||
maze::{
|
||||
assets::MazeAssets,
|
||||
components::{Maze, MazeConfig},
|
||||
errors::{MazeError, MazeResult},
|
||||
GlobalMazeConfig,
|
||||
},
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(super) fn update_floor(
|
||||
commands: &mut Commands,
|
||||
meshes: &mut ResMut<Assets<Mesh>>,
|
||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
maze_query: &mut Query<(Entity, &Floor, &mut Maze)>,
|
||||
floor: u8,
|
||||
maze_config: &MazeConfig,
|
||||
global_config: &GlobalMazeConfig,
|
||||
) -> MazeResult<()> {
|
||||
let (entity, _, mut maze) = maze_query
|
||||
.iter_mut()
|
||||
.find(|(_, f, _)| f.0 == floor)
|
||||
.ok_or(MazeError::FloorNotFound(floor))?;
|
||||
|
||||
maze.0 = generate_maze(maze_config)?;
|
||||
|
||||
commands.entity(entity).despawn_descendants();
|
||||
let assets = MazeAssets::new(meshes, materials, global_config);
|
||||
spawn_maze_tiles(
|
||||
commands,
|
||||
entity,
|
||||
&maze.0,
|
||||
&assets,
|
||||
maze_config,
|
||||
global_config,
|
||||
);
|
||||
|
||||
commands.entity(entity).insert(maze_config.clone());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -4,7 +4,7 @@ use crate::maze::{
|
||||
};
|
||||
use hexlab::{GeneratorType, HexMaze, MazeBuilder};
|
||||
|
||||
pub(super) fn generate_maze(config: &MazeConfig) -> MazeResult<HexMaze> {
|
||||
pub(crate) fn generate_maze(config: &MazeConfig) -> MazeResult<HexMaze> {
|
||||
MazeBuilder::new()
|
||||
.with_radius(config.radius)
|
||||
.with_seed(config.seed)
|
||||
14
src/maze/triggers/despawn.rs
Normal file
14
src/maze/triggers/despawn.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use crate::{floor::components::Floor, maze::events::DespawnMaze};
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(super) fn despawn_maze(
|
||||
trigger: Trigger<DespawnMaze>,
|
||||
mut commands: Commands,
|
||||
query: Query<(Entity, &Floor)>,
|
||||
) {
|
||||
let DespawnMaze { floor } = trigger.event();
|
||||
match query.iter().find(|(_, f)| f.0 == *floor) {
|
||||
Some((entity, _)) => commands.entity(entity).despawn_recursive(),
|
||||
_ => warn!("Floor {} not found for removal", floor),
|
||||
}
|
||||
}
|
||||
15
src/maze/triggers/mod.rs
Normal file
15
src/maze/triggers/mod.rs
Normal file
@ -0,0 +1,15 @@
|
||||
pub mod common;
|
||||
mod despawn;
|
||||
mod respawn;
|
||||
mod spawn;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use despawn::despawn_maze;
|
||||
use respawn::respawn_maze;
|
||||
use spawn::spawn_maze;
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_observer(spawn_maze)
|
||||
.add_observer(respawn_maze)
|
||||
.add_observer(despawn_maze);
|
||||
}
|
||||
53
src/maze/triggers/respawn.rs
Normal file
53
src/maze/triggers/respawn.rs
Normal file
@ -0,0 +1,53 @@
|
||||
use super::{common::generate_maze, spawn::spawn_maze_tiles};
|
||||
use crate::{
|
||||
floor::components::Floor,
|
||||
maze::{
|
||||
assets::MazeAssets, components::Maze, errors::MazeError, events::RespawnMaze,
|
||||
GlobalMazeConfig,
|
||||
},
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(super) fn respawn_maze(
|
||||
trigger: Trigger<RespawnMaze>,
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
mut maze_query: Query<(Entity, &Floor, &mut Maze)>,
|
||||
global_config: Res<GlobalMazeConfig>,
|
||||
) {
|
||||
let RespawnMaze { floor, config } = trigger.event();
|
||||
|
||||
let (entity, _, mut maze) = match maze_query
|
||||
.iter_mut()
|
||||
.find(|(_, f, _)| f.0 == *floor)
|
||||
.ok_or(MazeError::FloorNotFound(*floor))
|
||||
{
|
||||
Ok((entity, floor, maze)) => (entity, floor, maze),
|
||||
Err(e) => {
|
||||
warn!("Failed to update floor ({floor}). {e}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
maze.0 = match generate_maze(config) {
|
||||
Ok(generated_maze) => generated_maze,
|
||||
Err(e) => {
|
||||
warn!("Failed to update floor ({floor}). {e}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
commands.entity(entity).despawn_descendants();
|
||||
let assets = MazeAssets::new(&mut meshes, &mut materials, &global_config);
|
||||
spawn_maze_tiles(
|
||||
&mut commands,
|
||||
entity,
|
||||
&maze.0,
|
||||
&assets,
|
||||
config,
|
||||
&global_config,
|
||||
);
|
||||
|
||||
commands.entity(entity).insert(config.clone());
|
||||
}
|
||||
@ -3,6 +3,7 @@ use crate::{
|
||||
maze::{
|
||||
assets::MazeAssets,
|
||||
components::{Maze, MazeConfig, Tile, Wall},
|
||||
events::SpawnMaze,
|
||||
resources::GlobalMazeConfig,
|
||||
},
|
||||
};
|
||||
@ -13,30 +14,43 @@ use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6};
|
||||
|
||||
use super::common::generate_maze;
|
||||
|
||||
pub(super) fn spawn_floor(
|
||||
commands: &mut Commands,
|
||||
meshes: &mut ResMut<Assets<Mesh>>,
|
||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
floor: u8,
|
||||
maze_config: &MazeConfig,
|
||||
global_config: &GlobalMazeConfig,
|
||||
pub(super) fn spawn_maze(
|
||||
trigger: Trigger<SpawnMaze>,
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
maze_query: Query<(Entity, &Floor, &Maze)>,
|
||||
global_config: Res<GlobalMazeConfig>,
|
||||
) {
|
||||
let maze = generate_maze(maze_config).expect("Failed to generate maze during spawn");
|
||||
let SpawnMaze { floor, config } = trigger.event();
|
||||
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 entity = commands
|
||||
.spawn((
|
||||
Name::new(format!("Floor {}", floor)),
|
||||
Maze(maze.clone()),
|
||||
Floor(floor),
|
||||
Floor(*floor),
|
||||
CurrentFloor, // TODO: remove
|
||||
maze_config.clone(),
|
||||
config.clone(),
|
||||
Transform::from_translation(Vec3::ZERO),
|
||||
Visibility::Visible,
|
||||
))
|
||||
.id();
|
||||
|
||||
let assets = MazeAssets::new(meshes, materials, global_config);
|
||||
spawn_maze_tiles(commands, entity, &maze, &assets, maze_config, global_config);
|
||||
let assets = MazeAssets::new(&mut meshes, &mut materials, &global_config);
|
||||
spawn_maze_tiles(
|
||||
&mut commands,
|
||||
entity,
|
||||
&maze,
|
||||
&assets,
|
||||
config,
|
||||
&global_config,
|
||||
);
|
||||
}
|
||||
|
||||
pub(super) fn spawn_maze_tiles(
|
||||
@ -1,8 +1,10 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
#[derive(Debug, Event)]
|
||||
pub enum PlayerEvent {
|
||||
Spawn,
|
||||
Respawn,
|
||||
Despawn,
|
||||
}
|
||||
pub struct SpawnPlayer;
|
||||
|
||||
#[derive(Debug, Event)]
|
||||
pub struct RespawnPlayer;
|
||||
|
||||
#[derive(Debug, Event)]
|
||||
pub struct DespawnPlayer;
|
||||
|
||||
@ -2,15 +2,18 @@ mod assets;
|
||||
pub mod components;
|
||||
pub mod events;
|
||||
mod systems;
|
||||
mod triggers;
|
||||
|
||||
use bevy::{ecs::system::RunSystemOnce, prelude::*};
|
||||
use components::Player;
|
||||
use events::PlayerEvent;
|
||||
use events::{DespawnPlayer, RespawnPlayer, SpawnPlayer};
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.register_type::<Player>()
|
||||
.add_event::<PlayerEvent>()
|
||||
.add_plugins(systems::plugin);
|
||||
.add_event::<SpawnPlayer>()
|
||||
.add_event::<RespawnPlayer>()
|
||||
.add_event::<DespawnPlayer>()
|
||||
.add_plugins((triggers::plugin, systems::plugin));
|
||||
}
|
||||
|
||||
pub fn spawn_player_command(world: &mut World) {
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::player::components::Player;
|
||||
|
||||
pub(super) fn despawn_players(commands: &mut Commands, query: &Query<Entity, With<Player>>) {
|
||||
for entity in query.iter() {
|
||||
commands.entity(entity).despawn_recursive();
|
||||
}
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
use crate::{
|
||||
floor::components::CurrentFloor,
|
||||
maze::{components::MazeConfig, GlobalMazeConfig},
|
||||
player::{components::Player, events::PlayerEvent},
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
|
||||
use super::{despawn::despawn_players, respawn::respawn_player, spawn::spawn_player};
|
||||
|
||||
pub(crate) fn handle_player_events(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
mut event_reader: EventReader<PlayerEvent>,
|
||||
maze_config_query: Query<&MazeConfig, With<CurrentFloor>>,
|
||||
player_query: Query<Entity, With<Player>>,
|
||||
global_config: Res<GlobalMazeConfig>,
|
||||
) {
|
||||
for event in event_reader.read() {
|
||||
match event {
|
||||
PlayerEvent::Spawn => {
|
||||
let Ok(maze_config) = maze_config_query.get_single() else {
|
||||
warn!(
|
||||
"Failed to get maze configuration for current floor - cannot spawn player"
|
||||
);
|
||||
return;
|
||||
};
|
||||
spawn_player(
|
||||
&mut commands,
|
||||
&mut meshes,
|
||||
&mut materials,
|
||||
maze_config,
|
||||
&global_config,
|
||||
);
|
||||
}
|
||||
PlayerEvent::Respawn => {
|
||||
let Ok(maze_config) = maze_config_query.get_single() else {
|
||||
warn!("Failed to get maze configuration for current floor - cannot respawn player");
|
||||
return;
|
||||
};
|
||||
respawn_player(
|
||||
&mut commands,
|
||||
&mut meshes,
|
||||
&mut materials,
|
||||
&player_query,
|
||||
maze_config,
|
||||
&global_config,
|
||||
);
|
||||
}
|
||||
PlayerEvent::Despawn => despawn_players(&mut commands, &player_query),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,23 +1,18 @@
|
||||
mod despawn;
|
||||
mod event_handler;
|
||||
mod input;
|
||||
mod movement;
|
||||
mod respawn;
|
||||
pub mod setup;
|
||||
mod spawn;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use event_handler::handle_player_events;
|
||||
use input::player_input;
|
||||
use movement::player_movement;
|
||||
|
||||
use crate::maze::MazePluginLoaded;
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_systems(
|
||||
Update,
|
||||
(
|
||||
player_input,
|
||||
player_movement.after(player_input),
|
||||
handle_player_events,
|
||||
),
|
||||
(player_input, player_movement)
|
||||
.chain()
|
||||
.run_if(resource_exists::<MazePluginLoaded>),
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
use super::{despawn::despawn_players, spawn::spawn_player};
|
||||
use crate::{
|
||||
maze::{components::MazeConfig, GlobalMazeConfig},
|
||||
player::components::Player,
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(super) fn respawn_player(
|
||||
commands: &mut Commands,
|
||||
meshes: &mut ResMut<Assets<Mesh>>,
|
||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
query: &Query<Entity, With<Player>>,
|
||||
maze_config: &MazeConfig,
|
||||
global_config: &GlobalMazeConfig,
|
||||
) {
|
||||
despawn_players(commands, query);
|
||||
spawn_player(commands, meshes, materials, maze_config, global_config);
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::player::events::PlayerEvent;
|
||||
use crate::player::events::SpawnPlayer;
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(crate) fn setup(mut event_writer: EventWriter<PlayerEvent>) {
|
||||
event_writer.send(PlayerEvent::Spawn);
|
||||
pub(crate) fn setup(mut commands: Commands) {
|
||||
commands.trigger(SpawnPlayer);
|
||||
}
|
||||
|
||||
12
src/player/triggers/despawn.rs
Normal file
12
src/player/triggers/despawn.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::player::{components::Player, events::DespawnPlayer};
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(super) fn despawn_players(
|
||||
_trigger: Trigger<DespawnPlayer>,
|
||||
mut commands: Commands,
|
||||
query: Query<Entity, With<Player>>,
|
||||
) {
|
||||
for entity in query.iter() {
|
||||
commands.entity(entity).despawn_recursive();
|
||||
}
|
||||
}
|
||||
14
src/player/triggers/mod.rs
Normal file
14
src/player/triggers/mod.rs
Normal file
@ -0,0 +1,14 @@
|
||||
mod despawn;
|
||||
mod respawn;
|
||||
mod spawn;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use despawn::despawn_players;
|
||||
use respawn::respawn_player;
|
||||
use spawn::spawn_player;
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_observer(spawn_player)
|
||||
.add_observer(respawn_player)
|
||||
.add_observer(despawn_players);
|
||||
}
|
||||
7
src/player/triggers/respawn.rs
Normal file
7
src/player/triggers/respawn.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::player::events::{DespawnPlayer, RespawnPlayer, SpawnPlayer};
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(super) fn respawn_player(_trigger: Trigger<RespawnPlayer>, mut commands: Commands) {
|
||||
commands.trigger(DespawnPlayer);
|
||||
commands.trigger(SpawnPlayer);
|
||||
}
|
||||
@ -1,19 +1,25 @@
|
||||
use crate::{
|
||||
floor::components::CurrentFloor,
|
||||
maze::{components::MazeConfig, GlobalMazeConfig},
|
||||
player::{
|
||||
assets::{blue_material, generate_pill_mesh},
|
||||
components::{CurrentPosition, Player},
|
||||
events::SpawnPlayer,
|
||||
},
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(super) fn spawn_player(
|
||||
commands: &mut Commands,
|
||||
meshes: &mut ResMut<Assets<Mesh>>,
|
||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
maze_config: &MazeConfig,
|
||||
global_config: &GlobalMazeConfig,
|
||||
_trigger: Trigger<SpawnPlayer>,
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
maze_config_query: Query<&MazeConfig, With<CurrentFloor>>,
|
||||
global_config: Res<GlobalMazeConfig>,
|
||||
) {
|
||||
let Ok(maze_config) = maze_config_query.get_single() else {
|
||||
return;
|
||||
};
|
||||
let player_radius = global_config.hex_size * 0.5;
|
||||
let player_height = player_radius * 3.5;
|
||||
|
||||
@ -9,10 +9,7 @@ use crate::{asset_tracking::LoadResource, audio::Music, screens::Screen};
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_systems(
|
||||
OnEnter(Screen::Gameplay),
|
||||
(
|
||||
spawn_level_command,
|
||||
spawn_player_command.after(spawn_level_command),
|
||||
),
|
||||
(spawn_level_command, spawn_player_command).chain(),
|
||||
);
|
||||
|
||||
app.load_resource::<GameplayMusic>();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user