From ab0c3339358662701f5fc24f8f71ec86664ff581 Mon Sep 17 00:00:00 2001 From: cool-mist Date: Wed, 4 Jun 2025 16:05:11 +0530 Subject: [PATCH] Add sounds --- Cargo.lock | 98 +++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +- assets/button.wav | Bin 0 -> 16802 bytes assets/click.wav | Bin 0 -> 1377 bytes assets/loss.wav | Bin 0 -> 10552 bytes assets/mode.wav | Bin 0 -> 13745 bytes assets/win.wav | Bin 0 -> 18412 bytes src/game.rs | 19 +++++++-- src/game/button.rs | 7 +++- src/game/sound.rs | 9 +++++ src/main.rs | 21 ++++++++-- 11 files changed, 147 insertions(+), 10 deletions(-) create mode 100644 assets/button.wav create mode 100644 assets/click.wav create mode 100644 assets/loss.wav create mode 100644 assets/mode.wav create mode 100644 assets/win.wav create mode 100644 src/game/sound.rs diff --git a/Cargo.lock b/Cargo.lock index 7a59f33..d2080a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,6 +52,24 @@ dependencies = [ "serde", ] +[[package]] +name = "audir-sles" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea47348666a8edb7ad80cbee3940eb2bccf70df0e6ce09009abe1a836cb779f5" + +[[package]] +name = "audrey" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58b92a84e89497e3cd25d3672cd5d1c288abaac02c18ff21283f17d118b889b8" +dependencies = [ + "dasp_frame", + "dasp_sample", + "hound", + "lewton", +] + [[package]] name = "autocfg" version = "1.4.0" @@ -103,6 +121,21 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "dasp_frame" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a3937f5fe2135702897535c8d4a5553f8b116f76c1529088797f2eee7c5cd6" +dependencies = [ + "dasp_sample", +] + +[[package]] +name = "dasp_sample" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" + [[package]] name = "fdeflate" version = "0.3.7" @@ -159,6 +192,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hound" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" + [[package]] name = "image" version = "0.24.9" @@ -172,6 +211,17 @@ dependencies = [ "png", ] +[[package]] +name = "lewton" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d542c1a317036c45c2aa1cf10cc9d403ca91eb2d333ef1a4917e5cb10628bd0" +dependencies = [ + "byteorder", + "ogg", + "smallvec", +] + [[package]] name = "libc" version = "0.2.169" @@ -190,6 +240,7 @@ dependencies = [ "macroquad_macro", "miniquad", "quad-rand", + "quad-snd", "slotmap", ] @@ -208,6 +259,12 @@ dependencies = [ "libc", ] +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + [[package]] name = "miniquad" version = "0.4.6" @@ -254,6 +311,15 @@ dependencies = [ "malloc_buf", ] +[[package]] +name = "ogg" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e571c3517af9e1729d4c63571a27edd660ade0667973bfc74a67c660c2b651" +dependencies = [ + "byteorder", +] + [[package]] name = "once_cell" version = "1.20.2" @@ -291,12 +357,34 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quad-alsa-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66c2f04a6946293477973d85adc251d502da51c57b08cd9c997f0cfd8dcd4b5" +dependencies = [ + "libc", +] + [[package]] name = "quad-rand" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a651516ddc9168ebd67b24afd085a718be02f8858fe406591b013d101ce2f40" +[[package]] +name = "quad-snd" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cba0c4943fc67147fbe9d1eb731fb9e678bfc9d926507eebbbfe0103e154e5b0" +dependencies = [ + "audir-sles", + "audrey", + "libc", + "quad-alsa-sys", + "winapi", +] + [[package]] name = "quote" version = "1.0.38" @@ -382,12 +470,22 @@ dependencies = [ "version_check", ] +[[package]] +name = "smallvec" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +dependencies = [ + "maybe-uninit", +] + [[package]] name = "sol_chess" version = "0.1.1" dependencies = [ "argh", "macroquad", + "quad-snd", "rand", ] diff --git a/Cargo.toml b/Cargo.toml index bcb16e1..bab21a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,8 @@ default-run = "sol_chess" [dependencies] argh = "0.1.13" -macroquad = "0.4.13" +macroquad = { version = "0.4.13", features = ["audio"] } +quad-snd = "0.2.8" [dev-dependencies] rand = "0.9.1" diff --git a/assets/button.wav b/assets/button.wav new file mode 100644 index 0000000000000000000000000000000000000000..775cbb239f805a1dc9dbcbb8b39c993248ea3613 GIT binary patch literal 16802 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 literal 0 HcmV?d00001 diff --git a/assets/click.wav b/assets/click.wav new file mode 100644 index 0000000000000000000000000000000000000000..c0fa5e3c79cead51dd7adf90df2591f23e99533c GIT binary patch literal 1377 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 X8C6?bTMyUK2(uET3yvXLv5*Y_!TyC! literal 0 HcmV?d00001 diff --git a/assets/mode.wav b/assets/mode.wav new file mode 100644 index 0000000000000000000000000000000000000000..5b4f87341ab2902c164614ef89a9d244dbdb8df0 GIT binary patch literal 13745 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 ZJh&VZ11y0`Aj!g*s0zS5m=uC;001h*$uj@| literal 0 HcmV?d00001 diff --git a/src/game.rs b/src/game.rs index 4f15dae..d2683f0 100644 --- a/src/game.rs +++ b/src/game.rs @@ -5,17 +5,19 @@ use std::{ use button::Button; use color::UiColor; -use macroquad::{math, prelude::*, rand}; +use macroquad::{audio, math, prelude::*, rand}; use shadow::draw_shadow; use sol_chess::{ board::{Board, BoardState}, generator::{self, RandomRange}, }; +use sound::Sounds; use texture::PieceTexture; pub mod button; pub mod color; pub mod shadow; +pub mod sound; pub mod texture; pub struct MacroquadRandAdapter; @@ -34,6 +36,7 @@ pub struct Game { // Constants througout the game texture_res: Texture2D, + sounds: Sounds, num_squares: usize, heading_text: String, @@ -88,7 +91,7 @@ enum GameState { } impl Game { - pub fn new(texture_res: Texture2D) -> Self { + pub fn new(texture_res: Texture2D, sounds: Sounds) -> Self { let num_squares: usize = 4; let game_mode = GameMode::Medium; let board = Game::generate_puzzle(game_mode); @@ -103,6 +106,7 @@ impl Game { heading_font_size: 0., num_squares, texture_res, + sounds, state: GameState::SelectSource(None), game_mode, debug: false, @@ -432,6 +436,7 @@ impl Game { "Reset", Rect::new(board_x + btn_x_offset, btn_y, btn_w, btn_h), UiColor::Yellow, + self.sounds.button.clone(), ); let mut next_btn = Button::new( "Next", @@ -442,6 +447,7 @@ impl Game { btn_h, ), UiColor::Green, + self.sounds.button.clone(), ); next_btn.is_active = false; @@ -454,6 +460,7 @@ impl Game { btn_h, ), UiColor::Brown, + self.sounds.button.clone(), ); self.rules_btn = vec![rules_button]; @@ -470,6 +477,7 @@ impl Game { btn_h, ), UiColor::Yellow, + self.sounds.mode.clone(), ); let medium_btn = Button::new( @@ -481,6 +489,7 @@ impl Game { btn_h, ), UiColor::Yellow, + self.sounds.mode.clone(), ); let hard_button = Button::new( @@ -492,6 +501,7 @@ impl Game { btn_h, ), UiColor::Yellow, + self.sounds.mode.clone(), ); self.mode_btns = HashMap::new(); @@ -586,7 +596,6 @@ impl Game { }); let m = m.expect("legal move should be found"); - self.board.make_move(m.clone()); if self.board.game_state == BoardState::Won || self.board.game_state == BoardState::Lost @@ -598,6 +607,9 @@ impl Game { .get_mut(&ButtonAction::Next) .expect("Cannot find next button"); next_btn.is_active = true; + audio::play_sound_once(&self.sounds.win); + } else { + audio::play_sound_once(&self.sounds.loss); } return GameState::GameOver((x, y)); @@ -605,6 +617,7 @@ impl Game { self.reset_squares(); self.get(x, y).is_target = true; + audio::play_sound_once(&self.sounds.click); return GameState::SelectSource(Some((x, y))); } diff --git a/src/game/button.rs b/src/game/button.rs index dbe987a..f2e7dd1 100644 --- a/src/game/button.rs +++ b/src/game/button.rs @@ -1,4 +1,4 @@ -use macroquad::prelude::*; +use macroquad::{audio::{self, Sound}, prelude::*}; use super::{color::UiColor, shadow::draw_shadow}; @@ -10,10 +10,11 @@ pub struct Button { rect: Rect, shadow_width: f32, pub color: UiColor, + sound: Sound, } impl Button { - pub fn new(text: &str, rect: Rect, color: UiColor) -> Self { + pub fn new(text: &str, rect: Rect, color: UiColor, sound: Sound) -> Self { Self { text: text.to_string(), is_down: false, @@ -22,6 +23,7 @@ impl Button { rect, shadow_width: 5.0, color, + sound, } } @@ -117,6 +119,7 @@ impl Button { if is_mouse_button_released(MouseButton::Left) { if c.overlaps_rect(&self.rect) { self.is_clicked = true; + audio::play_sound_once(&self.sound); self.is_down = false; return; } diff --git a/src/game/sound.rs b/src/game/sound.rs new file mode 100644 index 0000000..40dd6d8 --- /dev/null +++ b/src/game/sound.rs @@ -0,0 +1,9 @@ +use macroquad::audio::Sound; + +pub struct Sounds { + pub click: Sound, + pub win: Sound, + pub loss: Sound, + pub button: Sound, + pub mode: Sound, +} diff --git a/src/main.rs b/src/main.rs index c28ea0b..39910f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ -use game::Game; -use macroquad::prelude::*; +use game::{sound::Sounds, Game}; +use macroquad::{audio, prelude::*}; use miniquad::date; mod game; @@ -30,12 +30,25 @@ async fn main() { } } +macro_rules! load_sound { + ($file_name:expr) => { + audio::load_sound_from_bytes(include_bytes!($file_name)) + .await + .unwrap() + }; +} + async fn init() -> Game { let texture_bytes = include_bytes!("../assets/pieces.png"); let texture_res = Texture2D::from_file_with_format(&texture_bytes[..], None); texture_res.set_filter(FilterMode::Nearest); build_textures_atlas(); - let game = Game::new(texture_res); - + let click = load_sound!("../assets/click.wav"); + let win = load_sound!("../assets/win.wav"); + let loss = load_sound!("../assets/loss.wav"); + let button = load_sound!("../assets/button.wav"); + let mode = load_sound!("../assets/mode.wav"); + let sounds = Sounds { click, win, loss, button, mode }; + let game = Game::new(texture_res, sounds); game }