79 lines
2.3 KiB
JavaScript
Executable File
79 lines
2.3 KiB
JavaScript
Executable File
// Native ES module served with the production JavaScript MIME type.
|
|
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);
|
|
}
|
|
}
|