mcpField
A
audio-and-sound

audio-and-sound

github.com/phaserjs開発40.6k965 回インストール10 週間前に更新
リポジトリ

audio-and-sound について

Phaser のゲーム開発者向けに、音声の読み込みと再生制御を解説するリファレンスです。Web Audio と HTML5 Audio の各バックエンドの機能も紹介します。

主な機能

  1. 01Web Audio と HTML5 Audio のバックエンド
  2. 02再生、ループ、音量の制御
  3. 03マーカー、オーディオスプライト、空間音響
  4. 04一時停止、再開、ブラウザー音声の有効化

活用シーン

  1. 01BGM やゲーム効果音の再生
  2. 02複数のクリップをオーディオスプライトに設定
  3. 03ゲームオブジェクトに応じた音の配置

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/phaserjs/phaser --skill audio-and-sound

インストール後、Claude Code で/audio-and-soundを入力して読み込まれたか確認します。

詳細

オーディオとサウンド

Phaser は this.sound(SoundManager)を通じて統合されたサウンドシステムを提供し、Web Audio API と HTML5 Audio を抽象化します。ローディング、再生、音量、パンニング、ループ、マーカー、オーディオスプライト、空間オーディオ、ブラウザの自動再生ポリシーの解除を処理します。

主要なソースパス: src/sound/BaseSoundManager.js、src/sound/BaseSound.js、src/sound/webaudio/、src/sound/html5/、src/sound/SoundManagerCreator.js、src/sound/events/、src/sound/typedefs/ 関連スキル: ../loading-assets/SKILL.md、../game-setup-and-config/SKILL.md

クイックスタート

class GameScene extends Phaser.Scene {
    preload() {
        this.load.audio('bgm', 'assets/music.mp3');
        this.load.audio('coin', ['assets/coin.ogg', 'assets/coin.mp3']);
    }

    create() {
        // Fire-and-forget (auto-destroys when complete)
        this.sound.play('coin');

        // Retained reference for ongoing control
        this.music = this.sound.add('bgm', { loop: true, volume: 0.5 });
        this.music.play();
    }
}

preload() 内で this.load.audio() を介して読み込まれたアセットは、create() が実行される時点で準備完了しています。クロスブラウザのフォーマットフォールバック用に URL の配列を指定してください。

基本概念

WebAudio と HTML5 Audio

Phaser は SoundManagerCreator.create() を介して最適なバックエンドを自動選択します:

  1. config.audio.noAudio が true の場合、またはデバイスが Web Audio も HTML5 Audio もサポートしていない場合、NoAudioSoundManager が作成されます(すべての呼び出しは no-op です)。
  2. デバイスが Web Audio をサポートし、config.audio.disableWebAudio が true でない場合、WebAudioSoundManager が作成されます(推奨)。
  3. それ以外の場合、フォールバックとして HTML5AudioSoundManager が作成されます。

WebAudio の利点:正確なタイミング、ギャップのないループ、ステレオパンニング(StereoPannerNode)、空間オーディオ(PannerNode)、サウンドごとのゲインノード、ランタイムデコード用の decodeAudio()。

HTML5 Audio の制限:空間オーディオなし、真のステレオパンニングなし(pan はイベントを発火しますが可聴効果はありません)、ループの精度が低い、同時再生にはロード時の instances 数が必要。

ゲーム設定で HTML5 を強制するか、オーディオを無効化します:audio: { disableWebAudio: true } または audio: { noAudio: true }。SPA で WebAudio コンテキストを再利用するには audio: { context: existingAudioContext } を渡します。

SoundManager (this.sound)

任意の Scene で this.sound を介してアクセスします。ゲーム全体で共有される単一のインスタンスです。主な役割:

  • サウンドインスタンスの追加、再生、削除
  • グローバルな音量、ミュート、レート、デチューン
  • ブラウザタブがフォーカスを失った/得たときの自動一時停止/再開(pauseOnBlur、デフォルトは true)
  • モバイルブラウザ向けのオーディオ解除処理
  • 空間オーディオのリスナー位置(WebAudio のみ)
サウンドインスタンス

this.sound.add(key, config) を介して作成されます。各インスタンスは独自の再生状態、音量、レート、デチューン、ループ、パン、シークプロパティを持ちます。サウンドは追加する前にオーディオキャッシュに存在している必要があります(Loader を介して読み込まれます)。

状態フラグ:isPlaying(boolean)、isPaused(boolean)。

const sfx = this.sound.add('explosion', { volume: 0.8 });
sfx.play();        // returns boolean
sfx.pause();       // only works if isPlaying
sfx.resume();      // only works if isPaused
sfx.stop();        // resets to stopped state
sfx.destroy();     // marks for removal from manager

一般的なパターン

サウンドの再生

ファイア・アンド・フォーゲット -- this.sound.play(key, config?) はサウンドを追加し、再生し、完了時に自動的に破棄します:

this.sound.play('explosion');
this.sound.play('powerup', { volume: 0.5, rate: 1.2 });

参照を保持 -- this.sound.add(key, config?) を実行し、インスタンスの play() を呼び出します:

const laser = this.sound.add('laser');
laser.play();
// Later: laser.stop(), laser.volume = 0.3, etc.
音量、レート、デチューン

各プロパティはサウンドごと、またはマネージャー上でグローバルに設定できます。グローバル値とサウンドごとの値は組み合わされます(レート/デチューンの場合、calculateRate() を介して乗算されます)。

// Per-sound
sound.volume = 0.5;          // 0 to 1
sound.setVolume(0.5);        // chainable alternative
sound.rate = 1.5;            // 0.5 = half speed, 2.0 = double speed
sound.setRate(1.5);
sound.detune = 200;          // cents, -1200 to 1200
sound.setDetune(200);

// Global (affects all sounds)
this.sound.volume = 0.8;
this.sound.setVolume(0.8);
this.sound.rate = 1.0;
this.sound.setRate(1.0);
this.sound.detune = 0;
this.sound.setDetune(0);

実効再生レートは次のとおりです:sound.rate * manager.rate * detuneRate(ここで detuneRate = Math.pow(1.0005777895065548, sound.detune + manager.detune))。

ループ
// Via config at creation
const bgm = this.sound.add('music', { loop: true });
bgm.play();

// Toggle during playback
bgm.loop = false;
bgm.setLoop(false);  // chainable

LOOPED イベントは、サウンドが先頭にループバックするたびに発火します。LOOP イベントは、loop プロパティが変更されたときに発火します。

シーク
sound.seek = 5.0;        // jump to 5 seconds in
sound.setSeek(5.0);      // chainable
console.log(sound.seek);  // current playback position in seconds

停止中のサウンドにシークを設定しても効果はありません。

ステレオパンニング
sound.pan = -1;   // full left
sound.pan = 0;    // center
sound.pan = 1;    // full right
sound.setPan(0.5); // chainable

WebAudio では、存在する場合 StereoPannerNode を使用します。HTML5 Audio では、pan プロパティはイベントを発火しますが可聴効果はありません。

オーディオスプライトとマーカー

オーディオスプライトは、複数のサウンドを 1 つのオーディオファイルにまとめ、JSON 設定(audiosprite ツールで生成)と組み合わせるものです。JSON は別途読み込む必要があります。

// In preload
this.load.audioSprite('sfx', 'assets/sfx.json', ['assets/sfx.ogg', 'assets/sfx.mp3']);

// In create
this.sound.playAudioSprite('sfx', 'explosion');
this.sound.playAudioSprite('sfx', 'coin', { volume: 0.5 });

// Or add for retained control
const sprite = this.sound.addAudioSprite('sfx');
sprite.play('explosion');

JSON の spritemap エントリは、name、start、duration、および省略可能な loop を持つマーカーに自動的に変換されます。

手動マーカー -- 任意のサウンドにマーカーを追加することもできます。

const sound = this.sound.add('longtrack');

sound.addMarker({ name: 'intro', start: 0, duration: 5 });
sound.addMarker({ name: 'loop', start: 5, duration: 20, config: { loop: true } });
sound.addMarker({ name: 'outro', start: 25, duration: 3 });

sound.play('intro');
// Later
sound.play('loop');

BaseSound のマーカー API: addMarker(marker)、updateMarker(marker)、removeMarker(markerName)。

バックグラウンドミュージックのパターン
this.bgm = this.sound.add('theme', { loop: true, volume: 0.4 });
this.bgm.play();
// Stop on scene shutdown: this.bgm.stop();

マネージャーの pauseOnBlur(デフォルトは true)は、タブがフォーカスを失ったときにすべてのサウンドを自動的に一時停止します。

空間オーディオ(WebAudio のみ)

空間オーディオは Web Audio の PannerNode を使用して、リスナーを基準とした 2D/3D 空間にサウンドを配置します。

// Set the listener position (typically your camera or player)
this.sound.setListenerPosition(400, 300);
// Or update directly: this.sound.listenerPosition.set(x, y);

// Create a spatialized sound with a source config
const enemy = this.sound.add('roar', {
    source: {
        x: 800,
        y: 300,
        refDistance: 50,
        maxDistance: 2000,
        rolloffFactor: 1,
        distanceModel: 'inverse',
        panningModel: 'equalpower',
        follow: enemySprite  // auto-track a Game Object's x/y
    }
});
enemy.play();

WebAudioSound の sound.x と sound.y を直接設定することで、いつでも位置を変更できます。follow に x/y プロパティを持つオブジェクトを設定すると、空間位置がフレームごとに自動的に更新されます。

setListenerPosition() は、引数なしで呼び出した場合、デフォルトでゲームキャンバスの中心になります。

ミュート
// Per-sound
sound.mute = true;
sound.setMute(true);

// Global
this.sound.mute = true;
this.sound.setMute(true);
サウンドの照会
this.sound.get('coin');          // first sound with key, or null
this.sound.getAll('coin');       // all sounds with key
this.sound.getAll();             // every sound in the manager
this.sound.getAllPlaying();      // all currently playing sounds
this.sound.isPlaying('coin');    // true if any 'coin' sound is playing
this.sound.isPlaying();          // true if any sound is playing
削除と停止
this.sound.stopAll();            // stop all sounds, fires STOP_ALL
this.sound.stopByKey('coin');    // stop all sounds with key, returns count
this.sound.pauseAll();           // pause all, fires PAUSE_ALL
this.sound.resumeAll();          // resume all, fires RESUME_ALL

this.sound.remove(soundInstance);  // destroy + remove specific sound
this.sound.removeByKey('coin');    // destroy + remove all with key, returns count
this.sound.removeAll();            // destroy + remove everything
実行時のオーディオデコード(WebAudio のみ)
this.sound.decodeAudio('key', base64StringOrArrayBuffer);
// Or batch: this.sound.decodeAudio([{ key: 'sfx1', data: buf1 }, { key: 'sfx2', data: buf2 }]);
this.sound.on('decoded', (key) => { /* one done */ });
this.sound.on('decodedall', () => { /* all done */ });

設定リファレンス

SoundConfig
プロパティ型デフォルト説明
mutebooleanfalseサウンドがミュートされているかどうか
volumenumber1音量、0(無音)から 1(最大)まで
ratenumber1再生速度(0.5 = 半分、2.0 = 2 倍)
detunenumber0セント単位のデチューン(-1200 から 1200)
seeknumber0再生開始位置(秒)
loopbooleanfalseサウンドをループさせるかどうか
delaynumber0再生開始前の遅延(秒)
pannumber0ステレオパン、-1(左)から 1(右)まで
sourceSpatialSoundConfignull空間オーディオ設定(WebAudio のみ)
SpatialSoundConfig

位置: x(0)、y(0)、z(0) -- ワールド空間におけるソースの位置。 向き: orientationX(0)、orientationY(0)、orientationZ(-1) -- ソースの方向ベクトル。 モデル: panningModel('equalpower' または 'HRTF')、distanceModel('linear'、'inverse'、'exponential')。 距離: refDistance(1)、maxDistance(10000)、rolloffFactor(1)。 コーン: coneInnerAngle(360)、coneOuterAngle(0)、coneOuterGain(0)。 トラッキング: follow(null) -- x/y がフレームごとに自動追跡される Vector2Like オブジェクト。

SoundMarker
プロパティ型デフォルト説明
namestring(必須)マーカーの一意の識別子
startnumber0開始位置(秒)
durationnumber(残り)再生時間(秒)
configSoundConfig{}このマーカーのデフォルト設定

イベント

サウンドインスタンスイベント(Sound オブジェクトで発行)
イベント定数文字列値コールバック引数発行タイミング
Events.PLAY'play'(sound)サウンドの再生が開始されたとき
Events.PAUSE'pause'(sound)サウンドが一時停止されたとき
Events.RESUME'resume'(sound)サウンドが一時停止から再開されたとき
Events.STOP'stop'(sound)サウンドが停止されたとき
Events.COMPLETE'complete'(sound)サウンドが最後まで再生されたとき(非ループ)
Events.LOOPED'looped'(sound)サウンドが先頭にループバックしたとき
Events.LOOP'loop'(sound, value)ループプロパティが変更されたとき
Events.MUTE'mute'(sound, value)ミュート状態が変更されたとき
Events.VOLUME'volume'(sound, value)音量が変更されたとき
Events.RATE'rate'(sound, value)再生レートが変更されたとき
Events.DETUNE'detune'(sound, value)デチューンが変更されたとき
Events.SEEK'seek'(sound, value)シーク位置が変更されたとき
Events.PAN'pan'(sound, value)パン値が変更されたとき
Events.DESTROY'destroy'(sound)サウンドが破棄されたとき
SoundManager イベント(this.sound で発行)
イベント定数文字列値コールバック引数発行タイミング
Events.PAUSE_ALL'pauseall'(manager)pauseAll() が呼び出されたとき
Events.RESUME_ALL'resumeall'(manager)resumeAll() が呼び出されたとき
Events.STOP_ALL'stopall'(manager)stopAll() が呼び出されたとき
Events.GLOBAL_MUTE'globalmute'(manager, value)グローバルミュートが変更されたとき
Events.GLOBAL_VOLUME'globalvolume'(manager, value)グローバル音量が変更されたとき
Events.GLOBAL_RATE'globalrate'(manager, value)グローバルレートが変更されたとき
Events.GLOBAL_DETUNE'globaldetune'(manager, value)グローバルデチューンが変更されたとき
Events.UNLOCKED'unlocked'(manager)ユーザー操作後にオーディオシステムのロックが解除されたとき
Events.DECODED'decoded'(key)単一のオーディオキーがデコードされたとき(WebAudio)
Events.DECODED_ALL'decodedall'()キュー内のすべてのオーディオがデコードされたとき(WebAudio)
// Example: listen for completion
const sfx = this.sound.add('bang');
sfx.on('complete', (sound) => {
    console.log(sound.key, 'finished');
});
sfx.play();

API クイックリファレンス

BaseSoundManager(this.sound)

メソッド: add(key, config?), addAudioSprite(key, config?), play(key, extra?), playAudioSprite(key, spriteName, config?), get(key), getAll(key?), getAllPlaying(), isPlaying(key?), remove(sound), removeByKey(key), removeAll(), stopAll(), stopByKey(key), pauseAll(), resumeAll(), setListenerPosition(x?, y?), setMute(value), setVolume(value), setRate(value), setDetune(value).

プロパティ: volume(0〜1)、mute(boolean)、rate(number)、detune(-1200〜1200)、pauseOnBlur(boolean、デフォルト true)、locked(boolean、読み取り専用)、listenerPosition(Vector2)、sounds(配列、プライベート)。

BaseSound(サウンドインスタンス)

メソッド: play(markerName?, config?), pause(), resume(), stop(), destroy(), addMarker(marker), updateMarker(marker), removeMarker(name), setMute(value), setVolume(value), setRate(value), setDetune(value), setSeek(value), setLoop(value), setPan(value).

プロパティ: volume(0〜1)、mute(boolean)、rate(number)、detune(number)、seek(秒)、loop(boolean)、pan(-1〜1)、isPlaying(読み取り専用)、isPaused(読み取り専用)、duration(秒)、totalDuration(秒)、key(string)、x / y(空間位置、WebAudio のみ)。

すべての set* メソッドはチェーン用に this を返します。

注意点

ブラウザの自動再生ポリシー

ブラウザはユーザーの操作があるまで音声をブロックします。Phaser はこれを自動的に処理します:

  • WebAudio: AudioContext はサスペンド状態で開始します。Phaser は document.body 上の touchstart/touchend/mousedown/mouseup/keydown をリッスンして context.resume() を呼び出します。locked プロパティはロック解除されるまで true です。解決されると UNLOCKED イベントが 1 回発火します。
  • HTML5 Audio: ロックされた audio タグは、最初のタッチでそれらを再生し直すまで、すべてのアクションをキューに入れます。

ロック解除を手動で処理する必要はありません。準備ができたことを知るには、UNLOCKED をリッスンします:

if (this.sound.locked) {
    this.sound.once('unlocked', () => {
        this.sound.play('bgm');
    });
} else {
    this.sound.play('bgm');
}
音声フォーマットのサポート

すべての環境で動作する単一のフォーマットはありません。複数のフォーマットを用意してください: this.load.audio('bgm', ['assets/bgm.ogg', 'assets/bgm.mp3'])。MP3 は最も幅広くサポートされています。OGG Vorbis は Safari のサポートがありません。AAC/M4A は Safari/iOS で問題なく動作します。WebM/Opus は優れた品質ですが、古いブラウザでのサポートは限定的です。

HTML5 Audio の同時再生

HTML5 Audio は <audio> タグのプールを使用します。同時再生のためにロード時に instances を指定します: this.load.audio('shot', 'assets/shot.mp3', { instances: 4 })。デフォルトは 1 です。すべてのタグが使用中で manager.override が true (デフォルト) の場合、最も再生が進んでいるサウンドが乗っ取られます。WebAudio にはこのような制限はありません。

iOS/Safari 特有の事項
  • StereoPannerNode は iOS/Safari ではサポートされていないため、pan は聴覚上の効果がありません (イベントは引き続き発火します)。
  • iOS 17/18+ ではバックグラウンドで音声が中断されることがあります。Phaser は VISIBLE ゲームイベントで context.suspend()/context.resume() を介してこれを処理します。
  • setListenerPosition() と空間オーディオは WebAudio 専用です。
WebAudio コンテキストの再利用

ページ全体をリロードせずにゲームを再作成する SPA では、ゲーム設定で audio: { context: existingAudioContext } を渡します。実行時に this.sound.setAudioContext(newContext) を介してコンテキストを差し替えることもできます (WebAudio のみ)。

Sound Manager は共有 (グローバル)

SoundManager はシーンごとではなく、ゲームごとに 1 つです。すべてのシーンで this.sound は同じマネージャーを参照します。サウンドはシーンのシャットダウン時に自動的にクリーンアップされません -- 必要であれば自分で停止/削除する必要があります。ループサウンドは、明示的に停止しない限り、シーンの変更をまたいで再生され続けます。

ファイア・アンド・フォーゲットと永続サウンド

this.sound.play(key) は完了時に自動破棄されるサウンドを作成します -- play を呼び出した後にそれを制御することはできません。一時停止、停止、音量調整、またはイベントのリッスンのために永続的な参照が必要な場合は、this.sound.add(key) を使用してください。

空間オーディオは WebAudio 専用

空間オーディオ用の source 設定は、HTML5 Audio を使用している場合は黙って無視されます。ゲームが HTML5 Audio フォールバックをサポートする必要がある場合、ゲームプレイ上重要な音声キューを空間配置に頼らないでください。

Web Audio Analyser (WebAudio 専用)

周波数/波形の可視化のために AnalyserNode を作成するには、基盤となる AudioContext にアクセスします:

const analyser = this.sound.context.createAnalyser();
analyser.fftSize = 256;
this.sound.masterVolumeNode.connect(analyser);
analyser.connect(this.sound.context.destination);

const dataArray = new Uint8Array(analyser.frequencyBinCount);

// In update loop
analyser.getByteFrequencyData(dataArray);
// Use dataArray values to drive visual effects

これは WebAudioSoundManager でのみ動作します。使用する前に this.sound.context が存在するか確認してください。

ソースファイルマップ

ファイル目的
src/sound/SoundManagerCreator.jsファクトリー: WebAudio、HTML5、または NoAudio マネージャーを選択します
src/sound/BaseSoundManager.jsベースマネージャー: 追加、再生、取得、すべての停止/一時停止/再開、グローバル音量/レート/デチューン
src/sound/BaseSound.jsベースサウンド: 再生/一時停止/再開/停止、マーカー、設定、calculateRate
src/sound/webaudio/WebAudioSoundManager.jsWebAudio マネージャー: AudioContext、ゲインノード、アンロック、空間リスナー、decodeAudio
src/sound/webaudio/WebAudioSound.jsWebAudio サウンド: バッファソース、空間/パンナーノード、シーク、すべてのプロパティ
src/sound/html5/HTML5AudioSoundManager.jsHTML5 マネージャー: audio タグのプーリング、ロックされたキュー、オーバーライド
src/sound/html5/HTML5AudioSound.jsHTML5 サウンド: タグベースの再生、限定された機能セット
src/sound/noaudio/NoAudioSoundManager.jsオーディオのない環境向けのノーオペレーションマネージャー
src/sound/events/すべてのサウンドイベント定数 (PLAY、STOP、COMPLETE など)
src/sound/typedefs/SoundConfig.jsSoundConfig 型定義
src/sound/typedefs/SoundMarker.jsSoundMarker 型定義
src/sound/typedefs/SpatialSoundConfig.jsSpatialSoundConfig 型定義
src/sound/typedefs/AudioSpriteSound.jsAudioSpriteSound 型定義

コメント