74 lines
2.2 KiB
Rust
74 lines
2.2 KiB
Rust
use crate::{
|
|
GameState, billboards::Billboard, global_observer, loading_assets::GameAssets,
|
|
physics_layers::GameLayer, player::Player, sounds::PlaySound,
|
|
squish_animation::SquishAnimation,
|
|
};
|
|
use avian3d::prelude::*;
|
|
use bevy::prelude::*;
|
|
use std::f32::consts::PI;
|
|
|
|
#[derive(Event, Reflect)]
|
|
pub struct KeySpawn(pub Vec3, pub String);
|
|
|
|
#[derive(Component, Reflect)]
|
|
#[reflect(Component)]
|
|
struct Key(pub String);
|
|
|
|
#[derive(Event, Reflect)]
|
|
pub struct KeyCollected(pub String);
|
|
|
|
pub fn plugin(app: &mut App) {
|
|
app.add_systems(Update, collect_key.run_if(in_state(GameState::Playing)));
|
|
|
|
global_observer!(app, on_spawn_key);
|
|
}
|
|
|
|
fn on_spawn_key(trigger: Trigger<KeySpawn>, mut commands: Commands, assets: Res<GameAssets>) {
|
|
let KeySpawn(position, id) = trigger.event();
|
|
|
|
let angle = rand::random::<f32>() * PI * 2.;
|
|
let spawn_dir = Quat::from_rotation_y(angle) * Vec3::new(0.5, 0.6, 0.).normalize();
|
|
|
|
commands.spawn((
|
|
Name::new("key"),
|
|
Key(id.clone()),
|
|
Transform::from_translation(*position),
|
|
Visibility::default(),
|
|
Collider::sphere(1.5),
|
|
ExternalImpulse::new(spawn_dir * 180.).with_persistence(false),
|
|
LockedAxes::ROTATION_LOCKED,
|
|
RigidBody::Dynamic,
|
|
CollisionLayers::new(LayerMask(GameLayer::Collectibles.to_bits()), LayerMask::ALL),
|
|
CollisionEventsEnabled,
|
|
Restitution::new(0.6),
|
|
Children::spawn(Spawn((
|
|
Billboard,
|
|
SquishAnimation(2.6),
|
|
SceneRoot(assets.mesh_key.clone()),
|
|
))),
|
|
));
|
|
}
|
|
|
|
fn collect_key(
|
|
mut commands: Commands,
|
|
mut collision_event_reader: EventReader<CollisionStarted>,
|
|
query_player: Query<&Player>,
|
|
query_collectable: Query<&Key>,
|
|
) {
|
|
for CollisionStarted(e1, e2) in collision_event_reader.read() {
|
|
let collectable = if query_player.contains(*e1) && query_collectable.contains(*e2) {
|
|
*e2
|
|
} else if query_player.contains(*e2) && query_collectable.contains(*e1) {
|
|
*e1
|
|
} else {
|
|
continue;
|
|
};
|
|
|
|
let key = query_collectable.get(collectable).unwrap();
|
|
|
|
commands.trigger(PlaySound::KeyCollect);
|
|
commands.trigger(KeyCollected(key.0.clone()));
|
|
commands.entity(collectable).despawn();
|
|
}
|
|
}
|