Add ship thruster sound
The player's Ship now has an AudioPlayer component constantly looping a thruster sound effect. It starts paused and is only resumed when the player fires the thruster. As noted in the TODO comment at the top of the input_ship_thruster(...) system, I need to figure out if I want to start using the `Single<>` query parameter instead of a `Query<>` and then doing my own null-ability checks (like what it does now).
This commit is contained in:
24
src/lib.rs
24
src/lib.rs
@@ -111,14 +111,28 @@ fn spawn_camera(mut commands: Commands) {
|
||||
/// Checks if "W" is pressed and increases velocity accordingly.
|
||||
fn input_ship_thruster(
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||
mut query: Query<(&mut physics::Velocity, &Transform, &mut Children), With<Ship>>,
|
||||
mut query: Query<
|
||||
(
|
||||
&mut physics::Velocity,
|
||||
&Transform,
|
||||
Option<&mut AudioSink>,
|
||||
&mut Children,
|
||||
),
|
||||
With<Ship>,
|
||||
>,
|
||||
mut commands: Commands,
|
||||
game_assets: Res<GameAssets>,
|
||||
) {
|
||||
// TODO: Maybe change for a Single<Ship>> so this only runs for the one ship
|
||||
// buuut... that would silently do nothing if there are 0 or >1 ships, and
|
||||
// I might want to crash on purpose in that case.
|
||||
let Ok((mut velocity, transform, children)) = query.single_mut() else {
|
||||
//
|
||||
// The AudioSink component doesn't exist for just one frame, forcing it to
|
||||
// be an optional system parameter. I'm not sure if I want to guard it with
|
||||
// a check like it does now, or finally switch to using a Single<...> query
|
||||
// parameter. I would lose ship control if the sound sink didn't spawn, but
|
||||
// that should be fine -- any time that fails, more has likely also failed.
|
||||
let Ok((mut velocity, transform, audio, children)) = query.single_mut() else {
|
||||
let count = query.iter().count();
|
||||
panic!("There should be exactly one player ship! Instead, there seems to be {count}.");
|
||||
};
|
||||
@@ -132,10 +146,16 @@ fn input_ship_thruster(
|
||||
commands
|
||||
.entity(*thrusters)
|
||||
.insert(MeshMaterial2d(game_assets.thruster_mat_active()));
|
||||
if let Some(audio) = audio {
|
||||
audio.play();
|
||||
}
|
||||
} else {
|
||||
commands
|
||||
.entity(*thrusters)
|
||||
.insert(MeshMaterial2d(game_assets.thruster_mat_inactive()));
|
||||
if let Some(audio) = audio {
|
||||
audio.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -168,6 +168,12 @@ pub fn spawn_player(mut commands: Commands, game_assets: Res<GameAssets>) {
|
||||
Mesh2d(game_assets.ship().0),
|
||||
MeshMaterial2d(game_assets.ship().1),
|
||||
Transform::default().with_scale(Vec3::new(20.0, 20.0, 20.0)),
|
||||
AudioPlayer::new(game_assets.ship_thruster_sound()),
|
||||
PlaybackSettings {
|
||||
mode: bevy::audio::PlaybackMode::Loop,
|
||||
paused: true,
|
||||
..Default::default()
|
||||
},
|
||||
))
|
||||
.with_child((
|
||||
Mesh2d(game_assets.thruster_mesh()),
|
||||
|
||||
@@ -58,7 +58,7 @@ impl Default for WorldSize {
|
||||
pub struct GameAssets {
|
||||
meshes: [Handle<Mesh>; 5],
|
||||
materials: [Handle<ColorMaterial>; 7],
|
||||
sounds: [Handle<AudioSource>; 3],
|
||||
sounds: [Handle<AudioSource>; 4],
|
||||
}
|
||||
|
||||
impl GameAssets {
|
||||
@@ -109,6 +109,10 @@ impl GameAssets {
|
||||
pub fn asteroid_crack_sound(&self) -> Handle<AudioSource> {
|
||||
self.sounds[2].clone()
|
||||
}
|
||||
|
||||
pub fn ship_thruster_sound(&self) -> Handle<AudioSource> {
|
||||
self.sounds[3].clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWorld for GameAssets {
|
||||
@@ -141,6 +145,7 @@ impl FromWorld for GameAssets {
|
||||
loader.load("explosionCrunch_004.ogg"),
|
||||
loader.load("laserSmall_001.ogg"),
|
||||
loader.load("explosionCrunch_000.ogg"),
|
||||
loader.load("thrusterFire_004.ogg"),
|
||||
];
|
||||
GameAssets {
|
||||
meshes,
|
||||
|
||||
Reference in New Issue
Block a user