Phaser3 音を鳴らす
Posted
Phaser3 音を鳴らす
前回の記事
https://mijinc0.github.io/blog/post/20200821_phaser3_depth/
基本
Phaser3で音を鳴らすには(Base|Web|Html5)SoundManager
を使うことになる。
…なるのだが、Webブラウザで音を鳴らすには一つ工夫が必要になる。Chromeなどのブラウザでは、Webサイトにアクセスした途端に音が鳴ることをデフォルトで許可していないことがある。(Webサイトにアクセスした途端に音が鳴ったりすると嫌ですよね)
そのため、各ブラウザによってWebサイトで音を鳴らすための条件をクリアしないと音が鳴らせない。最も簡単で一般的な条件は “ユーザーのアクションをトリガーにする” というものである。簡単に言うと、再生
ボタンを押したら音が鳴るような処理であれば、音を鳴らしても良いよとブラウザが判断するということ。(“ブラウザの自動再生ポリシー"で検索)
Phaser3のチュートリアルを雛形にゲームを作り始めると、ページにアクセスした途端に<canvas>
を描写し始める。これだと、音を鳴らすことが出来ない。回避するためには、ランチャーのようなベージをはさみ、PlayGame (音が出ます)
などのボタンを押すことでゲームが立ち上がるようにスクリプトを組む必要がある。
これで、ブラウザ内で起動するゲームの中で音を鳴らすことが出来るようになる。
3つのSoundManager
https://photonstorm.github.io/phaser3-docs/Phaser.Sound.BaseSoundManager.html
Phaser3には基盤となるBaseSoundManager
を継承した3つのサウンドマネージャーがある
- WebAudioSoundManager
- HTML5AudioSoundManager
- NoAudioSoundManager
そしてそれらが扱うサウンドオブジェクトとして、
- WebAudioSound
- HTML5AudioSound
- NoAudioSound
がある。WebAudioSound
とHTML5AudioSound
はBaseSound
を継承しているが、NoAudioSound
はBaseSound
を継承していない。
javascriptを使っている時は余り気にならないかもしれないが、typescriptを使って書いている時はこのコンテキストの違いが少し面倒で、なぜかと言うとBaseSound
クラスにはvolume
プロパティが無く、volume
プロパティはWebAudioSound
クラスとHTML5AudioSound
クラスに直接生えているため、再生開始時の音量設定は出来ても、typescriptの型としてBaseSound
なインスタンスを操作している時は(volume
プロパティが型としてないので)再生中の音の調整ができない。これだとBGMをイベントの雰囲気作りで音量を下げたいなどの時に困る。
勿論、<any>
でキャストしてしまえば済む話と言ってしまえばそうだが、それを嫌う場合はサウンドオブジェクトがWebAudioSound
またはHTML5AudioSound
であることを検査するカスタムのtypeguard関数を用意する必要がある。
音のフェード
Phaser3では標準的に音のフェード機能はない。tweenを使って自分で作る。上記でtypescriptで書いている時にサウンドオブジェクトのvolume
プロパティにアクセスする時は自家製のtypeguardが必要と書いたが、tweenを使うだけなら型の検査はすり抜けるので普通にtweenを使えば良い。
const soundConfig = {
// 設定
};
const soundObject = this.scene.sound.add('bgm', soundConfig);
// fade in
this.scene.add.tween({
targets: soundObject,
volume: {from: 0, to: 1},
duration: 1000,
});
sounObject.play();
参考
https://rexrainbow.github.io/phaser3-rex-notes/docs/site/audio/