Audio (AudioManager)
Cztery kanały, efektywna głośność, SoundHandle, mute i kolejka autoplay. Jak grać dźwięki bez problemów z blokadą przeglądarki.
Kanały i głośność#
AudioChannel = "master" | "music" | "sfx" | "ui"
Domyślne głośności: { master: 1, music: 0.7, sfx: 1, ui: 0.9 }.
Efektywna głośność dźwięku to iloczyn:
effectiveVolume = master × channel × volume
const audio = this.getAudio()
audio.setMasterVolume(0.8)
audio.setVolume('music', 0.5)
audio.setVolume('sfx', 1)
Odtwarzanie#
const handle = this.playSound('pickup', { channel: 'sfx', volume: 0.9 })
const music = this.playMusic('theme', { loop: true, volume: 0.6 })
this.stopMusic()
this.stopSounds()
this.stopSounds('game')
PlaySoundOptions = { channel?, volume?, loop?, rate?, owner? }.
SoundHandle#
handle.id
handle.assetId
handle.channel
handle.owner
handle.loop
handle.rate
handle.volume
handle.effectiveVolume
handle.isPlaying
handle.statusName
handle.setVolume(0.5)
handle.stop()
Przykład: wyciszanie muzyki w dialogu#
class DialogScene extends Scene {
private music: SoundHandle | null = null
create() {
this.music = this.playMusic('dialog-theme', { loop: true })
this.music?.setVolume(0.3)
}
close() {
this.music?.stop()
this.getEvents().emit('dialog:closed')
}
}
API#
audio.play(assetId, options?): SoundHandle | null
audio.playMusic(assetId, options?): SoundHandle | null
audio.stopMusic(); audio.getMusic()
audio.stop(handle): boolean; audio.stopAsset(assetId): number
audio.stopOwner(owner): number; audio.stopAll()
audio.pauseAll(); audio.resumeAll(); audio.isPaused()
audio.setVolume(channel, value); audio.setMasterVolume(value)
audio.getVolume(channel?); audio.getVolumes()
audio.setMuted(bool); audio.mute(); audio.unmute(); audio.toggleMute(); audio.isMuted()
audio.isUnlocked(); audio.unlock(): boolean; audio.onUnlock(listener)
audio.getHandleCount(); audio.getPendingCount(); audio.getState(): AudioState
Blokada autoplay i unlock#
Przeglądarki blokują audio bez gestu użytkownika. Żądania odtwarzania trafiają wtedy do kolejki pending, a unlock() odtwarza je po kolei i emituje audio:unlocked:
class MenuScene extends Scene {
create() {
this.playMusic('theme', { loop: true })
const start = this.createText('start', { x: 640, y: 500, text: 'Kliknij, aby zacząć' })
start.setRender({ type: 'text', text: 'Kliknij, aby zacząć', interactive: true })
this.getEvents().on('audio:unlocked', () => {
this.getLogger().info('Audio odblokowane')
})
}
update() {
if (this.getInput().getPointer().isDown) {
this.getAudio().unlock()
this.getEvents().emit('request:scene', { to: 'game' })
}
}
}
Wskazówka
Nie walcz z blokadą autoplay — kolejka pending jest po to, żeby muzyka wystartowała dokładnie przy pierwszym kliknięciu, bez podwójnego odtwarzania i bez błędów w konsoli.
Mute i pauza#
audio.toggleMute()
engine.pause()
engine.resume()
engine.pause() woła audio.pauseAll(), resume() — audio.resumeAll(). Każdy dźwięk ma właściciela (scenę), więc shutdown() sceny zatrzymuje tylko jej dźwięki przez stopOwner.
Stan audio#
const state = audio.getState()
AudioState zawiera kanały, głośności, mute, unlock i liczby uchwytów — gotowe do nakładki debug i raportu diagnostycznego.