generated from 2ndbeam/bevy-template
feat: Finished door mechanics
- Door now has i8 direction (-1 or 1) - Door may be locked with Locked component - Player entity RigidBody now cannot sleep to keep MayInteract when idle
This commit is contained in:
parent
4c23a38b92
commit
bb357d8062
2 changed files with 37 additions and 16 deletions
|
|
@ -17,7 +17,10 @@ pub struct Wall;
|
|||
|
||||
#[derive(Component)]
|
||||
#[require(Sprite, InteractiveObject)]
|
||||
pub struct Door;
|
||||
pub struct Door(pub i8);
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Locked;
|
||||
|
||||
#[derive(EntityEvent)]
|
||||
pub struct InteractionEvent {
|
||||
|
|
@ -76,24 +79,35 @@ pub fn detect_interact_collisions(
|
|||
fn on_door_interact(
|
||||
event: On<InteractionEvent>,
|
||||
mut commands: Commands,
|
||||
locked_query: Query<(), With<Locked>>,
|
||||
collider_query: Query<(), (With<Door>, With<Collider>)>,
|
||||
no_collider_query: Query<(), (With<Door>, Without<Collider>)>,
|
||||
mut sprite_query: Query<&mut Sprite, With<Door>>,
|
||||
door_query: Query<(&Door, &Children)>,
|
||||
mut sprite_query: Query<(&mut Sprite, &mut Transform)>,
|
||||
asset_server: Res<AssetServer>,
|
||||
) {
|
||||
let was_opened =
|
||||
if collider_query.get(event.entity).is_ok() { false }
|
||||
if locked_query.get(event.entity).is_ok() {
|
||||
return;
|
||||
}
|
||||
let was_opened = if collider_query.get(event.entity).is_ok() { false }
|
||||
else if no_collider_query.get(event.entity).is_ok() { true }
|
||||
else {
|
||||
error!("on_door_interact fired but entity {} isn't door", event.entity);
|
||||
return;
|
||||
};
|
||||
let Ok(mut sprite) = sprite_query.get_mut(event.entity) else {
|
||||
error!("on_door_interact fired but entity {} has no sprite", event.entity);
|
||||
let Ok((door, children)) = door_query.get(event.entity) else {
|
||||
error!("on_door_interact fired but entity {} has no children", event.entity);
|
||||
return;
|
||||
};
|
||||
let asset_path = if was_opened { DOOR_CLOSED_ASSET } else { DOOR_OPENED_ASSET };
|
||||
sprite.image = asset_server.load(asset_path);
|
||||
for child in children {
|
||||
if let Ok((mut sprite, mut transform)) = sprite_query.get_mut(*child) {
|
||||
let (image, translation) = if was_opened { (DOOR_CLOSED_ASSET, 0.) }
|
||||
else { (DOOR_OPENED_ASSET, door.0 as f32 * 8.) };
|
||||
sprite.image = asset_server.load(image);
|
||||
transform.translation.x = translation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if was_opened {
|
||||
commands.entity(event.entity).insert(door_collider());
|
||||
|
|
@ -103,13 +117,13 @@ fn on_door_interact(
|
|||
}
|
||||
|
||||
fn door_collider() -> Collider {
|
||||
Collider::cuboid(PIXELS_PER_METER * 0.125, PIXELS_PER_METER)
|
||||
Collider::cuboid(PIXELS_PER_METER * 0.06125, PIXELS_PER_METER)
|
||||
}
|
||||
|
||||
fn door_bundle(image: Handle<Image>, position: Vec2) -> impl Bundle {
|
||||
fn door_bundle(image: Handle<Image>, position: Vec2, facing_left: bool) -> impl Bundle {
|
||||
let direction = if facing_left { -1 } else { 1 };
|
||||
(
|
||||
Door,
|
||||
Sprite::from_image(image),
|
||||
Door(direction),
|
||||
Transform::from_xyz(position.x, position.y, 0.),
|
||||
Name::new(format!("Door ({}, {})", position.x, position.y)),
|
||||
door_collider(),
|
||||
|
|
@ -120,6 +134,10 @@ fn door_bundle(image: Handle<Image>, position: Vec2) -> impl Bundle {
|
|||
Sensor,
|
||||
Transform::from_xyz(0., 0., 0.),
|
||||
),
|
||||
(
|
||||
Sprite::from_image(image),
|
||||
Transform::from_xyz(0., 0., 0.),
|
||||
),
|
||||
],
|
||||
)
|
||||
}
|
||||
|
|
@ -138,6 +156,8 @@ pub fn setup_world(
|
|||
asset_server: Res<AssetServer>,
|
||||
) {
|
||||
let door_image = asset_server.load(DOOR_CLOSED_ASSET);
|
||||
commands.spawn(door_bundle(door_image, vec2(128., 0.)));
|
||||
commands.spawn(door_bundle(door_image.clone(), vec2(128., 0.), true));
|
||||
commands.spawn(door_bundle(door_image.clone(), vec2(160., 0.), false));
|
||||
commands.spawn(door_bundle(door_image.clone(), vec2(196., 0.), false)).insert(Locked);
|
||||
commands.spawn(wall_bundle(vec2(-128., 0.)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ fn player_bundle(asset_server: &Res<AssetServer>) -> impl Bundle {
|
|||
ActiveCollisionTypes::default() | ActiveCollisionTypes::KINEMATIC_STATIC,
|
||||
Collider::cuboid(PIXELS_PER_METER * 0.5, PIXELS_PER_METER),
|
||||
ActiveEvents::COLLISION_EVENTS,
|
||||
Sleeping::disabled(),
|
||||
children![
|
||||
(Inventory::new(UVec2::new(6, 2)), ActiveInventory),
|
||||
(Inventory::new(UVec2::new(5, 3)), ActiveInventory),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue