enemy can drop key
This commit is contained in:
80
src/keys.rs
Normal file
80
src/keys.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use crate::player::Player;
|
||||
use avian3d::prelude::*;
|
||||
use bevy::prelude::*;
|
||||
use std::f32::consts::PI;
|
||||
|
||||
#[derive(Event, Reflect)]
|
||||
pub struct KeySpawn(pub Vec3);
|
||||
|
||||
#[derive(Component, Reflect)]
|
||||
#[reflect(Component)]
|
||||
struct Key;
|
||||
|
||||
#[derive(Event, Reflect)]
|
||||
pub struct KeyCollected;
|
||||
|
||||
pub fn plugin(app: &mut App) {
|
||||
app.add_systems(Update, collect_key);
|
||||
app.add_observer(on_spawn);
|
||||
}
|
||||
|
||||
fn on_spawn(
|
||||
trigger: Trigger<KeySpawn>,
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
let KeySpawn(position) = trigger.event();
|
||||
|
||||
let mesh = meshes.add(Cylinder::default());
|
||||
|
||||
//TODO: randomize
|
||||
let spawn_dir = Quat::from_rotation_y(PI / 2.) * Vec3::new(0.5, 0.6, 0.).normalize();
|
||||
|
||||
commands
|
||||
.spawn((
|
||||
Name::new("key"),
|
||||
Key,
|
||||
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((
|
||||
Transform::from_scale(Vec3::new(2.2, 0.4, 2.2))
|
||||
.with_rotation(Quat::from_rotation_x(PI / 2.)),
|
||||
Mesh3d(mesh),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0., 0., 0.9))),
|
||||
));
|
||||
}
|
||||
|
||||
fn collect_key(
|
||||
mut commands: Commands,
|
||||
mut collision_event_reader: EventReader<CollisionStarted>,
|
||||
query_player: Query<&Player>,
|
||||
query_collectable: Query<&Key>,
|
||||
asset_server: Res<AssetServer>,
|
||||
) {
|
||||
for CollisionStarted(e1, e2) in collision_event_reader.read() {
|
||||
let collectable = if query_player.contains(*e1) && query_collectable.contains(*e2) {
|
||||
Some(*e2)
|
||||
} else if query_player.contains(*e2) && query_collectable.contains(*e1) {
|
||||
Some(*e1)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(collectable) = collectable {
|
||||
commands.spawn((
|
||||
AudioPlayer::new(asset_server.load("sfx/effects/key_collect.ogg")),
|
||||
PlaybackSettings::DESPAWN,
|
||||
));
|
||||
|
||||
commands.trigger(KeyCollected);
|
||||
commands.entity(collectable).despawn_recursive();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user