Different music per level

This commit is contained in:
Dustin Carlino 2020-12-18 16:26:39 -08:00
parent 31426db26a
commit 77fcd04402
7 changed files with 53 additions and 9 deletions

View File

@ -72,4 +72,6 @@ Other binary data bundled in:
- Material Design icons (<https://material.io/resources/icons>, Apache license)
- Some Graphics textures (<https://www.kenney.nl/>, CC0 1.0 Universal)
- Snowflake SVG (<https://www.svgrepo.com/page/licensing>, CC0)
- Jingle Bells (<https://soundcloud.com/royaltyfreebackgroundmusic/creative-commons-music-4061>, CC BY-NC-ND)
- Music
(<https://soundcloud.com/royaltyfreebackgroundmusic/sets/creative-commons-music-229>,
CC BY-NC-ND)

Binary file not shown.

View File

@ -41,6 +41,8 @@ impl Picker {
app,
level.map.clone(),
Box::new(move |ctx, app| {
app.session.music.change_song(&level.music);
ctx.canvas.cam_zoom = ZOOM;
let start = app
.map

View File

@ -9,6 +9,7 @@ pub struct Level {
pub title: String,
pub description: String,
pub map: MapName,
pub music: String,
pub start: osm::NodeID,
pub minimap_zoom: usize,
pub time_limit: Duration,
@ -27,6 +28,7 @@ impl Level {
some college students, whether they've been naughty or nice."
.to_string(),
map: MapName::seattle("udistrict_ravenna"),
music: "jingle_bells".to_string(),
start: osm::NodeID(53162661),
minimap_zoom: 1,
time_limit: Duration::seconds(90.0),
@ -41,6 +43,7 @@ impl Level {
everyone tucked away in the neighborhood?"
.to_string(),
map: MapName::seattle("wallingford"),
music: "silent_night".to_string(),
start: osm::NodeID(53218389),
minimap_zoom: 2,
time_limit: Duration::seconds(90.0),
@ -57,6 +60,7 @@ impl Level {
deliver to the apartments here!"
.to_string(),
map: MapName::seattle("slu"),
music: "jingle_bells".to_string(),
start: osm::NodeID(53142423),
minimap_zoom: 1,
time_limit: Duration::seconds(90.0),
@ -71,6 +75,7 @@ impl Level {
to this sleepy little pocket of the city?"
.to_string(),
map: MapName::seattle("montlake"),
music: "silent_night".to_string(),
start: osm::NodeID(53084814),
minimap_zoom: 1,
time_limit: Duration::minutes(3),
@ -85,6 +90,7 @@ impl Level {
one of the lowest-density parts of Seattle!"
.to_string(),
map: MapName::seattle("ballard"),
music: "jingle_bells".to_string(),
start: osm::NodeID(53117102),
minimap_zoom: 2,
time_limit: Duration::minutes(5),
@ -97,6 +103,7 @@ impl Level {
title: "Phinney Ridge".to_string(),
description: "...".to_string(),
map: MapName::seattle("phinney"),
music: "silent_night".to_string(),
start: osm::NodeID(53233319),
minimap_zoom: 1,
time_limit: Duration::minutes(5),
@ -109,6 +116,7 @@ impl Level {
title: "Queen Anne".to_string(),
description: "...".to_string(),
map: MapName::seattle("qa"),
music: "jingle_bells".to_string(),
start: osm::NodeID(53234637),
minimap_zoom: 1,
time_limit: Duration::minutes(5),

View File

@ -31,7 +31,7 @@ pub fn main() {
if app.opts.dev {
app.session.unlock_all();
}
app.session.music = music::Music::start(ctx, app.session.play_music);
app.session.music = music::Music::start(ctx, app.session.play_music, "jingle_bells");
app.session.music.specify_volume(music::OUT_OF_GAME);
let states = vec![title::TitleScreen::new(ctx, &app)];

View File

@ -1,7 +1,7 @@
use std::error::Error;
use std::io::Cursor;
use rodio::{Decoder, OutputStream, Sink};
use rodio::{Decoder, OutputStream, OutputStreamHandle, Sink};
use widgetry::{
Btn, Checkbox, EventCtx, GfxCtx, HorizontalAlignment, Outcome, Panel, VerticalAlignment,
@ -24,8 +24,10 @@ impl std::default::Default for Music {
struct Inner {
// Have to keep this alive for the background thread to continue
_stream: OutputStream,
stream_handle: OutputStreamHandle,
sink: Sink,
unmuted_volume: f32,
current_song: String,
panel: Panel,
}
@ -35,8 +37,8 @@ impl Music {
Music { inner: None }
}
pub fn start(ctx: &mut EventCtx, play_music: bool) -> Music {
match Inner::new(ctx, play_music) {
pub fn start(ctx: &mut EventCtx, play_music: bool, song: &str) -> Music {
match Inner::new(ctx, play_music, song) {
Ok(inner) => Music { inner: Some(inner) },
Err(err) => {
error!("No music, sorry: {}", err);
@ -74,14 +76,25 @@ impl Music {
inner.specify_volume(volume);
}
}
pub fn change_song(&mut self, song: &str) {
if let Some(ref mut inner) = self.inner {
if let Err(err) = inner.change_song(song) {
warn!("Couldn't play {}: {}", song, err);
}
}
}
}
impl Inner {
fn new(ctx: &mut EventCtx, play_music: bool) -> Result<Inner, Box<dyn Error>> {
fn new(ctx: &mut EventCtx, play_music: bool, song: &str) -> Result<Inner, Box<dyn Error>> {
let (stream, stream_handle) = OutputStream::try_default()?;
let sink = rodio::Sink::try_new(&stream_handle)?;
let raw_bytes =
Cursor::new(include_bytes!("../../data/system/assets/music/jingle_bells.ogg").to_vec());
let raw_bytes = Cursor::new(abstutil::slurp_file(&abstutil::path(format!(
"system/assets/music/{}.ogg",
song
)))?);
sink.append(Decoder::new_looped(raw_bytes)?);
if !play_music {
sink.set_volume(0.0);
@ -104,8 +117,10 @@ impl Inner {
Ok(Inner {
_stream: stream,
stream_handle,
sink,
unmuted_volume: 1.0,
current_song: song.to_string(),
panel,
})
}
@ -124,4 +139,21 @@ impl Inner {
self.unmute();
}
}
fn change_song(&mut self, song: &str) -> Result<(), Box<dyn Error>> {
if self.current_song == song {
return Ok(());
}
self.current_song = song.to_string();
let old_volume = self.sink.volume();
self.sink = rodio::Sink::try_new(&self.stream_handle)?;
let raw_bytes = Cursor::new(abstutil::slurp_file(&abstutil::path(format!(
"system/assets/music/{}.ogg",
song
)))?);
self.sink.append(Decoder::new_looped(raw_bytes)?);
self.sink.set_volume(old_volume);
Ok(())
}
}

View File

@ -165,7 +165,7 @@ impl Credits {
"Map data thanks to OpenStreetMap contributors",
"https://www.openstreetmap.org/about"),
link(ctx, "Land use data from Seattle GeoData", "https://data-seattlecitygis.opendata.arcgis.com/datasets/current-land-use-zoning-detail"),
link(ctx, "Music by Royalty Free Music", "https://soundcloud.com/royaltyfreebackgroundmusic/creative-commons-music-4061"),
link(ctx, "Music by Royalty Free Music", "https://soundcloud.com/royaltyfreebackgroundmusic/sets/creative-commons-music-229"),
link(ctx, "Fonts and icons by various sources", "https://dabreegster.github.io/abstreet/howto/#data-source-licensing"),
"Playtesting by Fridgehaus".draw_text(ctx),
Btn::text_bg2("Back").build_def(ctx, Key::Enter).centered_horiz(),