mirror of
https://github.com/kristoferssolo/maze-ascension.git
synced 2025-10-21 19:20:34 +00:00
feat(player): add player respawn and despawn
This commit is contained in:
parent
b89921dcd6
commit
f4aefb00fa
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -2589,12 +2589,13 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
||||
|
||||
[[package]]
|
||||
name = "hexlab"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b912e78d292803bc279aec3a4e2a0cdd0e0ac1540bcdc5d0f32cbfe9e4d234dc"
|
||||
dependencies = [
|
||||
"bevy",
|
||||
"hexx",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"thiserror 2.0.6",
|
||||
]
|
||||
|
||||
@ -3076,7 +3077,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "maze-ascension"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"bevy",
|
||||
"bevy-inspector-egui",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "maze-ascension"
|
||||
authors = ["Kristofers Solo <dev@kristofers.xyz>"]
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
@ -18,7 +18,7 @@ tracing = { version = "0.1", features = [
|
||||
"release_max_level_warn",
|
||||
] }
|
||||
hexx = { version = "0.19", features = ["bevy_reflect", "grid"] }
|
||||
hexlab = { path = "../hexlab", features = ["bevy"] }
|
||||
hexlab = { version = "0.3", features = ["bevy"] }
|
||||
bevy-inspector-egui = { version = "0.28", optional = true }
|
||||
bevy_egui = { version = "0.31", optional = true }
|
||||
thiserror = "2.0"
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use crate::{
|
||||
maze::{events::RecreateMazeEvent, MazeConfig, MazePluginLoaded},
|
||||
player::events::RespawnPlayer,
|
||||
};
|
||||
use bevy::{prelude::*, window::PrimaryWindow};
|
||||
use hexx::{Hex, HexOrientation};
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
use crate::maze::{events::RecreateMazeEvent, MazeConfig, MazePluginLoaded};
|
||||
use bevy_egui::{
|
||||
egui::{self, emath::Numeric, DragValue, TextEdit, Ui},
|
||||
EguiContext,
|
||||
};
|
||||
use hexx::{Hex, HexOrientation};
|
||||
use rand::{thread_rng, Rng};
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
pub(crate) fn maze_controls_ui(world: &mut World) {
|
||||
if world.get_resource::<MazePluginLoaded>().is_none() {
|
||||
@ -55,6 +56,9 @@ pub(crate) fn maze_controls_ui(world: &mut World) {
|
||||
{
|
||||
event_writer.send(RecreateMazeEvent { floor: 1 });
|
||||
}
|
||||
if let Some(mut event_writer) = world.get_resource_mut::<Events<RespawnPlayer>>() {
|
||||
event_writer.send(RespawnPlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -82,9 +86,9 @@ fn add_position_control(ui: &mut Ui, label: &str, pos: &mut Hex) -> bool {
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(label);
|
||||
let response_x = ui.add(DragValue::new(&mut pos.x).speed(1).prefix("x: "));
|
||||
let response_y = ui.add(DragValue::new(&mut pos.y).speed(1).prefix("y: "));
|
||||
changed = response_x.changed() || response_y.changed();
|
||||
let response_q = ui.add(DragValue::new(&mut pos.x).speed(1).prefix("q: "));
|
||||
let response_r = ui.add(DragValue::new(&mut pos.y).speed(1).prefix("r: "));
|
||||
changed = response_r.changed() || response_q.changed();
|
||||
});
|
||||
changed
|
||||
}
|
||||
|
||||
@ -7,12 +7,11 @@ mod resources;
|
||||
mod systems;
|
||||
|
||||
pub use resources::{MazeConfig, MazePluginLoaded};
|
||||
use systems::recreation::handle_maze_recreation_event;
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.init_resource::<MazeConfig>()
|
||||
.add_event::<RecreateMazeEvent>()
|
||||
.add_systems(Update, handle_maze_recreation_event);
|
||||
.add_plugins(systems::plugin);
|
||||
}
|
||||
|
||||
pub fn spawn_level_command(world: &mut World) {
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
use bevy::{
|
||||
ecs::{system::RunSystemOnce, world::Command},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use super::{
|
||||
events::RecreateMazeEvent,
|
||||
systems::{self, recreation::handle_maze_recreation_event},
|
||||
MazeConfig, MazePluginLoaded,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct MazePlugin;
|
||||
|
||||
impl Plugin for MazePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<MazeConfig>()
|
||||
.add_event::<RecreateMazeEvent>()
|
||||
.add_systems(Update, handle_maze_recreation_event);
|
||||
}
|
||||
}
|
||||
|
||||
impl Command for MazePlugin {
|
||||
fn apply(self, world: &mut World) {
|
||||
world.insert_resource(MazePluginLoaded);
|
||||
let _ = world.run_system_once(systems::setup::setup);
|
||||
}
|
||||
}
|
||||
@ -40,8 +40,8 @@ impl MazeConfig {
|
||||
let start_pos = generate_pos(radius, &mut rng)?;
|
||||
let end_pos = generate_pos(radius, &mut rng)?;
|
||||
|
||||
debug!("Start pos: ({},{})", start_pos.x, start_pos.y);
|
||||
debug!("End pos: ({},{})", end_pos.x, end_pos.y);
|
||||
info!("Start pos: (q={}, r={})", start_pos.x, start_pos.y);
|
||||
info!("End pos: (q={}, r={})", end_pos.x, end_pos.y);
|
||||
|
||||
let layout = HexLayout {
|
||||
orientation,
|
||||
|
||||
@ -1,3 +1,14 @@
|
||||
use crate::maze::components::Floor;
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::maze::components::MazeFloor;
|
||||
pub(crate) fn despawn_floor(
|
||||
commands: &mut Commands,
|
||||
query: &Query<(Entity, &Floor)>,
|
||||
floor_num: u8,
|
||||
) {
|
||||
for (entity, floor) in query.iter() {
|
||||
if floor.0 == floor_num {
|
||||
commands.entity(entity).despawn_recursive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,11 @@
|
||||
pub mod despawn;
|
||||
pub mod recreation;
|
||||
pub mod setup;
|
||||
mod spawn;
|
||||
pub mod spawn;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use recreation::recreate_maze;
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_systems(Update, recreate_maze);
|
||||
}
|
||||
|
||||
@ -2,9 +2,9 @@ use bevy::prelude::*;
|
||||
|
||||
use crate::maze::{components::Floor, events::RecreateMazeEvent, MazeConfig};
|
||||
|
||||
use super::setup::setup_maze;
|
||||
use super::{despawn::despawn_floor, spawn::spawn_floor};
|
||||
|
||||
pub(crate) fn handle_maze_recreation_event(
|
||||
pub(crate) fn recreate_maze(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
@ -14,14 +14,6 @@ pub(crate) fn handle_maze_recreation_event(
|
||||
) {
|
||||
for event in event_reader.read() {
|
||||
despawn_floor(&mut commands, &query, event.floor);
|
||||
setup_maze(&mut commands, &mut meshes, &mut materials, &config);
|
||||
}
|
||||
}
|
||||
|
||||
fn despawn_floor(commands: &mut Commands, query: &Query<(Entity, &Floor)>, floor_num: u8) {
|
||||
for (entity, floor) in query.iter() {
|
||||
if floor.0 == floor_num {
|
||||
commands.entity(entity).despawn_recursive();
|
||||
}
|
||||
spawn_floor(&mut commands, &mut meshes, &mut materials, &config);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,6 @@
|
||||
use super::spawn::spawn_floor;
|
||||
use crate::maze::MazeConfig;
|
||||
use bevy::prelude::*;
|
||||
use hexlab::{GeneratorType, MazeBuilder};
|
||||
|
||||
use crate::maze::{
|
||||
assets::MazeAssets,
|
||||
components::{Floor, Maze},
|
||||
MazeConfig,
|
||||
};
|
||||
|
||||
use super::spawn::spawn_single_hex_tile;
|
||||
|
||||
pub(crate) fn setup(
|
||||
mut commands: Commands,
|
||||
@ -15,34 +8,5 @@ pub(crate) fn setup(
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
config: Res<MazeConfig>,
|
||||
) {
|
||||
setup_maze(&mut commands, &mut meshes, &mut materials, &config);
|
||||
}
|
||||
|
||||
pub(super) fn setup_maze(
|
||||
commands: &mut Commands,
|
||||
meshes: &mut ResMut<Assets<Mesh>>,
|
||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
config: &MazeConfig,
|
||||
) {
|
||||
let maze = MazeBuilder::new()
|
||||
.with_radius(config.radius)
|
||||
.with_seed(config.seed)
|
||||
.with_generator(GeneratorType::RecursiveBacktracking)
|
||||
.build()
|
||||
.expect("Something went wrong while creating maze");
|
||||
|
||||
let assets = MazeAssets::new(meshes, materials, config);
|
||||
commands
|
||||
.spawn((
|
||||
Name::new("Floor"),
|
||||
Maze(maze.clone()),
|
||||
Floor(1),
|
||||
Transform::from_translation(Vec3::ZERO),
|
||||
Visibility::Visible,
|
||||
))
|
||||
.with_children(|parent| {
|
||||
for tile in maze.values() {
|
||||
spawn_single_hex_tile(parent, &assets, tile, config)
|
||||
}
|
||||
});
|
||||
spawn_floor(&mut commands, &mut meshes, &mut materials, &config);
|
||||
}
|
||||
|
||||
@ -1,14 +1,41 @@
|
||||
use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6};
|
||||
|
||||
use crate::maze::{
|
||||
assets::MazeAssets,
|
||||
components::{Floor, Maze, Tile, Wall},
|
||||
MazeConfig,
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
use hexlab::prelude::*;
|
||||
use hexx::HexOrientation;
|
||||
use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6};
|
||||
|
||||
use crate::maze::{
|
||||
assets::MazeAssets,
|
||||
components::{Tile, Wall},
|
||||
MazeConfig,
|
||||
};
|
||||
pub(super) fn spawn_floor(
|
||||
commands: &mut Commands,
|
||||
meshes: &mut ResMut<Assets<Mesh>>,
|
||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
config: &MazeConfig,
|
||||
) {
|
||||
let maze = MazeBuilder::new()
|
||||
.with_radius(config.radius)
|
||||
.with_seed(config.seed)
|
||||
.with_generator(GeneratorType::RecursiveBacktracking)
|
||||
.build()
|
||||
.expect("Something went wrong while creating maze");
|
||||
|
||||
let assets = MazeAssets::new(meshes, materials, config);
|
||||
commands
|
||||
.spawn((
|
||||
Name::new("Floor"),
|
||||
Maze(maze.clone()),
|
||||
Floor(1),
|
||||
Transform::from_translation(Vec3::ZERO),
|
||||
Visibility::Visible,
|
||||
))
|
||||
.with_children(|parent| {
|
||||
for tile in maze.values() {
|
||||
spawn_single_hex_tile(parent, &assets, tile, config)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub(super) fn spawn_single_hex_tile(
|
||||
parent: &mut ChildBuilder,
|
||||
|
||||
@ -16,7 +16,7 @@ pub struct MovementSpeed(pub f32);
|
||||
|
||||
impl Default for MovementSpeed {
|
||||
fn default() -> Self {
|
||||
Self(50.)
|
||||
Self(100.)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
4
src/player/events.rs
Normal file
4
src/player/events.rs
Normal file
@ -0,0 +1,4 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
#[derive(Debug, Event)]
|
||||
pub(crate) struct RespawnPlayer;
|
||||
@ -1,14 +1,18 @@
|
||||
mod assets;
|
||||
pub mod components;
|
||||
pub mod events;
|
||||
mod systems;
|
||||
|
||||
use bevy::{ecs::system::RunSystemOnce, prelude::*};
|
||||
use components::Player;
|
||||
use events::RespawnPlayer;
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.register_type::<Player>().add_plugins(systems::plugin);
|
||||
app.register_type::<Player>()
|
||||
.add_event::<RespawnPlayer>()
|
||||
.add_plugins(systems::plugin);
|
||||
}
|
||||
|
||||
pub fn spawn_player_command(world: &mut World) {
|
||||
let _ = world.run_system_once(systems::spawn::spawn_player);
|
||||
let _ = world.run_system_once(systems::setup::setup);
|
||||
}
|
||||
|
||||
9
src/player/systems/despawn.rs
Normal file
9
src/player/systems/despawn.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::player::components::Player;
|
||||
|
||||
pub(crate) fn despawn_players(commands: &mut Commands, query: &Query<Entity, With<Player>>) {
|
||||
for entity in query.iter() {
|
||||
commands.entity(entity).despawn_recursive();
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,22 @@
|
||||
pub mod despawn;
|
||||
mod input;
|
||||
mod movement;
|
||||
pub mod respawn;
|
||||
pub mod setup;
|
||||
pub mod spawn;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use input::player_input;
|
||||
use movement::player_movement;
|
||||
use respawn::respawn_player;
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_systems(Update, (player_input, player_movement.after(player_input)));
|
||||
app.add_systems(
|
||||
Update,
|
||||
(
|
||||
player_input,
|
||||
player_movement.after(player_input),
|
||||
respawn_player,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
21
src/player/systems/respawn.rs
Normal file
21
src/player/systems/respawn.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use crate::{
|
||||
maze::MazeConfig,
|
||||
player::{components::Player, events::RespawnPlayer},
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
|
||||
use super::{despawn::despawn_players, spawn::spawn_player};
|
||||
|
||||
pub(crate) fn respawn_player(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
config: Res<MazeConfig>,
|
||||
query: Query<Entity, With<Player>>,
|
||||
mut event_reader: EventReader<RespawnPlayer>,
|
||||
) {
|
||||
for _ in event_reader.read() {
|
||||
despawn_players(&mut commands, &query);
|
||||
spawn_player(&mut commands, &mut meshes, &mut materials, &config);
|
||||
}
|
||||
}
|
||||
14
src/player/systems/setup.rs
Normal file
14
src/player/systems/setup.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::maze::MazeConfig;
|
||||
|
||||
use super::spawn::spawn_player;
|
||||
|
||||
pub(crate) fn setup(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
config: Res<MazeConfig>,
|
||||
) {
|
||||
spawn_player(&mut commands, &mut meshes, &mut materials, &config);
|
||||
}
|
||||
@ -6,26 +6,26 @@ use crate::{
|
||||
},
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
use hexx::Hex;
|
||||
|
||||
pub fn spawn_player(
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
maze_config: Res<MazeConfig>,
|
||||
pub(super) fn spawn_player(
|
||||
commands: &mut Commands,
|
||||
meshes: &mut ResMut<Assets<Mesh>>,
|
||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
config: &MazeConfig,
|
||||
) {
|
||||
let player_height = maze_config.height * 0.5;
|
||||
let player_radius = maze_config.hex_size * 0.5;
|
||||
let player_radius = config.hex_size * 0.5;
|
||||
let player_height = player_radius * 3.5;
|
||||
|
||||
let start_hex = Hex::new(1, 1);
|
||||
let start_pos = maze_config.layout.hex_to_world_pos(start_hex);
|
||||
let y_offset = config.height / 2. + player_height / 1.3;
|
||||
|
||||
let start_pos = config.layout.hex_to_world_pos(config.start_pos);
|
||||
|
||||
commands.spawn((
|
||||
Name::new("Player"),
|
||||
Player,
|
||||
CurrentPosition(start_hex),
|
||||
CurrentPosition(config.start_pos),
|
||||
Mesh3d(meshes.add(generate_pill_mesh(player_radius, player_height / 2.))),
|
||||
MeshMaterial3d(materials.add(blue_material())),
|
||||
Transform::from_xyz(start_pos.x, player_height * 2., start_pos.y),
|
||||
Transform::from_xyz(start_pos.x, y_offset, start_pos.y),
|
||||
));
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user