decla-red/frontend/src/scripts/sound-handler.ts
2026-06-11 21:02:06 +01:00

82 lines
2.2 KiB
TypeScript

import hitSound from '../../static/hit.mp3';
import shootSound from '../../static/shoot.mp3';
import clickSound from '../../static/click.mp3';
import ambientSound from '../../static/ambient.mp3';
import { OptionsHandler } from './options-handler';
export enum Sounds {
hit = 'hit',
shoot = 'shoot',
click = 'click',
}
export abstract class SoundHandler {
private static sounds: { [key in Sounds]: HTMLAudioElement };
private static isAmbientPlaying = false;
private static ambientSound = new Audio(ambientSound);
private static initialized = false;
public static async initialize(
onPlayKeypress: () => unknown = () => null,
onPauseKeypress: () => unknown = () => null,
) {
this.sounds = {
[Sounds.hit]: await this.initializeSound(hitSound),
[Sounds.shoot]: await this.initializeSound(shootSound),
[Sounds.click]: await this.initializeSound(clickSound),
};
await this.ambientSound.play();
this.ambientSound.muted = true;
this.initialized = true;
this.ambientSound.onpause = onPauseKeypress;
this.ambientSound.onplay = onPlayKeypress;
this.ambientSound.muted = false;
this.ambientSound.volume = 0.5;
this.ambientSound.loop = true;
if (!this.isAmbientPlaying) {
this.ambientSound.pause();
}
}
private static async initializeSound(hitSound: string): Promise<HTMLAudioElement> {
const sound = new Audio(hitSound);
sound.muted = true;
await sound.play();
sound.pause();
sound.muted = false;
sound.currentTime = 0;
return sound;
}
public static play(sound: Sounds, volume = 1, playbackRate = 1) {
if (!this.initialized || !OptionsHandler.options.soundsEnabled) {
return;
}
const audio =
this.sounds[sound].currentTime > 0
? (this.sounds[sound].cloneNode(true) as HTMLAudioElement)
: this.sounds[sound];
audio.volume = Math.max(0, Math.min(1, volume));
audio.playbackRate = playbackRate;
audio.play();
}
public static playAmbient() {
this.isAmbientPlaying = true;
if (this.initialized) {
this.ambientSound.play();
}
}
public static stopAmbient() {
this.isAmbientPlaying = false;
if (this.initialized) {
this.ambientSound.pause();
}
}
}