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 0000000..775cbb2 Binary files /dev/null and b/assets/button.wav differ diff --git a/assets/click.wav b/assets/click.wav new file mode 100644 index 0000000..c0fa5e3 Binary files /dev/null and b/assets/click.wav differ diff --git a/assets/loss.wav b/assets/loss.wav new file mode 100644 index 0000000..575f8b1 Binary files /dev/null and b/assets/loss.wav differ diff --git a/assets/mode.wav b/assets/mode.wav new file mode 100644 index 0000000..5b4f873 Binary files /dev/null and b/assets/mode.wav differ diff --git a/assets/win.wav b/assets/win.wav new file mode 100644 index 0000000..d255fc0 Binary files /dev/null and b/assets/win.wav differ 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 }