audio-and-sound について
Phaser のゲーム開発者向けに、音声の読み込みと再生制御を解説するリファレンスです。Web Audio と HTML5 Audio の各バックエンドの機能も紹介します。
主な機能
- 01Web Audio と HTML5 Audio のバックエンド
- 02再生、ループ、音量の制御
- 03マーカー、オーディオスプライト、空間音響
- 04一時停止、再開、ブラウザー音声の有効化
活用シーン
- 01BGM やゲーム効果音の再生
- 02複数のクリップをオーディオスプライトに設定
- 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() を介して最適なバックエンドを自動選択します:
config.audio.noAudioが true の場合、またはデバイスが Web Audio も HTML5 Audio もサポートしていない場合、NoAudioSoundManager が作成されます(すべての呼び出しは no-op です)。- デバイスが Web Audio をサポートし、
config.audio.disableWebAudioが true でない場合、WebAudioSoundManager が作成されます(推奨)。 - それ以外の場合、フォールバックとして 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
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
mute | boolean | false | サウンドがミュートされているかどうか |
volume | number | 1 | 音量、0(無音)から 1(最大)まで |
rate | number | 1 | 再生速度(0.5 = 半分、2.0 = 2 倍) |
detune | number | 0 | セント単位のデチューン(-1200 から 1200) |
seek | number | 0 | 再生開始位置(秒) |
loop | boolean | false | サウンドをループさせるかどうか |
delay | number | 0 | 再生開始前の遅延(秒) |
pan | number | 0 | ステレオパン、-1(左)から 1(右)まで |
source | SpatialSoundConfig | null | 空間オーディオ設定(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
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
name | string | (必須) | マーカーの一意の識別子 |
start | number | 0 | 開始位置(秒) |
duration | number | (残り) | 再生時間(秒) |
config | SoundConfig | {} | このマーカーのデフォルト設定 |
イベント
サウンドインスタンスイベント(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.js | WebAudio マネージャー: AudioContext、ゲインノード、アンロック、空間リスナー、decodeAudio |
src/sound/webaudio/WebAudioSound.js | WebAudio サウンド: バッファソース、空間/パンナーノード、シーク、すべてのプロパティ |
src/sound/html5/HTML5AudioSoundManager.js | HTML5 マネージャー: audio タグのプーリング、ロックされたキュー、オーバーライド |
src/sound/html5/HTML5AudioSound.js | HTML5 サウンド: タグベースの再生、限定された機能セット |
src/sound/noaudio/NoAudioSoundManager.js | オーディオのない環境向けのノーオペレーションマネージャー |
src/sound/events/ | すべてのサウンドイベント定数 (PLAY、STOP、COMPLETE など) |
src/sound/typedefs/SoundConfig.js | SoundConfig 型定義 |
src/sound/typedefs/SoundMarker.js | SoundMarker 型定義 |
src/sound/typedefs/SpatialSoundConfig.js | SpatialSoundConfig 型定義 |
src/sound/typedefs/AudioSpriteSound.js | AudioSpriteSound 型定義 |