generated from 2ndbeam/bevy-template
- Made all observers public - Observe all InteractionEvents in the app, not in the entity - Added names to layout bundles - Raised player speed to 4 m/s for quicker debugging - Added second container on 2nd floor
98 lines
2.9 KiB
Rust
98 lines
2.9 KiB
Rust
use bevy::{ecs::relationship::RelatedSpawner, prelude::*};
|
|
use bevy_rapier2d::prelude::*;
|
|
|
|
use crate::{meters, player::Player};
|
|
|
|
use super::*;
|
|
|
|
#[derive(Component, Debug, PartialEq, Eq, Default, Clone, Copy, Reflect)]
|
|
#[reflect(Component, Debug, PartialEq, Default, Clone)]
|
|
#[require(InteractiveObject, Collider, Sensor)]
|
|
pub enum StairCollider {
|
|
#[default]
|
|
Up,
|
|
Down,
|
|
}
|
|
|
|
#[derive(Component, Clone, Copy, Default, Reflect, Debug, PartialEq)]
|
|
#[reflect(Component, Clone, Default, Debug, PartialEq)]
|
|
#[require(Transform)]
|
|
pub struct Stairs {
|
|
pub up: Option<Vec2>,
|
|
pub down: Option<Vec2>,
|
|
}
|
|
|
|
pub fn on_stairs_interact(
|
|
event: On<InteractionEvent>,
|
|
collider_query: Query<(&ChildOf, &StairCollider)>,
|
|
stairs_query: Query<&Stairs>,
|
|
mut player_query: Query<&mut Transform, With<Player>>,
|
|
) {
|
|
let Ok((parent, collider_type)) = collider_query.get(event.entity) else {
|
|
return;
|
|
};
|
|
let Ok(stairs) = stairs_query.get(parent.0) else {
|
|
error!("StairCollider does not have Stairs parent");
|
|
return;
|
|
};
|
|
let Ok(mut player_transform) = player_query.single_mut() else {
|
|
error!("Player is not single");
|
|
return;
|
|
};
|
|
|
|
let offset = match collider_type {
|
|
StairCollider::Up => {
|
|
let Some(offset) = stairs.up else {
|
|
error!("StairCollider::Up triggered but Stairs.up is None");
|
|
return;
|
|
};
|
|
offset
|
|
},
|
|
StairCollider::Down => {
|
|
let Some(offset) = stairs.down else {
|
|
error!("StairCollider::Down triggered but Stairs.down is None");
|
|
return;
|
|
};
|
|
offset
|
|
},
|
|
};
|
|
|
|
player_transform.translation.x += offset.x;
|
|
player_transform.translation.y += offset.y;
|
|
}
|
|
|
|
pub fn stairs_bundle(
|
|
_asset_server: &Res<AssetServer>,
|
|
position: Vec2,
|
|
up_position: Option<Vec2>,
|
|
down_position: Option<Vec2>,
|
|
) -> impl Bundle {
|
|
let (has_up, has_down) = (up_position.is_some(), down_position.is_some());
|
|
(
|
|
Stairs {
|
|
up: up_position,
|
|
down: down_position,
|
|
},
|
|
Transform::from_xyz(position.x, position.y, -1.),
|
|
Children::spawn(
|
|
SpawnWith(move |parent: &mut RelatedSpawner<ChildOf>| {
|
|
if has_up {
|
|
parent.spawn((
|
|
StairCollider::Up,
|
|
Collider::cuboid(meters(1.), meters(1.)),
|
|
Transform::from_xyz(meters(-1.), 0., 0.),
|
|
));
|
|
}
|
|
|
|
if has_down {
|
|
parent.spawn((
|
|
StairCollider::Down,
|
|
Collider::cuboid(meters(1.), meters(1.)),
|
|
Transform::from_xyz(meters(1.), 0., 0.),
|
|
));
|
|
}
|
|
})
|
|
),
|
|
Name::new(format!("Stairs ({},{})", position.x, position.y))
|
|
)
|
|
}
|