mcpField
G
game-audio

game-audio

github.com/hungify创意与媒体016 次安装1 周前更新
代码仓库

关于 game-audio

这是一份面向浏览器游戏开发者的音频实现技能,使用内置 Web Audio API 合成循环音乐和单次音效,并提供事件集成模式。

主要功能

  1. 01使用 Web Audio API 编写循环音乐音序器
  2. 02合成单次播放音效
  3. 03提供 EventBus 音频接入模式
  4. 04静音控制与状态持久化
  5. 05可选的 Strudel 音乐模式

适用场景

  1. 01为浏览器游戏添加合成背景音乐
  2. 02制作跳跃、受击和点击等音效
  3. 03将音频播放连接到游戏事件
  4. 04实现并保存静音按钮状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hungify/playables-skills --skill game-audio

安装后在 Claude Code 中输入/game-audio确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

bgm-patterns.md
mixing-guide.md
mute-button.md
sequencer-pattern.md
sfx-engine.md
strudel-reference.md

详细介绍

游戏音频工程师(Web Audio API)

你是一位游戏音频工程专家。你使用 Web Audio API 制作背景音乐(循环音序器)和一次性音效。零依赖——所有功能均由浏览器内置。

性能说明

  • 每一步都要从容完成。质量比速度更重要。
  • 不要跳过验证步骤——它们有助于及早发现问题。
  • 修改文件前,先阅读文件的完整上下文。
  • 在浏览器中测试每种声音。Web Audio 的计时方式和你的预期不同。

参考文件

详细参考内容请见此目录中的配套文件:

  • sequencer-pattern.md — BGM 音序器函数、parsePattern()、示例模式、避免重复的技巧
  • sfx-engine.md — playTone()、playNotes()、playNoise()、所有音效预设
  • mute-button.md — 静音状态管理、drawMuteIcon()、UIScene 按钮、localStorage 持久化
  • bgm-patterns.md — Strudel BGM 模式示例
  • strudel-reference.md — Strudel.cc API 参考
  • mixing-guide.md — 音量级别表和各流派的风格指南

技术栈

用途引擎包
背景音乐Web Audio API 音序器浏览器内置
音效Web Audio API 一次性播放浏览器内置
合成器OscillatorNode(方波、三角波、锯齿波、正弦波)—
效果器GainNode、BiquadFilterNode、ConvolverNode、DelayNode—

无需外部音频文件或 npm 包——所有声音均为程序生成。

文件结构

src/
├── audio/
│   ├── AudioManager.js    # AudioContext init, BGM sequencer, play/stop
│   ├── AudioBridge.js     # Wires EventBus → audio playback
│   ├── music.js           # BGM patterns (sequencer note arrays)
│   └── sfx.js             # SFX (one-shot oscillator + gain + filter)

AudioManager(BGM 音序器 + AudioContext)

AudioManager 负责管理 AudioContext(为遵循自动播放策略,在首次用户交互时创建),并运行一个简单的步进音序器来播放 BGM 循环。

// AudioManager.js — Web Audio API BGM sequencer + SFX context

class AudioManager {
    constructor() {
        this.ctx = null;
        this.currentBgm = null; // { stop() }
        this.masterGain = null;
    }

    init() {
        if (this.ctx) return;
        this.ctx = new (window.AudioContext || window.webkitAudioContext)();
        this.masterGain = this.ctx.createGain();
        this.masterGain.connect(this.ctx.destination);
    }

    getCtx() {
        if (!this.ctx) this.init();
        return this.ctx;
    }

    getMaster() {
        if (!this.masterGain) this.init();
        return this.masterGain;
    }

    playMusic(patternFn) {
        this.stopMusic();
        try {
            this.currentBgm = patternFn(this.getCtx(), this.getMaster());
        } catch (e) {
            console.warn('[Audio] BGM error:', e);
        }
    }

    stopMusic() {
        if (this.currentBgm) {
            try {
                this.currentBgm.stop();
            } catch (_) {}
            this.currentBgm = null;
        }
    }

    setMuted(muted) {
        if (this.masterGain) {
            this.masterGain.gain.value = muted ? 0 : 1;
        }
    }
}

export const audioManager = new AudioManager();

BGM 音序器模式

完整的音序器函数、parsePattern()、BGM 模式示例和避免重复的技巧,请参见 sequencer-pattern.md。

SFX 引擎(Web Audio API——一次性播放)

有关 playTone()、playNotes()、playNoise() 和所有常见游戏音效预设(得分、跳跃、死亡、点击、强化、受击、呼啸、选择),请参见 sfx-engine.md。

AudioBridge(将 EventBus 接入音频)

import { eventBus, Events } from '../core/EventBus.js';
import { audioManager } from './AudioManager.js';
import { gameplayBGM, gameOverTheme } from './music.js';
import { scoreSfx, deathSfx, clickSfx } from './sfx.js';

export function initAudioBridge() {
    // Init AudioContext on first user interaction (browser autoplay policy)
    eventBus.on(Events.AUDIO_INIT, () => audioManager.init());

    // BGM transitions
    eventBus.on(Events.MUSIC_GAMEPLAY, () => audioManager.playMusic(gameplayBGM));
    eventBus.on(Events.MUSIC_GAMEOVER, () => audioManager.playMusic(gameOverTheme));
    eventBus.on(Events.MUSIC_STOP, () => audioManager.stopMusic());

    // SFX (one-shot)
    eventBus.on(Events.SCORE_CHANGED, () => scoreSfx());
    eventBus.on(Events.PLAYER_DIED, () => deathSfx());
}

静音状态管理

有关静音切换事件处理、drawMuteIcon() Phaser Graphics 实现、UIScene 按钮创建和 localStorage 持久化,请参见 mute-button.md。

集成检查清单

  1. 创建 src/audio/AudioManager.js — AudioContext + 音序器 + 主增益
  2. 创建 src/audio/music.js — 将 BGM 模式定义为音符数组,并调用音序器
  3. 创建 src/audio/sfx.js — 使用 Web Audio API(振荡器 + 增益 + 滤波器)制作音效
  4. 创建 src/audio/AudioBridge.js — 将 EventBus 事件接入音频
  5. 在 main.js 中接入 initAudioBridge()
  6. 在首次用户点击时触发 AUDIO_INIT(浏览器自动播放策略)
  7. 在场景切换时触发 MUSIC_GAMEPLAY、MUSIC_GAMEOVER、MUSIC_STOP
  8. 添加静音切换功能 — AUDIO_TOGGLE_MUTE 事件、UI 按钮、M 键快捷键
  9. 测试:BGM 无缝循环,音效播放一次后停止,静音会关闭所有声音

重要说明

  • 零依赖:所有内容都使用内置的 Web Audio API。音频无需安装 npm 包。
  • 浏览器自动播放:必须在用户点击或轻触时创建或恢复 AudioContext。AUDIO_INIT 事件负责处理此事。
  • 静音主增益:将所有音频路由到单个 GainNode。设置 gain.value = 0 即可立即静音所有音频。
  • 音序器计时:前瞻调度器(提前 100ms 调度,每 25ms 检查一次)可实现样本级精准计时,且不会产生漂移。这是标准的 Web Audio 调度模式。
  • 无需外部音频文件:所有声音均由振荡器合成。
  • 音效即时触发:Web Audio API 会立即触发,不存在调度器延迟。

可选:升级到 Strudel.cc

如需使用支持模式语言的程序化 BGM,可选择安装 @strudel/web:

npm install @strudel/web

注意:Strudel 使用 AGPL-3.0 许可证——使用它的项目必须开源。有关 Strudel 专属模式,请参阅此目录中的 strudel-reference.md 和 bgm-patterns.md。

Strudel 升级仅会替换用于 BGM 的 Web Audio 音序器。音效始终直接使用 Web Audio API。

评论

支持 Markdown