feat: Collision beginning

- Added system for detecting collisions with interactive objects
- Added interactive doors
This commit is contained in:
Alexey 2026-03-16 17:21:10 +03:00
commit 4c23a38b92
5 changed files with 524 additions and 10 deletions

347
Cargo.lock generated
View file

@ -107,6 +107,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "alsa"
version = "0.9.1"
@ -1019,7 +1025,7 @@ dependencies = [
"arrayvec",
"bevy_reflect",
"derive_more",
"glam",
"glam 0.30.10",
"itertools 0.14.0",
"libm",
"rand",
@ -1178,6 +1184,19 @@ version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f98cbc6d34bbdb58240b72ed1731931b4991a893b3a3238bb7c42ae054aa676"
[[package]]
name = "bevy_rapier2d"
version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0b8ac06b0333af78e706982e13a33cfbacb9225d735a33ae8130a4d735bdfc5"
dependencies = [
"bevy",
"bitflags 2.10.0",
"log",
"nalgebra",
"rapier2d",
]
[[package]]
name = "bevy_reflect"
version = "0.18.0"
@ -1194,7 +1213,7 @@ dependencies = [
"downcast-rs 2.0.2",
"erased-serde",
"foldhash 0.2.0",
"glam",
"glam 0.30.10",
"indexmap",
"inventory",
"petgraph",
@ -1279,7 +1298,7 @@ dependencies = [
"downcast-rs 2.0.2",
"encase",
"fixedbitset",
"glam",
"glam 0.30.10",
"image",
"indexmap",
"js-sys",
@ -2293,6 +2312,15 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "ena"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1"
dependencies = [
"log",
]
[[package]]
name = "encase"
version = "0.12.0"
@ -2399,6 +2427,7 @@ dependencies = [
"bevy",
"bevy_common_assets",
"bevy_input",
"bevy_rapier2d",
"leafwing-input-manager",
"serde",
"toml 1.0.3+spec-1.1.0",
@ -2650,6 +2679,96 @@ dependencies = [
"xml-rs",
]
[[package]]
name = "glam"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "333928d5eb103c5d4050533cec0384302db6be8ef7d3cebd30ec6a35350353da"
[[package]]
name = "glam"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3abb554f8ee44336b72d522e0a7fe86a29e09f839a36022fa869a7dfe941a54b"
[[package]]
name = "glam"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4126c0479ccf7e8664c36a2d719f5f2c140fbb4f9090008098d2c291fa5b3f16"
[[package]]
name = "glam"
version = "0.17.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01732b97afd8508eee3333a541b9f7610f454bb818669e66e90f5f57c93a776"
[[package]]
name = "glam"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "525a3e490ba77b8e326fb67d4b44b4bd2f920f44d4cc73ccec50adc68e3bee34"
[[package]]
name = "glam"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b8509e6791516e81c1a630d0bd7fbac36d2fa8712a9da8662e716b52d5051ca"
[[package]]
name = "glam"
version = "0.20.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f43e957e744be03f5801a55472f593d43fabdebf25a4585db250f04d86b1675f"
[[package]]
name = "glam"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "518faa5064866338b013ff9b2350dc318e14cc4fcd6cb8206d7e7c9886c98815"
[[package]]
name = "glam"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12f597d56c1bd55a811a1be189459e8fad2bbc272616375602443bdfb37fa774"
[[package]]
name = "glam"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e4afd9ad95555081e109fe1d21f2a30c691b5f0919c67dfa690a2e1eb6bd51c"
[[package]]
name = "glam"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945"
[[package]]
name = "glam"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3"
[[package]]
name = "glam"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9"
[[package]]
name = "glam"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "779ae4bf7e8421cf91c0b3b64e7e8b40b862fba4d393f59150042de7c4965a94"
[[package]]
name = "glam"
version = "0.29.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee"
[[package]]
name = "glam"
version = "0.30.10"
@ -2833,6 +2952,8 @@ version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash 0.1.5",
]
@ -2872,7 +2993,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29a164ceff4500f2a72b1d21beaa8aa8ad83aec2b641844c659b190cb3ea2e0b"
dependencies = [
"constgebra",
"glam",
"glam 0.30.10",
"tinyvec",
]
@ -3254,6 +3375,16 @@ dependencies = [
"regex-automata",
]
[[package]]
name = "matrixmultiply"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08"
dependencies = [
"autocfg",
"rawpointer",
]
[[package]]
name = "memchr"
version = "2.8.0"
@ -3354,6 +3485,49 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "nalgebra"
version = "0.34.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4d5b3eff5cd580f93da45e64715e8c20a3996342f1e466599cf7a267a0c2f5f"
dependencies = [
"approx",
"glam 0.14.0",
"glam 0.15.2",
"glam 0.16.0",
"glam 0.17.3",
"glam 0.18.0",
"glam 0.19.0",
"glam 0.20.5",
"glam 0.21.3",
"glam 0.22.0",
"glam 0.23.0",
"glam 0.24.2",
"glam 0.25.0",
"glam 0.27.0",
"glam 0.28.0",
"glam 0.29.3",
"glam 0.30.10",
"matrixmultiply",
"nalgebra-macros",
"num-complex",
"num-rational",
"num-traits",
"simba",
"typenum",
]
[[package]]
name = "nalgebra-macros"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "973e7178a678cfd059ccec50887658d482ce16b0aa9da3888ddeab5cd5eb4889"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "ndk"
version = "0.8.0"
@ -3465,6 +3639,25 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "num-bigint"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-complex"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
dependencies = [
"num-traits",
]
[[package]]
name = "num-derive"
version = "0.4.2"
@ -3476,6 +3669,26 @@ dependencies = [
"syn",
]
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [
"num-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
@ -3854,6 +4067,32 @@ dependencies = [
"windows-link 0.2.1",
]
[[package]]
name = "parry2d"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef681740349cec3ab9b5996b03b459b383b6998e1ffcb2804e8b57eb1e8491d9"
dependencies = [
"approx",
"arrayvec",
"bitflags 2.10.0",
"downcast-rs 2.0.2",
"either",
"ena",
"foldhash 0.2.0",
"hashbrown 0.16.1",
"log",
"nalgebra",
"num-derive",
"num-traits",
"ordered-float",
"simba",
"slab",
"smallvec",
"spade",
"thiserror 2.0.18",
]
[[package]]
name = "paste"
version = "1.0.15"
@ -4017,6 +4256,19 @@ name = "profiling"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
dependencies = [
"profiling-procmacros",
]
[[package]]
name = "profiling-procmacros"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "pxfm"
@ -4108,12 +4360,43 @@ version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68"
[[package]]
name = "rapier2d"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dbf9046b02ffdaff5a8b65405e5e557d71dfb13e74d335fcf9fd12ad6c503a7"
dependencies = [
"approx",
"arrayvec",
"bit-vec",
"bitflags 2.10.0",
"downcast-rs 2.0.2",
"log",
"nalgebra",
"num-derive",
"num-traits",
"ordered-float",
"parry2d",
"profiling",
"rustc-hash 2.1.1",
"simba",
"static_assertions",
"thiserror 2.0.18",
"wide",
]
[[package]]
name = "raw-window-handle"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
[[package]]
name = "rawpointer"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
[[package]]
name = "read-fonts"
version = "0.35.0"
@ -4203,6 +4486,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
name = "robust"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e27ee8bb91ca0adcf0ecb116293afa12d393f9c2b9b9cd54d33e8078fe19839"
[[package]]
name = "rodio"
version = "0.20.1"
@ -4295,6 +4584,15 @@ dependencies = [
"twox-hash",
]
[[package]]
name = "safe_arch"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323"
dependencies = [
"bytemuck",
]
[[package]]
name = "same-file"
version = "1.0.6"
@ -4424,6 +4722,19 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "simba"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95"
dependencies = [
"approx",
"num-complex",
"num-traits",
"paste",
"wide",
]
[[package]]
name = "simd-adler32"
version = "0.3.8"
@ -4521,6 +4832,18 @@ dependencies = [
"serde",
]
[[package]]
name = "spade"
version = "2.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb313e1c8afee5b5647e00ee0fe6855e3d529eb863a0fdae1d60006c4d1e9990"
dependencies = [
"hashbrown 0.15.5",
"num-traits",
"robust",
"smallvec",
]
[[package]]
name = "spin"
version = "0.10.0"
@ -4916,6 +5239,12 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "typewit"
version = "1.14.2"
@ -5361,6 +5690,16 @@ dependencies = [
"web-sys",
]
[[package]]
name = "wide"
version = "0.7.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03"
dependencies = [
"bytemuck",
"safe_arch",
]
[[package]]
name = "winapi"
version = "0.3.9"

View file

@ -9,6 +9,7 @@ edition = "2024"
bevy = { version = "0.18.0", features = ["bevy_remote", "debug", "experimental_bevy_ui_widgets"] }
bevy_common_assets = { version = "0.15.0", features = ["toml"] }
bevy_input = { version = "0.18.0", features = ["serde", "serialize"] }
bevy_rapier2d = { version = "0.33.0", features = ["rapier-debug-render"] }
leafwing-input-manager = "0.20.0"
serde = { version = "1.0.228", features = ["derive"] }
toml = "1.0.3"

View file

@ -1 +1,143 @@
use bevy::{ecs::query::QueryFilter, prelude::*};
use bevy_rapier2d::prelude::*;
use crate::{PIXELS_PER_METER, player::Player};
const DOOR_OPENED_ASSET: &'static str = "sprites/interactive/door_opened.png";
const DOOR_CLOSED_ASSET: &'static str = "sprites/interactive/door_closed.png";
#[derive(Component)]
pub struct MayInteract;
#[derive(Component, Default)]
pub struct InteractiveObject;
#[derive(Component)]
pub struct Wall;
#[derive(Component)]
#[require(Sprite, InteractiveObject)]
pub struct Door;
#[derive(EntityEvent)]
pub struct InteractionEvent {
pub entity: Entity,
}
fn get_interactive_id<F: QueryFilter>(
tested_id: Entity,
interactive_query: Query<(), F>,
parent_query: Query<&ChildOf, With<Collider>>,
) -> Option<Entity> {
if interactive_query.get(tested_id).is_ok() {
return Some(tested_id);
}
let Ok(parent_id) = parent_query.get(tested_id) else {
return None;
};
match interactive_query.get(parent_id.0) {
Ok(_) => Some(parent_id.0),
Err(_) => None,
}
}
pub fn detect_interact_collisions(
mut commands: Commands,
mut collision_events: MessageReader<CollisionEvent>,
player_query: Query<(), With<Player>>,
interactive_query1: Query<(), (With<InteractiveObject>, Without<MayInteract>)>,
interactive_query2: Query<(), (With<InteractiveObject>, With<MayInteract>)>,
parent_query: Query<&ChildOf, With<Collider>>,
) {
for collision_event in collision_events.read() {
match collision_event {
CollisionEvent::Started(first, second, _) => {
let Some(interactive_id) = get_interactive_id(*first, interactive_query1, parent_query) else {
continue;
};
if player_query.get(*second).is_err() {
continue;
}
commands.entity(interactive_id).insert(MayInteract);
},
CollisionEvent::Stopped(first, second, _) => {
let Some(interactive_id) = get_interactive_id(*first, interactive_query2, parent_query) else {
continue;
};
if player_query.get(*second).is_err() {
continue;
}
commands.entity(interactive_id).remove::<MayInteract>();
},
}
}
}
fn on_door_interact(
event: On<InteractionEvent>,
mut commands: Commands,
collider_query: Query<(), (With<Door>, With<Collider>)>,
no_collider_query: Query<(), (With<Door>, Without<Collider>)>,
mut sprite_query: Query<&mut Sprite, With<Door>>,
asset_server: Res<AssetServer>,
) {
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);
return;
};
let asset_path = if was_opened { DOOR_CLOSED_ASSET } else { DOOR_OPENED_ASSET };
sprite.image = asset_server.load(asset_path);
if was_opened {
commands.entity(event.entity).insert(door_collider());
} else {
commands.entity(event.entity).remove::<Collider>();
}
}
fn door_collider() -> Collider {
Collider::cuboid(PIXELS_PER_METER * 0.125, PIXELS_PER_METER)
}
fn door_bundle(image: Handle<Image>, position: Vec2) -> impl Bundle {
(
Door,
Sprite::from_image(image),
Transform::from_xyz(position.x, position.y, 0.),
Name::new(format!("Door ({}, {})", position.x, position.y)),
door_collider(),
Observer::new(on_door_interact),
children![
(
Collider::cuboid(PIXELS_PER_METER * 0.5, PIXELS_PER_METER),
Sensor,
Transform::from_xyz(0., 0., 0.),
),
],
)
}
fn wall_bundle(position: Vec2) -> impl Bundle {
(
Wall,
Transform::from_xyz(position.x, position.y, 0.),
Collider::cuboid(PIXELS_PER_METER * 0.5, PIXELS_PER_METER),
Name::new(format!("Wall ({}, {})", position.x, position.y)),
)
}
pub fn setup_world(
mut commands: Commands,
asset_server: Res<AssetServer>,
) {
let door_image = asset_server.load(DOOR_CLOSED_ASSET);
commands.spawn(door_bundle(door_image, vec2(128., 0.)));
commands.spawn(wall_bundle(vec2(-128., 0.)));
}

View file

@ -7,9 +7,12 @@ pub mod ui;
mod tests;
use bevy::{prelude::*, ui_widgets::ScrollbarPlugin};
use bevy_rapier2d::{prelude::*, rapier::prelude::IntegrationParameters};
use leafwing_input_manager::prelude::*;
use serde::{Deserialize, Serialize};
pub const PIXELS_PER_METER: f32 = 16.0;
pub struct ExpeditionPlugin;
#[derive(Actionlike, PartialEq, Eq, Hash, Debug, Clone, Reflect, Serialize, Deserialize)]
@ -87,15 +90,30 @@ impl Plugin for ExpeditionPlugin {
input::InputAssetPlugin::<InputAction>::default(),
input::InputAssetPlugin::<UiAction>::default(),
ScrollbarPlugin,
RapierPhysicsPlugin::<()>::default()
.with_custom_initialization(RapierContextInitialization::InitializeDefaultRapierContext {
integration_parameters: IntegrationParameters {
length_unit: PIXELS_PER_METER,
..default()
},
rapier_configuration: RapierConfiguration {
gravity: Vec2::ZERO,
physics_pipeline_active: true,
scaled_shape_subdivision: 10,
force_update_from_transform_changes: false,
},
}),
RapierDebugRenderPlugin::default(),
))
.init_state::<GameState>()
.insert_resource(ui::WindowSize::default())
.add_systems(Startup, (player::setup_player, setup_global))
.add_systems(Startup, (player::setup_player, setup_global, layout::setup_world))
.add_systems(Update, (
player::handle_input,
ui::update_window_size,
ui::handle_input,
insert_entity_name,
layout::detect_interact_collisions,
))
.add_systems(OnEnter(GameState::Inventory), inventory::ui::setup_ui_inventory)
.add_systems(OnExit(GameState::Inventory), inventory::ui::clear_ui_inventory)

View file

@ -1,7 +1,8 @@
use bevy::prelude::*;
use bevy_rapier2d::prelude::*;
use leafwing_input_manager::prelude::*;
use crate::{GameState, InputAction as Action, inventory::{ActiveInventory, Inventory, item::Item}};
use crate::{GameState, InputAction as Action, PIXELS_PER_METER, inventory::{ActiveInventory, Inventory, item::Item}, layout::{InteractionEvent, MayInteract}};
#[derive(Component, Reflect)]
pub struct Player {
@ -19,6 +20,11 @@ fn player_bundle(asset_server: &Res<AssetServer>) -> impl Bundle {
Transform::from_xyz(0f32, 0f32, 1f32),
Action::default_input_map(),
Name::new("Player"),
RigidBody::KinematicPositionBased,
KinematicCharacterController::default(),
ActiveCollisionTypes::default() | ActiveCollisionTypes::KINEMATIC_STATIC,
Collider::cuboid(PIXELS_PER_METER * 0.5, PIXELS_PER_METER),
ActiveEvents::COLLISION_EVENTS,
children![
(Inventory::new(UVec2::new(6, 2)), ActiveInventory),
(Inventory::new(UVec2::new(5, 3)), ActiveInventory),
@ -63,12 +69,13 @@ pub fn handle_input(
time: Res<Time>,
state: Res<State<GameState>>,
mut next_state: ResMut<NextState<GameState>>,
mut player: Query<(&Player, &mut ActionState<Action>, &mut Transform, &mut Sprite)>,
interactables: Query<Entity, With<MayInteract>>,
mut player: Query<(&Player, &mut ActionState<Action>, &mut KinematicCharacterController, &mut Sprite)>,
) {
let player = player.single_mut().expect("Player should be single");
match state.get() {
GameState::Running => {
let (Player {speed}, mut action_state, mut transform, mut sprite) = player;
let (Player {speed}, mut action_state, mut controller, mut sprite) = player;
if action_state.just_released(&Action::ToggleInventory) {
next_state.set(GameState::Inventory);
@ -77,13 +84,20 @@ pub fn handle_input(
let direction = action_state.clamped_value(&Action::Move);
transform.translation.x += direction * speed * time.delta_secs();
controller.translation = Some(vec2(direction * speed * time.delta_secs(), 0.));
if direction != 0f32 {
sprite.flip_x = direction < 0f32;
}
if action_state.just_pressed(&Action::Interact) {
commands.run_system_cached(try_insert_item);
let mut action_happened = false;
for interactable_id in interactables {
commands.trigger(InteractionEvent { entity: interactable_id });
action_happened = true;
}
if !action_happened {
commands.run_system_cached(try_insert_item);
}
}
},
GameState::Inventory => {