FIX - use packaged 2048 sound effects

This commit is contained in:
smx.pusha
2026-08-06 08:49:17 +02:00
parent 3c92660069
commit cd0b667d2f
5 changed files with 28 additions and 63 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,77 +1,42 @@
import gameOverUrl from '@/assets/audio/number-merge/game-over.wav?url'
import mergeUrl from '@/assets/audio/number-merge/merge.wav?url'
import moveUrl from '@/assets/audio/number-merge/move.wav?url'
import winUrl from '@/assets/audio/number-merge/win.wav?url'
export type NumberMergeSound = 'game-over' | 'merge' | 'move' | 'win' export type NumberMergeSound = 'game-over' | 'merge' | 'move' | 'win'
type Tone = { const soundUrls: Record<NumberMergeSound, string> = {
duration: number 'game-over': gameOverUrl,
frequency: number merge: mergeUrl,
offset: number move: moveUrl,
type: OscillatorType win: winUrl,
volume: number
} }
const playerPools = new Map<NumberMergeSound, HTMLAudioElement[]>()
const sounds: Record<NumberMergeSound, Tone[]> = { function getPlayers(sound: NumberMergeSound): HTMLAudioElement[] {
move: [{ duration: 0.065, frequency: 290, offset: 0, type: 'sine', volume: 0.085 }], const existing = playerPools.get(sound)
merge: [ if (existing) return existing
{ duration: 0.1, frequency: 390, offset: 0, type: 'sine', volume: 0.1 },
{ duration: 0.14, frequency: 540, offset: 0.055, type: 'sine', volume: 0.12 }, const players = Array.from({ length: 3 }, () => {
], const player = new Audio(soundUrls[sound])
win: [ player.preload = 'auto'
{ duration: 0.16, frequency: 523.25, offset: 0, type: 'sine', volume: 0.08 }, player.volume = 0.82
{ duration: 0.16, frequency: 659.25, offset: 0.1, type: 'sine', volume: 0.085 }, return player
{ duration: 0.16, frequency: 783.99, offset: 0.2, type: 'sine', volume: 0.09 }, })
{ duration: 0.3, frequency: 1046.5, offset: 0.3, type: 'sine', volume: 0.1 }, playerPools.set(sound, players)
], return players
'game-over': [
{ duration: 0.14, frequency: 260, offset: 0, type: 'triangle', volume: 0.065 },
{ duration: 0.18, frequency: 195, offset: 0.12, type: 'triangle', volume: 0.06 },
{ duration: 0.22, frequency: 146, offset: 0.26, type: 'triangle', volume: 0.055 },
],
} }
let audioContext: AudioContext | undefined
export function playNumberMergeSound( export function playNumberMergeSound(
sound: NumberMergeSound, sound: NumberMergeSound,
enabled: boolean, enabled: boolean,
): void { ): void {
if (!enabled) return if (!enabled) return
const AudioContextConstructor = const players = getPlayers(sound)
window.AudioContext ?? const player = players.find((candidate) => candidate.paused) ?? players[0]
(window as typeof window & { webkitAudioContext?: typeof AudioContext }) player.currentTime = 0
.webkitAudioContext void player.play().catch((error: unknown) => {
if (!AudioContextConstructor) { console.error(`[2048 audio] Failed to play ${sound}`, error)
console.error('[2048 audio] Web Audio is unavailable')
return
}
audioContext ??= new AudioContextConstructor()
const context = audioContext
const scheduleSound = (): void => {
const now = context.currentTime + 0.02
for (const tone of sounds[sound]) {
const oscillator = context.createOscillator()
const gain = context.createGain()
const start = now + tone.offset
const end = start + tone.duration
oscillator.type = tone.type
oscillator.frequency.setValueAtTime(tone.frequency, start)
gain.gain.setValueAtTime(0.0001, start)
gain.gain.linearRampToValueAtTime(tone.volume, start + 0.012)
gain.gain.exponentialRampToValueAtTime(0.0001, end)
oscillator.connect(gain).connect(context.destination)
oscillator.start(start)
oscillator.stop(end + 0.01)
}
}
if (context.state === 'running') {
scheduleSound()
return
}
void context.resume().then(scheduleSound).catch((error: unknown) => {
console.error('[2048 audio] Failed to start sound', error)
}) })
} }