aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/app/.client/audio/AudioController.ts
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-08-21 02:46:37 +0900
committernsfisis <nsfisis@gmail.com>2024-08-21 02:46:37 +0900
commit483e297f4789fb1fdaa241f87686a00ef55a046d (patch)
treef4227c503ce82ffeba84603f872f7237fbee8ea7 /frontend/app/.client/audio/AudioController.ts
parent0765f61a494de1f284042ba56382983d58d5a6f5 (diff)
parent5dba0da3efae63cab5313582a17f20dbb41c6450 (diff)
downloadiosdc-japan-2024-albatross-483e297f4789fb1fdaa241f87686a00ef55a046d.tar.gz
iosdc-japan-2024-albatross-483e297f4789fb1fdaa241f87686a00ef55a046d.tar.zst
iosdc-japan-2024-albatross-483e297f4789fb1fdaa241f87686a00ef55a046d.zip
Merge branch 'feat/audio'
Diffstat (limited to 'frontend/app/.client/audio/AudioController.ts')
-rw-r--r--frontend/app/.client/audio/AudioController.ts94
1 files changed, 94 insertions, 0 deletions
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<SoundEffect, HTMLAudioElement | null>;
+
+ 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<void> {
+ 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<void> {
+ const audio = this.audioElements[soundEffect];
+ if (!audio) {
+ return;
+ }
+ audio.currentTime = 0;
+ await audio.play();
+ }
+
+ async playSoundEffectFinish(): Promise<void> {
+ await this.playSoundEffect("finish");
+ }
+
+ async playSoundEffectWinner(winner: 1 | 2): Promise<void> {
+ await this.playSoundEffect(`winner_${winner}`);
+ }
+
+ async playSoundEffectGood(): Promise<void> {
+ 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<void> {
+ 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<void> {
+ const variant = Math.floor(Math.random() * 2) + 1;
+ if (variant !== 1 && variant !== 2) {
+ return; // unreachable
+ }
+ return await this.playSoundEffect(`compile_error_${variant}`);
+ }
+}