mirror of
https://github.com/kristoferssolo/maze-ascension.git
synced 2025-10-21 19:20:34 +00:00
feat(player): add ascension/descension
This commit is contained in:
parent
4640862402
commit
269686323f
@ -1,10 +1,10 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
#[derive(Debug, Reflect, Component)]
|
||||
#[derive(Debug, Reflect, Component, Deref, DerefMut)]
|
||||
#[reflect(Component)]
|
||||
pub struct Floor(pub u8);
|
||||
|
||||
#[derive(Debug, Reflect, Component)]
|
||||
#[derive(Debug, Reflect, Component, Deref, DerefMut)]
|
||||
#[reflect(Component)]
|
||||
pub struct TargetFloor(pub u8);
|
||||
|
||||
@ -17,3 +17,13 @@ impl Default for Floor {
|
||||
Self(1)
|
||||
}
|
||||
}
|
||||
|
||||
impl Floor {
|
||||
pub fn increase(&self) -> Self {
|
||||
Self(self.0.saturating_add(1))
|
||||
}
|
||||
|
||||
pub fn decrease(&self) -> Self {
|
||||
Self(self.0.saturating_sub(1).max(1))
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,4 +4,6 @@ mod systems;
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(super) fn plugin(_app: &mut App) {}
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.add_plugins(systems::plugin);
|
||||
}
|
||||
|
||||
@ -1 +1,3 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub(super) fn plugin(_app: &mut App) {}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
use crate::theme::palette::rose_pine::{LOVE, PINE};
|
||||
|
||||
use super::resources::GlobalMazeConfig;
|
||||
use bevy::prelude::*;
|
||||
use bevy::{prelude::*, utils::HashMap};
|
||||
use std::f32::consts::FRAC_PI_2;
|
||||
|
||||
const WALL_OVERLAP_MODIFIER: f32 = 1.25;
|
||||
@ -11,6 +13,7 @@ pub(crate) struct MazeAssets {
|
||||
pub(crate) wall_mesh: Handle<Mesh>,
|
||||
pub(crate) hex_material: Handle<StandardMaterial>,
|
||||
pub(crate) wall_material: Handle<StandardMaterial>,
|
||||
pub(crate) custom_materials: HashMap<String, Handle<StandardMaterial>>,
|
||||
}
|
||||
|
||||
impl MazeAssets {
|
||||
@ -19,6 +22,11 @@ impl MazeAssets {
|
||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
global_config: &GlobalMazeConfig,
|
||||
) -> MazeAssets {
|
||||
let mut custom_materials = HashMap::new();
|
||||
custom_materials.extend(vec![
|
||||
("LOVE".to_string(), materials.add(red_material())),
|
||||
("PINE".to_string(), materials.add(blue_material())),
|
||||
]);
|
||||
MazeAssets {
|
||||
hex_mesh: meshes.add(generate_hex_mesh(
|
||||
global_config.hex_size,
|
||||
@ -30,6 +38,7 @@ impl MazeAssets {
|
||||
)),
|
||||
hex_material: materials.add(white_material()),
|
||||
wall_material: materials.add(Color::BLACK),
|
||||
custom_materials,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -53,9 +62,8 @@ fn generate_square_mesh(depth: f32, wall_size: f32) -> Mesh {
|
||||
Mesh::from(rectangular_prism).rotated_by(rotation)
|
||||
}
|
||||
|
||||
fn white_material() -> StandardMaterial {
|
||||
pub(crate) fn white_material() -> StandardMaterial {
|
||||
StandardMaterial {
|
||||
base_color: Color::WHITE,
|
||||
emissive: LinearRgba::new(
|
||||
WHITE_EMISSION_INTENSITY,
|
||||
WHITE_EMISSION_INTENSITY,
|
||||
@ -65,3 +73,17 @@ fn white_material() -> StandardMaterial {
|
||||
..default()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn red_material() -> StandardMaterial {
|
||||
StandardMaterial {
|
||||
emissive: LOVE.to_linear(),
|
||||
..default()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn blue_material() -> StandardMaterial {
|
||||
StandardMaterial {
|
||||
emissive: PINE.to_linear(),
|
||||
..default()
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,12 +81,28 @@ pub(super) fn spawn_single_hex_tile(
|
||||
HexOrientation::Flat => Quat::from_rotation_y(FRAC_PI_6), // 30 degrees rotation
|
||||
};
|
||||
|
||||
let material = match tile.pos() {
|
||||
pos if pos == maze_config.start_pos => assets
|
||||
.custom_materials
|
||||
.get("PINE")
|
||||
.cloned()
|
||||
.to_owned()
|
||||
.unwrap(),
|
||||
pos if pos == maze_config.end_pos => assets
|
||||
.custom_materials
|
||||
.get("LOVE")
|
||||
.cloned()
|
||||
.to_owned()
|
||||
.unwrap(),
|
||||
_ => assets.hex_material.clone(),
|
||||
};
|
||||
|
||||
parent
|
||||
.spawn((
|
||||
Name::new(format!("Hex {}", tile)),
|
||||
Tile,
|
||||
Mesh3d(assets.hex_mesh.clone()),
|
||||
MeshMaterial3d(assets.hex_material.clone()),
|
||||
MeshMaterial3d(material),
|
||||
Transform::from_translation(world_pos).with_rotation(rotation),
|
||||
))
|
||||
.with_children(|parent| spawn_walls(parent, assets, tile.walls(), global_config));
|
||||
|
||||
@ -8,3 +8,13 @@ pub struct RespawnPlayer;
|
||||
|
||||
#[derive(Debug, Event)]
|
||||
pub struct DespawnPlayer;
|
||||
|
||||
#[derive(Debug, Event)]
|
||||
pub struct AscendPlayer {
|
||||
pub floor: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug, Event)]
|
||||
pub struct DescendPlayer {
|
||||
pub floor: u8,
|
||||
}
|
||||
|
||||
@ -6,13 +6,15 @@ mod triggers;
|
||||
|
||||
use bevy::{ecs::system::RunSystemOnce, prelude::*};
|
||||
use components::Player;
|
||||
use events::{DespawnPlayer, RespawnPlayer, SpawnPlayer};
|
||||
use events::{AscendPlayer, DescendPlayer, DespawnPlayer, RespawnPlayer, SpawnPlayer};
|
||||
|
||||
pub(super) fn plugin(app: &mut App) {
|
||||
app.register_type::<Player>()
|
||||
.add_event::<SpawnPlayer>()
|
||||
.add_event::<RespawnPlayer>()
|
||||
.add_event::<DespawnPlayer>()
|
||||
.add_event::<AscendPlayer>()
|
||||
.add_event::<DescendPlayer>()
|
||||
.add_plugins((triggers::plugin, systems::plugin));
|
||||
}
|
||||
|
||||
|
||||
30
src/player/systems/ascend.rs
Normal file
30
src/player/systems/ascend.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::{
|
||||
floor::components::{CurrentFloor, Floor},
|
||||
maze::components::MazeConfig,
|
||||
player::{
|
||||
components::{CurrentPosition, Player},
|
||||
events::AscendPlayer,
|
||||
},
|
||||
};
|
||||
|
||||
pub(super) fn ascend_player(
|
||||
query: Query<&CurrentPosition, With<Player>>,
|
||||
maze_config_query: Query<(&MazeConfig, &Floor), With<CurrentFloor>>,
|
||||
mut event_writer: EventWriter<AscendPlayer>,
|
||||
) {
|
||||
let Ok((config, floor)) = maze_config_query.get_single() else {
|
||||
warn!("No current floor configuration found");
|
||||
return;
|
||||
};
|
||||
|
||||
for current_hex in query.iter() {
|
||||
if current_hex.0 == config.end_pos {
|
||||
event_writer.send(AscendPlayer {
|
||||
floor: *floor.increase(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/player/systems/descend.rs
Normal file
30
src/player/systems/descend.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::{
|
||||
floor::components::{CurrentFloor, Floor},
|
||||
maze::components::MazeConfig,
|
||||
player::{
|
||||
components::{CurrentPosition, Player},
|
||||
events::DescendPlayer,
|
||||
},
|
||||
};
|
||||
|
||||
pub(super) fn descend_player(
|
||||
query: Query<&CurrentPosition, With<Player>>,
|
||||
maze_config_query: Query<(&MazeConfig, &Floor), With<CurrentFloor>>,
|
||||
mut event_writer: EventWriter<DescendPlayer>,
|
||||
) {
|
||||
let Ok((config, floor)) = maze_config_query.get_single() else {
|
||||
warn!("No current floor configuration found");
|
||||
return;
|
||||
};
|
||||
|
||||
for current_hex in query.iter() {
|
||||
if current_hex.0 == config.start_pos {
|
||||
event_writer.send(DescendPlayer {
|
||||
floor: *floor.decrease(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,17 +1,20 @@
|
||||
mod ascend;
|
||||
mod descend;
|
||||
mod input;
|
||||
mod movement;
|
||||
pub mod setup;
|
||||
|
||||
use crate::maze::MazePluginLoaded;
|
||||
use ascend::ascend_player;
|
||||
use bevy::prelude::*;
|
||||
use descend::descend_player;
|
||||
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)
|
||||
(player_input, player_movement, ascend_player, descend_player)
|
||||
.chain()
|
||||
.run_if(resource_exists::<MazePluginLoaded>),
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user