From 5dba0da3efae63cab5313582a17f20dbb41c6450 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 21 Aug 2024 02:46:06 +0900 Subject: feat(frontend): partially implement sound effect --- frontend/app/.client/audio/AudioController.ts | 94 +++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 frontend/app/.client/audio/AudioController.ts (limited to 'frontend/app/.client/audio/AudioController.ts') diff --git a/frontend/app/.client/audio/AudioController.ts b/frontend/app/.client/audio/AudioController.ts new file mode 100644 index 0000000..6ed6180 --- /dev/null +++ b/frontend/app/.client/audio/AudioController.ts @@ -0,0 +1,94 @@ +import { SoundEffect, getFileUrl } from "./SoundEffect"; + +export class AudioController { + audioElements: Record; + + constructor() { + this.audioElements = { + finish: null, + winner_1: null, + winner_2: null, + good_1: null, + good_2: null, + good_3: null, + good_4: null, + new_score_1: null, + new_score_2: null, + new_score_3: null, + compile_error_1: null, + compile_error_2: null, + }; + } + + loadAll(): Promise { + return new Promise((resolve) => { + const files = Object.keys(this.audioElements).map( + (se) => [se as SoundEffect, getFileUrl(se as SoundEffect)] as const, + ); + const totalCount = files.length; + let loadedCount = 0; + + files.forEach(([se, fileUrl]) => { + const audio = new Audio(fileUrl); + + audio.addEventListener( + "canplaythrough", + () => { + loadedCount++; + this.audioElements[se] = audio; + if (loadedCount === totalCount) { + resolve(); + } + }, + { once: true }, + ); + + audio.addEventListener("error", () => { + console.log(`Failed to load audio file: ${fileUrl}`); + // Ignore the error and continue loading other files. + }); + }); + }); + } + + async playSoundEffect(soundEffect: SoundEffect): Promise { + const audio = this.audioElements[soundEffect]; + if (!audio) { + return; + } + audio.currentTime = 0; + await audio.play(); + } + + async playSoundEffectFinish(): Promise { + await this.playSoundEffect("finish"); + } + + async playSoundEffectWinner(winner: 1 | 2): Promise { + await this.playSoundEffect(`winner_${winner}`); + } + + async playSoundEffectGood(): Promise { + const variant = Math.floor(Math.random() * 4) + 1; + if (variant !== 1 && variant !== 2 && variant !== 3 && variant !== 4) { + return; // unreachable + } + return await this.playSoundEffect(`good_${variant}`); + } + + async playSoundEffectNewScore(): Promise { + const variant = Math.floor(Math.random() * 3) + 1; + if (variant !== 1 && variant !== 2 && variant !== 3) { + return; // unreachable + } + return await this.playSoundEffect(`new_score_${variant}`); + } + + async playSoundEffectCompileError(): Promise { + const variant = Math.floor(Math.random() * 2) + 1; + if (variant !== 1 && variant !== 2) { + return; // unreachable + } + return await this.playSoundEffect(`compile_error_${variant}`); + } +} -- cgit v1.2.3-70-g09d2