import { type GameEffect } from '../core/gameResult' type SoundKey = 'session-start' | 'start-complete' | 'control-complete' | 'finish-complete' | 'warning' const SOUND_SRC: Record = { 'session-start': '/assets/sounds/session-start.wav', 'start-complete': '/assets/sounds/start-complete.wav', 'control-complete': '/assets/sounds/control-complete.wav', 'finish-complete': '/assets/sounds/finish-complete.wav', warning: '/assets/sounds/warning.wav', } export class SoundDirector { enabled: boolean contexts: Partial> constructor() { this.enabled = true this.contexts = {} } setEnabled(enabled: boolean): void { this.enabled = enabled } destroy(): void { const keys = Object.keys(this.contexts) as SoundKey[] for (const key of keys) { const context = this.contexts[key] if (!context) { continue } context.stop() context.destroy() } this.contexts = {} } handleEffects(effects: GameEffect[]): void { if (!this.enabled || !effects.length) { return } const hasFinishCompletion = effects.some((effect) => effect.type === 'control_completed' && effect.controlKind === 'finish') for (const effect of effects) { if (effect.type === 'session_started') { this.play('session-start') continue } if (effect.type === 'punch_feedback' && effect.tone === 'warning') { this.play('warning') continue } if (effect.type === 'control_completed') { if (effect.controlKind === 'start') { this.play('start-complete') continue } if (effect.controlKind === 'finish') { this.play('finish-complete') continue } this.play('control-complete') continue } if (effect.type === 'session_finished' && !hasFinishCompletion) { this.play('finish-complete') } } } play(key: SoundKey): void { const context = this.getContext(key) context.stop() context.seek(0) context.play() } getContext(key: SoundKey): WechatMiniprogram.InnerAudioContext { const existing = this.contexts[key] if (existing) { return existing } const context = wx.createInnerAudioContext() context.src = SOUND_SRC[key] context.autoplay = false context.loop = false context.obeyMuteSwitch = true context.volume = 1 this.contexts[key] = context return context } }