Files
HEDZReloaded/src/keys.rs

69 lines
2.1 KiB
Rust

use crate::{
GameState, billboards::Billboard, 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)));
app.add_observer(on_spawn);
}
fn on_spawn(trigger: Trigger<KeySpawn>, mut commands: Commands, asset_server: Res<AssetServer>) {
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();
let mesh = asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/key.glb"));
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,
Restitution::new(0.6),
))
.with_child((Billboard, SquishAnimation(2.6), SceneRoot(mesh)));
}
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_recursive();
}
}