1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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}`);
}
}
|