Add basic game sounds

This commit is contained in:
2023-03-18 12:31:53 +01:00
parent 09125bcd2f
commit 5d92c82db4
9 changed files with 154 additions and 63 deletions

12
src/audio.rs Normal file
View File

@@ -0,0 +1,12 @@
use bevy::prelude::*;
use bevy_asset_loader::prelude::*;
#[derive(AssetCollection, Resource)]
pub struct Assets {
#[asset(path = "sounds/collision.wav")]
pub collision: Handle<AudioSource>,
#[asset(path = "sounds/tick.wav")]
pub tick: Handle<AudioSource>,
#[asset(path = "sounds/blip.wav")]
pub blip: Handle<AudioSource>,
}

View File

@@ -6,12 +6,14 @@ use crate::{
ui::UiPlugin,
};
use bevy::{prelude::*, render::camera::ScalingMode, window::WindowResolution};
use bevy_asset_loader::prelude::*;
use bevy_tweening::TweeningPlugin;
use std::time::Duration;
#[cfg(debug_assertions)]
use bevy_editor_pls::prelude::*;
mod audio;
mod canvas;
mod fruit;
mod grid;
@@ -22,7 +24,6 @@ const ASPECT_RATIO: f32 = 16. / 9.;
const WINDOW_WIDTH: f32 = WINDOW_HEIGHT * ASPECT_RATIO;
const WINDOW_HEIGHT: f32 = 720.;
const TICK_PERIOD: Duration = Duration::from_millis(125);
const CLEAR_COLOR: Color = Color::rgba(0.15, 0.15, 0.15, 1.0);
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)]
enum GameState {
@@ -38,7 +39,7 @@ struct Score(u32);
fn main() {
let mut app = App::new();
app.insert_resource(ClearColor(CLEAR_COLOR))
app.insert_resource(ClearColor(Color::BLACK))
.insert_resource(FixedTime::new(TICK_PERIOD))
.insert_resource(Score(0))
.add_plugins(DefaultPlugins.set(WindowPlugin {
@@ -50,6 +51,7 @@ fn main() {
}),
..Default::default()
}))
.init_collection::<audio::Assets>()
.add_state::<GameState>()
.add_plugin(TweeningPlugin)
.add_plugin(SnakePlugin)
@@ -81,10 +83,6 @@ fn setup_system(mut commands: Commands) {
},
..Default::default()
},
camera: Camera {
hdr: true,
..Default::default()
},
..Default::default()
})
.insert(Name::new("Orthographic Camera"));

View File

@@ -3,7 +3,7 @@ mod bulge;
mod direction;
mod movement;
use crate::{fruit, grid, GameState};
use crate::{audio, fruit, grid, GameState};
use bevy::prelude::*;
use direction::Direction;
use itertools::Itertools;
@@ -57,7 +57,24 @@ impl Plugin for SnakePlugin {
.in_schedule(CoreSchedule::FixedUpdate)
.in_set(SystemSet::CollisionDetection)
.in_set(OnUpdate(GameState::InGame))
.after(collision_system),
.after(collision_system)
.run_if(about_to_collide),
)
.add_system(
collision_sound_system
.run_if(in_state(GameState::InGame))
.run_if(about_to_collide),
)
.add_system(
tick_sound_system
.in_schedule(CoreSchedule::FixedUpdate)
.run_if(in_state(GameState::InGame))
.run_if(not(about_to_collide)),
)
.add_system(
blip_sound_system
.in_schedule(CoreSchedule::FixedUpdate)
.run_if(in_state(GameState::InGame)),
)
.add_system(direction::start_game_system.in_set(OnUpdate(GameState::Begin)))
.add_system(direction::change_direction_system)
@@ -104,11 +121,18 @@ struct Collision {
pub struct AddTailEvent;
fn create_snake_segment(commands: &mut Commands, grid_position: grid::Coordinate) -> Entity {
fn create_snake_segment(
commands: &mut Commands,
grid_position: grid::Coordinate,
segment_number: u32,
) -> Entity {
let mut color = Color::RED;
color *= 0.99f32.powi(segment_number as _);
commands
.spawn(SpriteBundle {
sprite: Sprite {
color: Color::RED,
color,
custom_size: Some(Vec2::splat(grid::SEGMENT_SIZE) * 0.9),
..Default::default()
},
@@ -122,7 +146,8 @@ fn create_snake_segment(commands: &mut Commands, grid_position: grid::Coordinate
}
fn setup_snake_system(mut commands: Commands) {
let snake_head = create_snake_segment(&mut commands, grid::Coordinate::splat(grid::SIZE / 2));
let snake_head =
create_snake_segment(&mut commands, grid::Coordinate::splat(grid::SIZE / 2), 0);
commands
.entity(snake_head)
@@ -164,11 +189,14 @@ fn add_tail_system(
mut tail_event_reader: EventReader<AddTailEvent>,
) {
for _ in tail_event_reader.iter() {
let segment =
create_snake_segment(&mut commands, grid::Coordinate::splat(grid::Index::MIN / 2));
let (snake_entity, mut segments) = snake_query.single_mut();
let segment = create_snake_segment(
&mut commands,
grid::Coordinate::splat(grid::Index::MIN / 2),
segments.0.len() as _,
);
segments.0.push(segment);
commands
@@ -232,12 +260,29 @@ fn collision_system(
}
}
fn game_over_system(
query: Query<&Collision, With<Snake>>,
mut next_state: ResMut<NextState<GameState>>,
fn about_to_collide(query: Query<&Collision, With<Snake>>) -> bool {
query.get_single().unwrap().about_to_collide
}
fn game_over_system(mut next_state: ResMut<NextState<GameState>>) {
next_state.set(GameState::End);
}
fn collision_sound_system(audio: Res<Audio>, audio_assets: Res<audio::Assets>) {
audio.play(audio_assets.collision.clone());
}
fn tick_sound_system(audio: Res<Audio>, audio_assets: Res<audio::Assets>) {
audio.play(audio_assets.tick.clone());
}
fn blip_sound_system(
audio: Res<Audio>,
audio_assets: Res<audio::Assets>,
mut eaten_event_reader: EventReader<fruit::EatenEvent>,
) {
if query.get_single().unwrap().about_to_collide {
next_state.set(GameState::End);
for _ in eaten_event_reader.iter() {
audio.play(audio_assets.blip.clone());
}
}