Overworld
包参考

@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
autoSubscribeSceneChangestrue订阅总线 scene:changed 自动换曲
events全局 gameEvents自定义事件总线(测试时传入新实例);bus 是保留的旧别名,两者同传时 events 优先
volume / sfxVolume0.7初始 BGM / 音效音量(0–1)
fadeDuration1000切曲淡入淡出时长(ms),0 表示立即切换
looptrueBGM 是否循环
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

本页目录