-
Notifications
You must be signed in to change notification settings - Fork 4
Sound
Frequently misunderstood. 😢
Most browsers won't play sound until the user clicks/taps on the game. You can check the sound manager's locked
property for this.
Chrome gives a console warning if the game boots using Web Audio:
The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page
That's normal. Phaser will try to resume the audio context after the first user gesture (click/tap). If you don't need sound in your game, disable audio and you won't see this warning.
Some browsers give a console error when playing a locked sound fails, and some don't.
Phaser 3 uses Web Audio, the audio element (“HTML5 Audio”), or no audio, depending on the device support (which you can find in game.device.audio
). Most devices support Web Audio. Detuning and panning effects are in Web Audio only. Web Audio may have lower latency.
You can disable Web Audio with
new Phaser.Game({ audio: { disableWebAudio: true } });
or disable all audio with
new Phaser.Game({ audio: { noAudio: true } });
See details in Media container formats and Web audio codec guide. If you're publishing a game you should probably support more than one audio format.
When loading audio, Phaser matches the media type (inferred from the URL or given by you) with the device's support for that type. If there's no match, nothing is downloaded and if you try to create or play a sound with that key it will fail with an error.
You can give an explicit media type like
this.load.audio('scream', { url: 'scream.mpg', type: 'm4a' });
The type
keywords are in Phaser.Device.Audio.
If you want to play simultaneous sounds from the same source in HTML5 Audio mode, give instances
:
this.load.audio('laser', 'laser.mpg', { instances: 4 });
In Web Audio mode, the audio cache (game.cache.audio
) stores AudioBuffer. In HTML5 Audio mode, it stores arrays of audio element (one per instance).
- audiosprite makes audio sprite files for loading in Phaser
There is one global sound manager, available on game.sound
or this.sound
on a scene. You can think of it as an audio player.
It can be convenient to create a second sound manager.
new Phaser.Game({
callbacks: {
preBoot: function (game) {
game.music = Phaser.Sound.SoundManagerCreator.create(game);
}
}
});
Then in a scene you use this.game.music
instead of this.sound
.
These are like audio tracks.
If you need to play a sound through once, use sound.play()
:
this.sound.play('kapow');
That's it. Repeat as necessary.
If you need to pause, stop, or monitor a specific sound, create a sound object:
const kapowSound1 = this.sound.add('kapow');
kapowSound1.play();
// …
kapowSound1.pause();
// …
kapowSound1.resume();
If you call a sound's play()
method again, it will restart. If you want to play multiple sounds at once from the same source, add multiple sounds (remember these are like tracks):
const kapowSound2 = this.sound.add('kapow');
const kapowSound3 = this.sound.add('kapow');
You should discard sounds when finished with them:
kapowSound1.destroy();
// etc.
Time values (e.g., delay
, duration
, seek
) are in seconds, not milliseconds.
You can work on sounds in the manager even without a direct reference: get()
, getKey()
, stopByKey()
, removeByKey()
.
For audio sprites you use load.audioSprite()
and then sound.playAudioSprite()
or sound.addAudioSprite()
.
You can also add markers to any sound created with sound.add()
.