Add standalone export for Two Rivers at Moonrise
All checks were successful
Build Org Website / build (push) Successful in 44s
All checks were successful
Build Org Website / build (push) Successful in 44s
This commit is contained in:
77
assets/scripts/games/two-rivers/systems/audio.mjs
Normal file
77
assets/scripts/games/two-rivers/systems/audio.mjs
Normal file
@@ -0,0 +1,77 @@
|
||||
export class AudioDirector {
|
||||
constructor(records, getSettings) {
|
||||
this.getSettings = getSettings;
|
||||
this.records = records;
|
||||
this.sounds = new Map();
|
||||
this.music = null;
|
||||
this.ambience = null;
|
||||
this.unlocked = false;
|
||||
records.forEach((record) => {
|
||||
this.sounds.set(record.id, new window.Howl({
|
||||
src: record.urls || [record.url],
|
||||
loop: record.type !== "sfx",
|
||||
preload: record.type === "sfx",
|
||||
volume: 0
|
||||
}));
|
||||
});
|
||||
document.addEventListener("visibilitychange", () => {
|
||||
if (document.hidden) window.Howler?.mute(true);
|
||||
else if (this.getSettings().sound) window.Howler?.mute(false);
|
||||
});
|
||||
}
|
||||
|
||||
unlock() {
|
||||
this.unlocked = true;
|
||||
window.Howler?.ctx?.resume?.();
|
||||
this.sync();
|
||||
}
|
||||
|
||||
sync() {
|
||||
const settings = this.getSettings();
|
||||
window.Howler.volume(settings.masterVolume);
|
||||
window.Howler.mute(!settings.sound);
|
||||
if (this.music) this.sounds.get(this.music)?.volume(settings.musicVolume);
|
||||
if (this.ambience) this.sounds.get(this.ambience)?.volume(settings.ambienceVolume * 0.35);
|
||||
}
|
||||
|
||||
playLocation(music, ambience) {
|
||||
if (!this.unlocked) return;
|
||||
this.crossfade("music", music);
|
||||
this.crossfade("ambience", ambience);
|
||||
}
|
||||
|
||||
crossfade(channel, nextId) {
|
||||
const currentId = this[channel];
|
||||
if (currentId === nextId) return;
|
||||
const settings = this.getSettings();
|
||||
const target = channel === "music" ? settings.musicVolume : settings.ambienceVolume * 0.35;
|
||||
if (currentId && this.sounds.has(currentId)) {
|
||||
const old = this.sounds.get(currentId);
|
||||
old.fade(old.volume(), 0, 500);
|
||||
window.setTimeout(() => old.stop(), 520);
|
||||
}
|
||||
this[channel] = nextId;
|
||||
const next = this.sounds.get(nextId);
|
||||
if (next) {
|
||||
next.volume(0);
|
||||
if (!next.playing()) next.play();
|
||||
next.fade(0, target, 700);
|
||||
}
|
||||
}
|
||||
|
||||
sfx(id) {
|
||||
if (!this.unlocked || !this.getSettings().sound) return;
|
||||
const sound = this.sounds.get(id);
|
||||
if (sound) {
|
||||
sound.volume(this.getSettings().sfxVolume);
|
||||
sound.play();
|
||||
}
|
||||
}
|
||||
|
||||
duck(active) {
|
||||
if (!this.music) return;
|
||||
const sound = this.sounds.get(this.music);
|
||||
const volume = this.getSettings().musicVolume * (active ? 0.45 : 1);
|
||||
sound?.fade(sound.volume(), volume, 250);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user