audio
This commit is contained in:
parent
7d6822cd34
commit
a19a9e9cc3
867
Cargo.lock
generated
867
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
rand = "0.9.0"
|
||||
rodio = "0.20.1"
|
||||
|
||||
[dependencies.sdl2]
|
||||
version = "0.37.0"
|
||||
|
4
src/gui.rs
Normal file
4
src/gui.rs
Normal file
@ -0,0 +1,4 @@
|
||||
mod audio;
|
||||
mod render;
|
||||
|
||||
pub use render::start_game;
|
74
src/gui/audio.rs
Normal file
74
src/gui/audio.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use std::{fs::File, io::BufReader, sync::mpsc};
|
||||
|
||||
use rodio::{Decoder, OutputStream, OutputStreamHandle, Sink, Source};
|
||||
|
||||
use crate::game::SoundEffect;
|
||||
|
||||
fn source_from_path<P: AsRef<std::path::Path>>(path: P) -> Decoder<BufReader<File>> {
|
||||
let file = BufReader::new(File::open(path).unwrap());
|
||||
let source = Decoder::new(file).unwrap();
|
||||
source
|
||||
}
|
||||
|
||||
fn play_audio<P: AsRef<std::path::Path>>(
|
||||
stream_handle: &OutputStreamHandle,
|
||||
sink: &mut Sink,
|
||||
path: P,
|
||||
volume: f32,
|
||||
) {
|
||||
let source = source_from_path(path);
|
||||
*sink = Sink::try_new(&stream_handle).unwrap();
|
||||
sink.set_volume(volume);
|
||||
sink.append(source);
|
||||
}
|
||||
|
||||
pub fn audio_thread() -> mpsc::Sender<SoundEffect> {
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
|
||||
let _ = std::thread::spawn(move || {
|
||||
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
|
||||
let music_sink = Sink::try_new(&stream_handle).unwrap();
|
||||
let mut hard_drop_sink = Sink::try_new(&stream_handle).unwrap();
|
||||
let mut line_clear_sink = Sink::try_new(&stream_handle).unwrap();
|
||||
let mut move_sink = Sink::try_new(&stream_handle).unwrap();
|
||||
let mut rotation_sink = Sink::try_new(&stream_handle).unwrap();
|
||||
|
||||
music_sink.append(source_from_path("resources/music.ogg").repeat_infinite());
|
||||
|
||||
loop {
|
||||
let Ok(effect) = receiver.recv() else {
|
||||
break;
|
||||
};
|
||||
|
||||
let base_volume = 0.5;
|
||||
match effect {
|
||||
SoundEffect::HardDrop => play_audio(
|
||||
&stream_handle,
|
||||
&mut hard_drop_sink,
|
||||
"resources/hard_drop.ogg",
|
||||
base_volume,
|
||||
),
|
||||
SoundEffect::LineClear(lines_cleared) => play_audio(
|
||||
&stream_handle,
|
||||
&mut line_clear_sink,
|
||||
"resources/line_clear.ogg",
|
||||
base_volume + (lines_cleared as f32 - 1.0) * 0.5,
|
||||
),
|
||||
SoundEffect::Move => play_audio(
|
||||
&stream_handle,
|
||||
&mut move_sink,
|
||||
"resources/move.ogg",
|
||||
base_volume,
|
||||
),
|
||||
SoundEffect::Rotation => play_audio(
|
||||
&stream_handle,
|
||||
&mut rotation_sink,
|
||||
"resources/rotation.ogg",
|
||||
base_volume,
|
||||
),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
sender
|
||||
}
|
@ -1,17 +1,17 @@
|
||||
use crate::actions::{Action, ActionsHeld};
|
||||
use crate::board::Board;
|
||||
use crate::game::{CurrentTetromino, Game};
|
||||
use crate::tetromino::Tetromino;
|
||||
use crate::Rgb;
|
||||
use sdl2::event::Event;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2::pixels::Color;
|
||||
use sdl2::rect::Rect;
|
||||
use sdl2::render::{Texture, TextureCreator, WindowCanvas};
|
||||
use sdl2::rwops::RWops;
|
||||
use sdl2::ttf::Sdl2TtfContext;
|
||||
use std::time::Duration;
|
||||
|
||||
use super::audio::{self};
|
||||
|
||||
const WIDTH: i32 = 1000;
|
||||
const HEIGHT: i32 = 800;
|
||||
|
||||
@ -119,10 +119,7 @@ fn font_texture<'font, 'a, C>(
|
||||
ttf_context: &'a Sdl2TtfContext,
|
||||
texture_creator: &'font TextureCreator<C>,
|
||||
) -> Result<Texture<'font>, String> {
|
||||
let font = ttf_context.load_font_from_rwops(
|
||||
RWops::from_bytes(include_bytes!("res/josenfin_sans_regular.ttf"))?,
|
||||
24,
|
||||
)?;
|
||||
let font = ttf_context.load_font("resources/josenfin_sans_regular.ttf", 24)?;
|
||||
let game_over_text = font.render(text).solid(Color::RGB(255, 255, 255)).unwrap();
|
||||
let texture = texture_creator
|
||||
.create_texture_from_surface(game_over_text)
|
||||
@ -161,6 +158,8 @@ pub fn start_game() -> Result<(), String> {
|
||||
let mut actions = ActionsHeld::new();
|
||||
let mut paused = false;
|
||||
|
||||
let audio_thread = audio::audio_thread();
|
||||
|
||||
let sdl_context = sdl2::init()?;
|
||||
let ttf_context = sdl2::ttf::init().unwrap();
|
||||
let video_subsystem = sdl_context.video()?;
|
||||
@ -242,7 +241,10 @@ pub fn start_game() -> Result<(), String> {
|
||||
&ttf_context,
|
||||
)?;
|
||||
} else {
|
||||
game.step(&actions);
|
||||
let effects = game.step(&actions);
|
||||
effects
|
||||
.into_iter()
|
||||
.for_each(|effect| audio_thread.send(effect).unwrap());
|
||||
}
|
||||
|
||||
canvas.present();
|
@ -3,7 +3,7 @@ use tetromino::Tetromino;
|
||||
mod actions;
|
||||
mod board;
|
||||
mod game;
|
||||
mod sdl_impl;
|
||||
mod gui;
|
||||
mod tetromino;
|
||||
|
||||
struct Rgb(u8, u8, u8);
|
||||
@ -23,5 +23,5 @@ impl Rgb {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
sdl_impl::start_game();
|
||||
gui::start_game().unwrap();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user