generated from 2ndbeam/bevy-template
feat: Interaction highlighting
- Added Collision{Started,Stopped}Event
- Added player headlight just for showcasing
This commit is contained in:
parent
926c4e6644
commit
1f9dace4ce
11 changed files with 303 additions and 54 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 896 B After Width: | Height: | Size: 875 B |
|
|
@ -62,9 +62,13 @@ pub fn load_level (
|
||||||
|
|
||||||
for DoorData { pos, facing_left, lock } in level.interactive.doors.iter() {
|
for DoorData { pos, facing_left, lock } in level.interactive.doors.iter() {
|
||||||
let door_pos = vec2(meters(pos.x + 0.5), meters(pos.y));
|
let door_pos = vec2(meters(pos.x + 0.5), meters(pos.y));
|
||||||
let mut door = parent.spawn(door_bundle(&textures, door_pos, *facing_left));
|
let door_id = parent.spawn(door_bundle(&textures, door_pos, *facing_left))
|
||||||
|
.observe(super::door::on_door_interact)
|
||||||
|
.id();
|
||||||
if let Some(lock_facing_left) = lock {
|
if let Some(lock_facing_left) = lock {
|
||||||
door.with_child(padlock_bundle(&textures, *lock_facing_left));
|
parent.commands().spawn(padlock_bundle(&textures, *lock_facing_left))
|
||||||
|
.observe(super::lock::on_padlock_interaction)
|
||||||
|
.insert(ChildOf(door_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,6 +93,7 @@ pub fn load_level (
|
||||||
let pos = vec2(meters(pos.x), meters(pos.y));
|
let pos = vec2(meters(pos.x), meters(pos.y));
|
||||||
|
|
||||||
let mut container = parent.spawn(container_bundle(&textures, pos, *size));
|
let mut container = parent.spawn(container_bundle(&textures, pos, *size));
|
||||||
|
container.observe(super::container::on_container_interact);
|
||||||
|
|
||||||
for item in items {
|
for item in items {
|
||||||
// TODO: replace with proper item-by-id system
|
// TODO: replace with proper item-by-id system
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use bevy::prelude::*;
|
use bevy::{ecs::relationship::RelatedSpawner, prelude::*};
|
||||||
use bevy_rapier2d::prelude::*;
|
use bevy_rapier2d::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -35,6 +35,54 @@ pub fn on_container_interact(
|
||||||
next_state.set(GameState::Inventory);
|
next_state.set(GameState::Inventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_container_collision_started(
|
||||||
|
event: On<CollisionStartedEvent>,
|
||||||
|
mut commands: Commands,
|
||||||
|
collider_query: Query<&ChildOf, With<Collider>>,
|
||||||
|
parent_query: Query<&Children>,
|
||||||
|
highlight_sprite_query: Query<(), With<Sprite>>,
|
||||||
|
) {
|
||||||
|
let Ok(parent_id) = collider_query.get(event.entity) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Ok(children) = parent_query.get(parent_id.0) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
if highlight_sprite_query.get(*child).is_ok() {
|
||||||
|
commands.entity(*child).insert(Visibility::Visible);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commands.entity(parent_id.0).insert(Visibility::Hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_container_collision_stopped(
|
||||||
|
event: On<CollisionStoppedEvent>,
|
||||||
|
mut commands: Commands,
|
||||||
|
collider_query: Query<&ChildOf, With<Collider>>,
|
||||||
|
parent_query: Query<&Children>,
|
||||||
|
highlight_sprite_query: Query<(), With<Sprite>>,
|
||||||
|
) {
|
||||||
|
let Ok(parent_id) = collider_query.get(event.entity) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Ok(children) = parent_query.get(parent_id.0) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
if highlight_sprite_query.get(*child).is_ok() {
|
||||||
|
commands.entity(*child).insert(Visibility::Hidden);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commands.entity(parent_id.0).insert(Visibility::Visible);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn container_bundle(
|
pub fn container_bundle(
|
||||||
textures: &Res<LayoutTextures>,
|
textures: &Res<LayoutTextures>,
|
||||||
position: Vec2,
|
position: Vec2,
|
||||||
|
|
@ -48,14 +96,16 @@ pub fn container_bundle(
|
||||||
sprite,
|
sprite,
|
||||||
Inventory::new(inventory_size),
|
Inventory::new(inventory_size),
|
||||||
Children::spawn((
|
Children::spawn((
|
||||||
Spawn((
|
SpawnWith(|parent: &mut RelatedSpawner<ChildOf>| {
|
||||||
Collider::cuboid(meters(1.), meters(1.)),
|
parent.spawn((
|
||||||
Sensor,
|
Collider::cuboid(meters(1.), meters(1.)),
|
||||||
Transform::from_xyz(0., meters(0.5), 0.),
|
Sensor,
|
||||||
)),
|
Transform::from_xyz(0., meters(0.5), 0.),
|
||||||
|
)).observe(on_container_collision_started)
|
||||||
|
.observe(on_container_collision_stopped);
|
||||||
|
}),
|
||||||
Spawn((
|
Spawn((
|
||||||
highlight_sprite,
|
highlight_sprite,
|
||||||
Transform::from_xyz(0., 0., 1.),
|
|
||||||
Visibility::Hidden,
|
Visibility::Hidden,
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use bevy::prelude::*;
|
use bevy::{ecs::relationship::RelatedSpawner, prelude::*};
|
||||||
use bevy_light_2d::prelude::*;
|
use bevy_light_2d::prelude::*;
|
||||||
use bevy_rapier2d::prelude::*;
|
use bevy_rapier2d::prelude::*;
|
||||||
|
|
||||||
use crate::meters;
|
use crate::{layout::lock::Padlock, meters};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
|
@ -61,7 +61,8 @@ pub fn on_door_interact(
|
||||||
},
|
},
|
||||||
Err(_) => continue,
|
Err(_) => continue,
|
||||||
}
|
}
|
||||||
let texture = if maybe_door_collider.is_none() { &textures.door_closed } else { &textures.door_opened };
|
let texture = if maybe_door_collider.is_none() { &textures.door_closed }
|
||||||
|
else { &textures.door_opened };
|
||||||
let (sprite, highlight_sprite) = door_sprites(texture, door.is_facing_left());
|
let (sprite, highlight_sprite) = door_sprites(texture, door.is_facing_left());
|
||||||
let needed_sprite = if highlight_query.get(*child).is_err() { sprite } else { highlight_sprite };
|
let needed_sprite = if highlight_query.get(*child).is_err() { sprite } else { highlight_sprite };
|
||||||
commands.entity(*child).insert(needed_sprite);
|
commands.entity(*child).insert(needed_sprite);
|
||||||
|
|
@ -74,6 +75,56 @@ pub fn on_door_interact(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_door_collision_started(
|
||||||
|
event: On<CollisionStartedEvent>,
|
||||||
|
mut commands: Commands,
|
||||||
|
collider_query: Query<&ChildOf, With<Collider>>,
|
||||||
|
parent_query: Query<&Children>,
|
||||||
|
sprite_query: Query<(), (With<Sprite>, Without<Padlock>)>,
|
||||||
|
highlight_query: Query<(), With<DoorHighlight>>,
|
||||||
|
) {
|
||||||
|
let Ok(parent_id) = collider_query.get(event.entity) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Ok(children) = parent_query.get(parent_id.0) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
if sprite_query.get(*child).is_ok() {
|
||||||
|
match highlight_query.get(*child) {
|
||||||
|
Ok(_) => { commands.entity(*child).insert(Visibility::Visible); },
|
||||||
|
Err(_) => { commands.entity(*child).insert(Visibility::Hidden); },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_door_collision_stopped(
|
||||||
|
event: On<CollisionStoppedEvent>,
|
||||||
|
mut commands: Commands,
|
||||||
|
collider_query: Query<&ChildOf, With<Collider>>,
|
||||||
|
parent_query: Query<&Children>,
|
||||||
|
sprite_query: Query<(), (With<Sprite>, Without<Padlock>)>,
|
||||||
|
highlight_query: Query<(), With<DoorHighlight>>,
|
||||||
|
) {
|
||||||
|
let Ok(parent_id) = collider_query.get(event.entity) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Ok(children) = parent_query.get(parent_id.0) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
if sprite_query.get(*child).is_ok() {
|
||||||
|
match highlight_query.get(*child) {
|
||||||
|
Ok(_) => { commands.entity(*child).insert(Visibility::Hidden); },
|
||||||
|
Err(_) => { commands.entity(*child).insert(Visibility::Visible); },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn door_collider_bundle() -> impl Bundle {
|
pub fn door_collider_bundle() -> impl Bundle {
|
||||||
let size = vec2(meters(0.06125), meters(1.));
|
let size = vec2(meters(0.06125), meters(1.));
|
||||||
(
|
(
|
||||||
|
|
@ -103,22 +154,22 @@ pub fn door_bundle(textures: &Res<LayoutTextures>, position: Vec2, facing_left:
|
||||||
Transform::from_xyz(position.x, position.y, 0.),
|
Transform::from_xyz(position.x, position.y, 0.),
|
||||||
Name::new(format!("Door ({}, {})", position.x, position.y)),
|
Name::new(format!("Door ({}, {})", position.x, position.y)),
|
||||||
InheritedVisibility::VISIBLE,
|
InheritedVisibility::VISIBLE,
|
||||||
children![
|
Children::spawn((
|
||||||
door_collider_bundle(),
|
Spawn(door_collider_bundle()),
|
||||||
(
|
SpawnWith(|parent: &mut RelatedSpawner<ChildOf>| {
|
||||||
Collider::cuboid(meters(0.5), meters(1.)),
|
parent.spawn((
|
||||||
Transform::default(),
|
Collider::cuboid(meters(0.5), meters(1.)),
|
||||||
Sensor,
|
Transform::default(),
|
||||||
),
|
Sensor,
|
||||||
(
|
)).observe(on_door_collision_started)
|
||||||
sprite,
|
.observe(on_door_collision_stopped);
|
||||||
),
|
}),
|
||||||
(
|
Spawn(sprite),
|
||||||
|
Spawn((
|
||||||
highlight_sprite,
|
highlight_sprite,
|
||||||
Transform::from_xyz(0., 0., 1.),
|
|
||||||
DoorHighlight,
|
DoorHighlight,
|
||||||
Visibility::Hidden,
|
Visibility::Hidden,
|
||||||
)
|
)),
|
||||||
],
|
)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use bevy::prelude::*;
|
use bevy::{ecs::relationship::RelatedSpawner, prelude::*};
|
||||||
use bevy_rapier2d::prelude::*;
|
use bevy_rapier2d::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -49,6 +49,54 @@ pub fn on_padlock_interaction(
|
||||||
commands.entity(lockpick_id).despawn();
|
commands.entity(lockpick_id).despawn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_padlock_collision_started(
|
||||||
|
event: On<CollisionStartedEvent>,
|
||||||
|
mut commands: Commands,
|
||||||
|
collider_query: Query<&ChildOf, With<Collider>>,
|
||||||
|
parent_query: Query<&Children>,
|
||||||
|
highlight_sprite_query: Query<(), With<Sprite>>,
|
||||||
|
) {
|
||||||
|
let Ok(parent_id) = collider_query.get(event.entity) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Ok(children) = parent_query.get(parent_id.0) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
if highlight_sprite_query.get(*child).is_ok() {
|
||||||
|
commands.entity(*child).insert(Visibility::Visible);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commands.entity(parent_id.0).insert(Visibility::Hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_padlock_collision_stopped(
|
||||||
|
event: On<CollisionStoppedEvent>,
|
||||||
|
mut commands: Commands,
|
||||||
|
collider_query: Query<&ChildOf, With<Collider>>,
|
||||||
|
parent_query: Query<&Children>,
|
||||||
|
highlight_sprite_query: Query<(), With<Sprite>>,
|
||||||
|
) {
|
||||||
|
let Ok(parent_id) = collider_query.get(event.entity) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Ok(children) = parent_query.get(parent_id.0) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
if highlight_sprite_query.get(*child).is_ok() {
|
||||||
|
commands.entity(*child).insert(Visibility::Hidden);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commands.entity(parent_id.0).insert(Visibility::Visible);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn padlock_bundle(textures: &Res<LayoutTextures>, facing_left: bool) -> impl Bundle {
|
pub fn padlock_bundle(textures: &Res<LayoutTextures>, facing_left: bool) -> impl Bundle {
|
||||||
let sign = if facing_left { -1. } else { 1. };
|
let sign = if facing_left { -1. } else { 1. };
|
||||||
(
|
(
|
||||||
|
|
@ -57,14 +105,17 @@ pub fn padlock_bundle(textures: &Res<LayoutTextures>, facing_left: bool) -> impl
|
||||||
flip_x: !facing_left,
|
flip_x: !facing_left,
|
||||||
..textures.lock.sprite("main")
|
..textures.lock.sprite("main")
|
||||||
},
|
},
|
||||||
Transform::from_xyz(meters(sign * 0.125), meters(0.), 0.),
|
Transform::from_xyz(meters(sign * 0.125), meters(0.), 1.),
|
||||||
InheritedVisibility::VISIBLE,
|
InheritedVisibility::VISIBLE,
|
||||||
Children::spawn((
|
Children::spawn((
|
||||||
Spawn((
|
SpawnWith(move |parent: &mut RelatedSpawner<ChildOf>| {
|
||||||
Transform::from_xyz(meters(sign * 0.1875), 0., 0.),
|
parent.spawn((
|
||||||
Collider::cuboid(meters(0.1875), meters(1.)),
|
Transform::from_xyz(meters(sign * 0.1875), 0., 0.),
|
||||||
Sensor,
|
Collider::cuboid(meters(0.1875), meters(1.)),
|
||||||
)),
|
Sensor,
|
||||||
|
)).observe(on_padlock_collision_started)
|
||||||
|
.observe(on_padlock_collision_stopped);
|
||||||
|
}),
|
||||||
Spawn((
|
Spawn((
|
||||||
Sprite {
|
Sprite {
|
||||||
flip_x: !facing_left,
|
flip_x: !facing_left,
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,21 @@ pub struct LevelAssetHandle(Handle<asset::structs::LevelAsset>);
|
||||||
#[derive(EntityEvent, Reflect, Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(EntityEvent, Reflect, Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
#[reflect(Event, Debug, PartialEq, Clone)]
|
#[reflect(Event, Debug, PartialEq, Clone)]
|
||||||
pub struct InteractionEvent {
|
pub struct InteractionEvent {
|
||||||
|
#[event_target]
|
||||||
|
pub entity: Entity,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(EntityEvent, Reflect, Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
#[reflect(Event, Debug, PartialEq, Clone)]
|
||||||
|
pub struct CollisionStartedEvent {
|
||||||
|
#[event_target]
|
||||||
|
pub entity: Entity,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(EntityEvent, Reflect, Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
#[reflect(Event, Debug, PartialEq, Clone)]
|
||||||
|
pub struct CollisionStoppedEvent {
|
||||||
|
#[event_target]
|
||||||
pub entity: Entity,
|
pub entity: Entity,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,40 @@ pub fn on_stairs_interact(
|
||||||
player_transform.translation.y += offset.y;
|
player_transform.translation.y += offset.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_stairs_collision_started(
|
||||||
|
event: On<CollisionStartedEvent>,
|
||||||
|
mut commands: Commands,
|
||||||
|
collider_query: Query<&Children, With<StairCollider>>,
|
||||||
|
sprite_query: Query<(), With<Sprite>>,
|
||||||
|
) {
|
||||||
|
let Ok(children) = collider_query.get(event.entity) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
if sprite_query.get(*child).is_ok() {
|
||||||
|
commands.entity(*child).insert(Visibility::Visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_stairs_collision_stopped(
|
||||||
|
event: On<CollisionStoppedEvent>,
|
||||||
|
mut commands: Commands,
|
||||||
|
collider_query: Query<&Children, With<StairCollider>>,
|
||||||
|
sprite_query: Query<(), With<Sprite>>,
|
||||||
|
) {
|
||||||
|
let Ok(children) = collider_query.get(event.entity) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
if sprite_query.get(*child).is_ok() {
|
||||||
|
commands.entity(*child).insert(Visibility::Hidden);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stairs_bundle(
|
pub fn stairs_bundle(
|
||||||
textures: &Res<LayoutTextures>,
|
textures: &Res<LayoutTextures>,
|
||||||
position: Vec2,
|
position: Vec2,
|
||||||
|
|
@ -89,10 +123,11 @@ pub fn stairs_bundle(
|
||||||
Visibility::Hidden,
|
Visibility::Hidden,
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
));
|
)).observe(on_stairs_collision_started)
|
||||||
|
.observe(on_stairs_collision_stopped);
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
stairs.sprite("main"),
|
stairs.sprite("main"),
|
||||||
Transform::from_xyz(0., meters(1.5), 0.),
|
Transform::from_xyz(0., meters(1.5), -1.),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,11 +139,15 @@ pub fn stairs_bundle(
|
||||||
InheritedVisibility::VISIBLE,
|
InheritedVisibility::VISIBLE,
|
||||||
Children::spawn(
|
Children::spawn(
|
||||||
Spawn((
|
Spawn((
|
||||||
stairs.sprite("down"),
|
Sprite {
|
||||||
|
flip_y: true,
|
||||||
|
..stairs.sprite("up")
|
||||||
|
},
|
||||||
Visibility::Hidden,
|
Visibility::Hidden,
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
));
|
)).observe(on_stairs_collision_started)
|
||||||
|
.observe(on_stairs_collision_stopped);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
|
|
|
||||||
|
|
@ -54,19 +54,35 @@ pub fn detect_interact_collisions(
|
||||||
for collision_event in collision_events.read() {
|
for collision_event in collision_events.read() {
|
||||||
match collision_event {
|
match collision_event {
|
||||||
CollisionEvent::Started(first, second, _) => {
|
CollisionEvent::Started(first, second, _) => {
|
||||||
if let Some(interactive_id) = interact_collisions_inner(*first, *second, interactive_query1, player_query, parent_query) {
|
if let Some(interactive_id) = interact_collisions_inner(
|
||||||
|
*first,
|
||||||
|
*second,
|
||||||
|
interactive_query1,
|
||||||
|
player_query,
|
||||||
|
parent_query
|
||||||
|
) {
|
||||||
commands.entity(interactive_id).insert(MayInteract);
|
commands.entity(interactive_id).insert(MayInteract);
|
||||||
|
commands.trigger(CollisionStartedEvent { entity: *first });
|
||||||
}
|
}
|
||||||
if let Some(interactive_id) = interact_collisions_inner(*second, *first, interactive_query1, player_query, parent_query) {
|
if let Some(interactive_id) = interact_collisions_inner(
|
||||||
|
*second,
|
||||||
|
*first,
|
||||||
|
interactive_query1,
|
||||||
|
player_query,
|
||||||
|
parent_query
|
||||||
|
) {
|
||||||
commands.entity(interactive_id).insert(MayInteract);
|
commands.entity(interactive_id).insert(MayInteract);
|
||||||
|
commands.trigger(CollisionStartedEvent { entity: *second });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CollisionEvent::Stopped(first, second, _) => {
|
CollisionEvent::Stopped(first, second, _) => {
|
||||||
if let Some(interactive_id) = interact_collisions_inner(*first, *second, interactive_query2, player_query, parent_query) {
|
if let Some(interactive_id) = interact_collisions_inner(*first, *second, interactive_query2, player_query, parent_query) {
|
||||||
commands.entity(interactive_id).remove::<MayInteract>();
|
commands.entity(interactive_id).remove::<MayInteract>();
|
||||||
|
commands.trigger(CollisionStoppedEvent { entity: *first });
|
||||||
}
|
}
|
||||||
if let Some(interactive_id) = interact_collisions_inner(*second, *first, interactive_query2, player_query, parent_query) {
|
if let Some(interactive_id) = interact_collisions_inner(*second, *first, interactive_query2, player_query, parent_query) {
|
||||||
commands.entity(interactive_id).remove::<MayInteract>();
|
commands.entity(interactive_id).remove::<MayInteract>();
|
||||||
|
commands.trigger(CollisionStoppedEvent { entity: *second });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -166,13 +182,6 @@ pub fn load_layout_textures(
|
||||||
uvec2(72, 8),
|
uvec2(72, 8),
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
indices.insert(
|
|
||||||
"down".to_owned(),
|
|
||||||
atlas.add_texture(URect::from_corners(
|
|
||||||
uvec2(64, 8),
|
|
||||||
uvec2(72, 16),
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
atlases.add(atlas)
|
atlases.add(atlas)
|
||||||
};
|
};
|
||||||
textures.stairs = AtlasLayoutTexture::new(image, atlas, indices);
|
textures.stairs = AtlasLayoutTexture::new(image, atlas, indices);
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ pub fn camera_bundle() -> impl Bundle {
|
||||||
..OrthographicProjection::default_2d()
|
..OrthographicProjection::default_2d()
|
||||||
}),
|
}),
|
||||||
Light2d {
|
Light2d {
|
||||||
ambient_light: AmbientLight2d { brightness: 0.25, ..default() }
|
ambient_light: AmbientLight2d { brightness: 0.1, ..default() }
|
||||||
},
|
},
|
||||||
Name::new("Camera2d"),
|
Name::new("Camera2d"),
|
||||||
)
|
)
|
||||||
|
|
@ -131,9 +131,6 @@ impl Plugin for ExpeditionPlugin {
|
||||||
.add_systems(OnEnter(GameState::Inventory), ui::inventory::systems::setup_ui_inventory)
|
.add_systems(OnEnter(GameState::Inventory), ui::inventory::systems::setup_ui_inventory)
|
||||||
.add_systems(OnExit(GameState::Inventory), ui::inventory::systems::clear_ui_inventory)
|
.add_systems(OnExit(GameState::Inventory), ui::inventory::systems::clear_ui_inventory)
|
||||||
.add_observer(ui::inventory::observers::on_ui_rotate)
|
.add_observer(ui::inventory::observers::on_ui_rotate)
|
||||||
.add_observer(layout::container::on_container_interact)
|
|
||||||
.add_observer(layout::door::on_door_interact)
|
|
||||||
.add_observer(layout::lock::on_padlock_interaction)
|
|
||||||
.add_observer(layout::stairs::on_stairs_interact);
|
.add_observer(layout::stairs::on_stairs_interact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use bevy_light_2d::prelude::*;
|
||||||
use bevy_rapier2d::prelude::*;
|
use bevy_rapier2d::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -39,6 +40,19 @@ pub fn player_bundle(asset_server: &Res<AssetServer>, position: Vec2) -> impl Bu
|
||||||
Inventory::new(UVec2::new(5, 3)),
|
Inventory::new(UVec2::new(5, 3)),
|
||||||
Inventory::new(UVec2::new(4, 4)),
|
Inventory::new(UVec2::new(4, 4)),
|
||||||
camera_bundle(),
|
camera_bundle(),
|
||||||
|
(
|
||||||
|
SpotLight2d {
|
||||||
|
color: Color::linear_rgb(0.98, 0.98, 0.824),
|
||||||
|
intensity: 1.,
|
||||||
|
radius: meters(6.),
|
||||||
|
source_width: 0.,
|
||||||
|
cast_shadows: true,
|
||||||
|
falloff: meters(8.),
|
||||||
|
direction: 0.,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
Transform::from_xyz(meters(0.1875), meters(0.625), 0.),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,21 @@ pub fn handle_input(
|
||||||
state: Res<State<GameState>>,
|
state: Res<State<GameState>>,
|
||||||
mut next_state: ResMut<NextState<GameState>>,
|
mut next_state: ResMut<NextState<GameState>>,
|
||||||
interactables: Query<Entity, With<MayInteract>>,
|
interactables: Query<Entity, With<MayInteract>>,
|
||||||
mut player: Query<(&Player, &mut ActionState<Action>, &mut KinematicCharacterController, &mut Sprite)>,
|
mut player: Query<(
|
||||||
|
&Player,
|
||||||
|
&mut ActionState<Action>,
|
||||||
|
&mut KinematicCharacterController,
|
||||||
|
&mut Sprite,
|
||||||
|
&Children
|
||||||
|
)>,
|
||||||
|
mut player_light: Query<(&mut SpotLight2d, &mut Transform)>,
|
||||||
) {
|
) {
|
||||||
let Ok(player) = player.single_mut() else {
|
let Ok(player) = player.single_mut() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
match state.get() {
|
match state.get() {
|
||||||
GameState::Running => {
|
GameState::Running => {
|
||||||
let (Player {speed}, mut action_state, mut controller, mut sprite) = player;
|
let (Player {speed}, mut action_state, mut controller, mut sprite, children) = player;
|
||||||
|
|
||||||
if action_state.just_released(&Action::ToggleInventory) {
|
if action_state.just_released(&Action::ToggleInventory) {
|
||||||
next_state.set(GameState::Inventory);
|
next_state.set(GameState::Inventory);
|
||||||
|
|
@ -35,7 +42,18 @@ pub fn handle_input(
|
||||||
|
|
||||||
controller.translation = Some(vec2(direction * speed * time.delta_secs(), 0.));
|
controller.translation = Some(vec2(direction * speed * time.delta_secs(), 0.));
|
||||||
if direction != 0f32 {
|
if direction != 0f32 {
|
||||||
sprite.flip_x = direction < 0f32;
|
let facing_left = direction < 0f32;
|
||||||
|
sprite.flip_x = facing_left;
|
||||||
|
for child in children {
|
||||||
|
if let Ok((mut spotlight, mut transform)) = player_light.get_mut(*child) {
|
||||||
|
spotlight.direction = if facing_left { 180. } else { 0. };
|
||||||
|
let last_x = transform.translation.x;
|
||||||
|
if last_x < 0. && !facing_left || last_x > 0. && facing_left {
|
||||||
|
transform.translation.x = -transform.translation.x;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if action_state.just_released(&Action::Interact) {
|
if action_state.just_released(&Action::Interact) {
|
||||||
|
|
@ -46,7 +64,7 @@ pub fn handle_input(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GameState::Inventory => {
|
GameState::Inventory => {
|
||||||
let (_, mut action_state, _, _) = player;
|
let (_, mut action_state, _, _, _) = player;
|
||||||
if action_state.just_released(&Action::ToggleInventory)
|
if action_state.just_released(&Action::ToggleInventory)
|
||||||
|| action_state.just_released(&Action::Interact) {
|
|| action_state.just_released(&Action::Interact) {
|
||||||
next_state.set(GameState::Running);
|
next_state.set(GameState::Running);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue