@overworld-engine/audio
BGM/音效管理器:场景-曲目映射、切曲淡入淡出与自动播放策略处理
BGM / 音效管理器:单例 HTMLAudio 池、切曲淡入淡出、浏览器自动播放策略处理
(首次用户交互后自动重试)、可选的音量与静音设置持久化(经 persist 显式开启),
并可订阅事件总线上的 scene:changed 事件自动切换场景 BGM。
包内零游戏内容:曲目表、场景映射全部由配置注入。所有浏览器 API 均有守卫, 在 Node / SSR / 测试环境中导入和创建不会崩溃(仅记录状态、不实际播放)。
快速开始
import { createAudioManager } from '@overworld-engine/audio'
const audio = createAudioManager({
tracks: {
town: '/bgm/town.mp3',
dungeon: '/bgm/dungeon.mp3',
pickup: '/sfx/pickup.mp3',
},
sceneTracks: { plaza: 'town', crypt: 'dungeon' }, // 场景 id → 曲目 id
})
// 之后每次 gameEvents.emit('scene:changed', ...) 都会自动切换 BGM
audio.playSfx('pickup') // 一次性音效配置(AudioManagerConfig)
| 选项 | 默认 | 说明 |
|---|---|---|
tracks | 必填 | 曲目 id → 音频 URL(BGM 与音效共用) |
sceneTracks | — | 场景 id → 曲目 id;未映射的场景会停止当前 BGM |
autoSubscribeSceneChanges | true | 订阅总线 scene:changed 自动换曲 |
events | 全局 gameEvents | 自定义事件总线(测试时传入新实例);bus 是保留的旧别名,两者同传时 events 优先 |
volume / sfxVolume | 0.7 | 初始 BGM / 音效音量(0–1) |
fadeDuration | 1000 | 切曲淡入淡出时长(ms),0 表示立即切换 |
loop | true | BGM 是否循环 |
persist | 省略(关闭) | 框架统一约定:省略或 false 不持久化;true 用默认配置持久化音量/静音(键 overworld:audio);可传对象自定义。v0.9 起省略即关闭(此前默认开启),依赖持久化请显式传 persist: true |
Manager API
-
store— 底层 zustand vanilla store(StoreApi<AudioState>),状态为{ volume, sfxVolume, muted, currentTrackId, unlocked };getState()取快照, React 里用 zustand 的useStore:import { useStore } from 'zustand' const muted = useStore(audio.store, (s) => s.muted) -
playTrack(trackId)/stopTrack()— 播放 / 停止 BGM(带淡入淡出) -
playSceneTrack(sceneId)— 按场景映射播放;resolveSceneTrack(sceneId)仅做解析 -
playSfx(trackId)— 一次性音效 -
setVolume(v)/setSfxVolume(v)— 音量(自动钳制到 0–1) -
setMuted(muted)/toggleMute()— 静音;静音期间仍记录目标曲目,取消静音后恢复播放 -
dispose()— 退订总线、移除解锁监听并停止播放
自动播放策略
浏览器通常禁止无交互时自动播放。当 audio.play() 被拒绝时,管理器会在
window 上注册一次性的 pointerdown / keydown 监听,首次用户交互后自动
重试当前曲目;成功后 unlocked 置为 true。
依赖
依赖 @overworld-engine/core(事件总线与持久化辅助);peerDependency 为 zustand。