chore: rename MovementState -> FloorYTarget

This commit is contained in:
Kristofers Solo 2025-01-01 22:53:57 +02:00
parent 90f5443804
commit e352b45401
13 changed files with 81 additions and 119 deletions

3
src/constants.rs Normal file
View File

@ -0,0 +1,3 @@
pub const MOVEMENT_THRESHOLD: f32 = 0.01;
pub const WALL_OVERLAP_MODIFIER: f32 = 1.25;
pub const FLOOR_Y_OFFSET: u8 = 100;

View File

@ -12,12 +12,9 @@ pub struct CurrentFloor;
#[reflect(Component)]
pub struct NextFloor;
#[derive(Debug, Reflect, Component)]
#[derive(Debug, Reflect, Component, Deref, DerefMut)]
#[reflect(Component)]
pub struct MovementState {
pub target_y: f32,
pub direction: f32,
}
pub struct FloorYTarget(pub f32);
impl Default for Floor {
fn default() -> Self {

View File

@ -16,9 +16,8 @@ pub(super) fn plugin(app: &mut App) {
spawn_floor,
despawn_floor,
handle_floor_transition_events,
move_floors,
move_floors.after(handle_floor_transition_events),
)
.chain()
.run_if(resource_exists::<MazePluginLoaded>),
);
}

View File

@ -1,40 +1,41 @@
use crate::{
constants::{FLOOR_Y_OFFSET, MOVEMENT_THRESHOLD},
floor::{
components::{CurrentFloor, MovementState, NextFloor},
components::{CurrentFloor, FloorYTarget, NextFloor},
events::TransitionFloor,
},
maze::components::HexMaze,
player::components::{MovementSpeed, Player},
};
use bevy::prelude::*;
const MOVEMENT_THRESHOLD: f32 = 0.001;
pub(super) fn move_floors(
pub fn move_floors(
mut commands: Commands,
mut maze_query: Query<(Entity, &mut Transform, Option<&mut MovementState>), With<HexMaze>>,
mut maze_query: Query<
(Entity, &mut Transform, &FloorYTarget),
(With<HexMaze>, With<FloorYTarget>),
>,
player_query: Query<&MovementSpeed, With<Player>>,
time: Res<Time>,
) {
let speed = player_query.get_single().map_or(100., |s| s.0);
let movement_distance = speed * time.delta_secs();
for (entity, mut transform, mut movement_state) in maze_query.iter_mut() {
if let Some(state) = movement_state.as_mut() {
let delta = state.target_y - transform.translation.y;
if delta.abs() > MOVEMENT_THRESHOLD {
let movement = delta.signum() * movement_distance.min(delta.abs());
transform.translation.y += movement;
} else {
transform.translation.y = state.target_y;
commands.entity(entity).remove::<MovementState>();
}
for (entity, mut transform, movement_state) in maze_query.iter_mut() {
let delta = movement_state.0 - transform.translation.y;
if delta.abs() > MOVEMENT_THRESHOLD {
let movement = delta.signum() * movement_distance.min(delta.abs());
transform.translation.y += movement;
} else {
transform.translation.y = movement_state.0;
commands.entity(entity).remove::<FloorYTarget>();
}
}
}
pub(super) fn handle_floor_transition_events(
pub fn handle_floor_transition_events(
mut commands: Commands,
mut maze_query: Query<(Entity, &mut Transform, Option<&mut MovementState>), With<HexMaze>>,
mut maze_query: Query<(Entity, &Transform, Option<&FloorYTarget>), With<HexMaze>>,
current_query: Query<Entity, With<CurrentFloor>>,
next_query: Query<Entity, With<NextFloor>>,
mut event_reader: EventReader<TransitionFloor>,
@ -50,21 +51,17 @@ pub(super) fn handle_floor_transition_events(
for event in event_reader.read() {
let direction = event.into();
let Some((current_entity, current_y)) = get_floor_info(&maze_query, &current_query) else {
let Some(current_entity) = current_query.get_single().ok() else {
continue;
};
let Some((next_entity, next_y)) = get_floor_info(&maze_query, &next_query) else {
let Some(next_entity) = next_query.get_single().ok() else {
continue;
};
let diff = (current_y - next_y).abs();
for (entity, transforms, movement_state) in maze_query.iter_mut() {
let target_y = diff.mul_add(direction, transforms.translation.y);
let target_y = (FLOOR_Y_OFFSET as f32).mul_add(direction, transforms.translation.y);
if movement_state.is_none() {
commands.entity(entity).insert(MovementState {
target_y,
direction,
});
commands.entity(entity).insert(FloorYTarget(target_y));
}
}
@ -80,15 +77,3 @@ fn update_current_next_floor(commands: &mut Commands, current_entity: Entity, ne
.remove::<NextFloor>()
.insert(CurrentFloor);
}
fn get_floor_info(
maze_query: &Query<(Entity, &mut Transform, Option<&mut MovementState>), With<HexMaze>>,
query: &Query<Entity, With<impl Component>>,
) -> Option<(Entity, f32)> {
query.get_single().ok().and_then(|entity| {
maze_query
.get(entity)
.ok()
.map(|(_, transform, _)| (entity, transform.translation.y))
})
}

View File

@ -1,6 +1,6 @@
use crate::{
floor::{
components::{CurrentFloor, Floor, MovementState},
components::{CurrentFloor, Floor, FloorYTarget},
events::TransitionFloor,
resources::HighestFloor,
},
@ -10,8 +10,7 @@ use bevy::prelude::*;
pub(super) fn spawn_floor(
mut commands: Commands,
query: Query<&mut Floor, With<CurrentFloor>>,
movement_state_query: Query<Option<&MovementState>>,
query: Query<&mut Floor, (With<CurrentFloor>, Without<FloorYTarget>)>,
mut event_reader: EventReader<TransitionFloor>,
mut highest_floor: ResMut<HighestFloor>,
) {
@ -19,13 +18,6 @@ pub(super) fn spawn_floor(
return;
};
let is_moving = movement_state_query
.iter()
.any(|movement_state| movement_state.is_some());
if is_moving {
return;
}
for event in event_reader.read() {
let floor = event.next_floor_num(floor);

View File

@ -1,5 +1,6 @@
pub mod asset_tracking;
pub mod audio;
pub mod constants;
#[cfg(feature = "dev")]
pub mod dev_tools;
pub mod floor;

View File

@ -1,10 +1,12 @@
use super::resources::GlobalMazeConfig;
use crate::theme::{palette::rose_pine::RosePine, prelude::ColorScheme};
use crate::{
constants::WALL_OVERLAP_MODIFIER,
theme::{palette::rose_pine::RosePine, prelude::ColorScheme},
};
use bevy::{prelude::*, utils::HashMap};
use std::f32::consts::FRAC_PI_2;
use strum::IntoEnumIterator;
const WALL_OVERLAP_MODIFIER: f32 = 1.25;
const HEX_SIDES: u32 = 6;
const WHITE_EMISSION_INTENSITY: f32 = 10.;

View File

@ -1,5 +1,6 @@
use super::common::generate_maze;
use crate::{
constants::FLOOR_Y_OFFSET,
floor::components::{CurrentFloor, Floor, NextFloor},
maze::{
assets::MazeAssets,
@ -14,8 +15,6 @@ use hexlab::prelude::{Tile as HexTile, *};
use hexx::HexOrientation;
use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6};
pub const FLOOR_Y_OFFSET: u8 = 100;
pub(super) fn spawn_maze(
trigger: Trigger<SpawnMaze>,
mut commands: Commands,

View File

@ -1,25 +0,0 @@
use crate::{
floor::{components::CurrentFloor, events::TransitionFloor},
maze::components::MazeConfig,
player::components::{CurrentPosition, Player},
};
use bevy::prelude::*;
pub(super) fn ascend_player(
query: Query<&CurrentPosition, With<Player>>,
maze_config: Query<&MazeConfig, With<CurrentFloor>>,
mut event_writer: EventWriter<TransitionFloor>,
) {
let Ok(config) = maze_config.get_single() else {
warn!("Failed to get maze configuration for current floor - cannot ascend player");
return;
};
for current_hex in query.iter() {
if current_hex.0 == config.end_pos {
dbg!("Ascend");
event_writer.send(TransitionFloor::Ascend);
return;
}
}
}

View File

@ -1,28 +0,0 @@
use bevy::prelude::*;
use crate::{
floor::{
components::{CurrentFloor, Floor},
events::TransitionFloor,
},
maze::components::MazeConfig,
player::components::{CurrentPosition, Player},
};
pub(super) fn descend_player(
query: Query<&CurrentPosition, With<Player>>,
maze_config: Query<(&MazeConfig, &Floor), With<CurrentFloor>>,
mut event_writer: EventWriter<TransitionFloor>,
) {
let Ok((config, floor)) = maze_config.get_single() else {
warn!("Failed to get maze configuration for current floor - cannot descend player");
return;
};
for current_hex in query.iter() {
if current_hex.0 == config.start_pos && floor.0 != 1 {
event_writer.send(TransitionFloor::Descend);
return;
}
}
}

View File

@ -1,21 +1,22 @@
mod ascend;
mod descend;
mod input;
mod movement;
pub mod setup;
mod vertical_transition;
use crate::maze::MazePluginLoaded;
use ascend::ascend_player;
use bevy::prelude::*;
use descend::descend_player;
use input::player_input;
use movement::player_movement;
use vertical_transition::handle_floor_transition;
pub(super) fn plugin(app: &mut App) {
app.add_systems(
Update,
(player_input, player_movement, ascend_player, descend_player)
.chain()
(
player_input,
player_movement.after(player_input),
handle_floor_transition,
)
.run_if(resource_exists::<MazePluginLoaded>),
);
}

View File

@ -1,4 +1,5 @@
use crate::{
constants::MOVEMENT_THRESHOLD,
floor::components::CurrentFloor,
maze::components::MazeConfig,
player::components::{CurrentPosition, MovementSpeed, MovementTarget, Player},
@ -6,8 +7,6 @@ use crate::{
use bevy::prelude::*;
use hexx::Hex;
const MOVEMENT_THRESHOLD: f32 = 0.1;
pub(super) fn player_movement(
time: Res<Time>,
mut query: Query<

View File

@ -0,0 +1,37 @@
use bevy::prelude::*;
use crate::{
floor::{
components::{CurrentFloor, Floor},
events::TransitionFloor,
},
maze::components::MazeConfig,
player::components::{CurrentPosition, Player},
};
pub fn handle_floor_transition(
player_query: Query<&CurrentPosition, With<Player>>,
maze_query: Query<(&MazeConfig, &Floor), With<CurrentFloor>>,
mut event_writer: EventWriter<TransitionFloor>,
) {
let Ok((config, floor)) = maze_query.get_single() else {
warn!("Failed to get maze configuration for current floor - cannot ascend/descend player.");
return;
};
for current_hex in player_query.iter() {
// Check for ascending
if current_hex.0 == config.end_pos {
dbg!("Ascending");
event_writer.send(TransitionFloor::Ascend);
return;
}
// Check for descending
if current_hex.0 == config.start_pos && floor.0 != 1 {
dbg!("Descending");
event_writer.send(TransitionFloor::Descend);
return;
}
}
}