Loading...
Loading...
This skill should be used when the user asks to "add sound", "play music", "audio not working", "add background music", "sound effects", "mute button", "audio sprite", "game audio", "play sound effect", or "music won't play".
npx skill4agent add yakoub-ai/phaser4-gamedev phaser-audioAudioContextconst config: Phaser.Types.Core.GameConfig = {
audio: {
disableWebAudio: true, // force HTML5 Audio fallback
},
};// preload()
preload(): void {
// ALWAYS provide both formats as an array — mp3 first, ogg second
this.load.audio('music-main', ['assets/audio/main.mp3', 'assets/audio/main.ogg']);
this.load.audio('sfx-jump', ['assets/audio/jump.mp3', 'assets/audio/jump.ogg']);
this.load.audio('sfx-coin', ['assets/audio/coin.mp3', 'assets/audio/coin.ogg']);
this.load.audio('sfx-hurt', ['assets/audio/hurt.mp3', 'assets/audio/hurt.ogg']);
}.oggthis.sound.add()add()create(): void {
const music = this.sound.add('music-main', {
loop: true,
volume: 0.6,
});
music.play();
this.music = music;
}this.sound.play()play()// In update() or an event handler:
this.sound.play('sfx-coin', { volume: 0.9 });
this.sound.play('sfx-jump', { volume: 1.0, rate: 1.1 });add()sound.play()SoundConfigadd()play()const config: Phaser.Types.Sound.SoundConfig = {
loop: false, // boolean — loop the sound (default: false)
volume: 1, // number 0–1 — per-sound volume (default: 1)
rate: 1, // number — playback speed multiplier (default: 1; 2 = double speed)
detune: 0, // number — cents offset from base pitch (default: 0; 100 = 1 semitone)
seek: 0, // number — start position in seconds (default: 0)
delay: 0, // number — seconds to wait before playing (default: 0)
};// --- In PreloaderScene.preload() ---
this.load.audio('music-game', ['assets/audio/game.mp3', 'assets/audio/game.ogg']);
this.load.audio('music-menu', ['assets/audio/menu.mp3', 'assets/audio/menu.ogg']);
// --- In GameScene.create() ---
this.bgMusic = this.sound.add('music-game', { loop: true, volume: 0.5 });
this.bgMusic.play();
// Adjust volume at runtime
this.bgMusic.setVolume(0.3);
// Pause/resume (e.g. on pause screen)
this.bgMusic.pause();
this.bgMusic.resume();
// Stop (e.g. on scene shutdown)
this.bgMusic.stop();this.sound.play()// In any scene method or event handler:
this.sound.play('sfx-coin', { volume: 0.9 });
this.sound.play('sfx-jump', { volume: 1.0, rate: 1.05 });
this.sound.play('sfx-death', { volume: 0.8, detune: -200 });play()create(): void {
// Create a pool of 5 gunshot sounds
this.gunshotPool = [];
for (let i = 0; i < 5; i++) {
this.gunshotPool.push(this.sound.add('sfx-gunshot', { volume: 0.8 }));
}
this.poolIndex = 0;
}
private fireGunshot(): void {
const snd = this.gunshotPool[this.poolIndex];
// Stop any currently playing instance at this slot, then play fresh
if (snd.isPlaying) snd.stop();
snd.play();
this.poolIndex = (this.poolIndex + 1) % this.gunshotPool.length;
}// preload()
this.load.audioSprite(
'sfx-pack', // key
'assets/audio/sfx-pack.json', // JSON with marker definitions
['assets/audio/sfx-pack.mp3', 'assets/audio/sfx-pack.ogg'] // audio files
);// this.sound.playAudioSprite(key, markerName, config?)
this.sound.playAudioSprite('sfx-pack', 'coin');
this.sound.playAudioSprite('sfx-pack', 'jump', { volume: 0.8 });
this.sound.playAudioSprite('sfx-pack', 'hurt', { rate: 1.2 });{
"resources": ["sfx-pack.mp3", "sfx-pack.ogg"],
"spritemap": {
"coin": { "start": 0.0, "end": 0.4, "loop": false },
"jump": { "start": 0.5, "end": 0.85, "loop": false },
"hurt": { "start": 1.0, "end": 1.6, "loop": false },
"music": { "start": 2.0, "end": 34.0, "loop": true }
}
}references/audio-api.md// Global volume (affects all sounds)
this.sound.volume = 0.5; // set
const vol = this.sound.volume; // get
// Per-sound volume
music.setVolume(0.4);
const soundVol = music.volume;
// Mute/unmute everything
this.sound.mute = true; // mute all
this.sound.mute = false; // unmute all
// Check if global mute is on
const isMuted = this.sound.mute;create(): void {
const muteBtn = this.add.image(750, 30, 'btn-mute').setInteractive();
muteBtn.on('pointerdown', () => {
this.sound.mute = !this.sound.mute;
muteBtn.setTexture(this.sound.mute ? 'btn-unmute' : 'btn-mute');
});
}pointerdownkeydownAudioContextif (this.sound.locked) {
// AudioContext has not yet been unlocked
// Show a "tap to start" overlay
}
// Listen for the unlock event
this.sound.on(Phaser.Sound.Events.UNLOCKED, () => {
// Now safe to play audio
this.bgMusic.play();
});play()create(): void {
this.bgMusic = this.sound.add('music-main', { loop: true, volume: 0.6 });
if (this.sound.locked) {
const overlay = this.add.rectangle(400, 300, 800, 600, 0x000000, 0.7)
.setInteractive();
const label = this.add.text(400, 300, 'TAP TO START', {
fontSize: '32px', color: '#ffffff',
}).setOrigin(0.5);
this.sound.once(Phaser.Sound.Events.UNLOCKED, () => {
overlay.destroy();
label.destroy();
this.bgMusic.play();
});
} else {
this.bgMusic.play();
}
}AudioContextthis.sound.lockedfalse// In PreloaderScene.create() or main.ts, after game is initialized:
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
const mgr = this.sound as Phaser.Sound.WebAudioSoundManager;
if (mgr.context?.state === 'suspended') {
mgr.context.resume();
}
}
});this.game.events.on(Phaser.Core.Events.FOCUS, () => {
const mgr = this.sound as Phaser.Sound.WebAudioSoundManager;
if (mgr.context?.state === 'suspended') {
mgr.context.resume();
}
});mgr.context?.stateresume()'running''closed'| State | Meaning |
|---|---|
| Audio playing normally |
| Paused (tab hidden, device sleep) — call |
| Permanently closed — create a new game instance |
// --- In OutgoingScene.shutdown() ---
shutdown(): void {
if (this.bgMusic?.isPlaying) {
this.tweens.add({
targets: this.bgMusic,
volume: 0,
duration: 500,
onComplete: () => this.bgMusic.stop(),
});
}
}
// --- In IncomingScene.create() ---
create(): void {
this.bgMusic = this.sound.add('music-new', { loop: true, volume: 0 });
this.bgMusic.play();
this.tweens.add({
targets: this.bgMusic,
volume: 0.6,
duration: 800,
ease: 'Linear',
});
}this.tweenssound.volume// Stop all sounds owned by the SoundManager (global — affects all scenes)
this.sound.stopAll();
// Stop only a specific sound
this.bgMusic.stop();
// Preferred pattern in shutdown():
shutdown(): void {
// If music belongs to this scene only
this.bgMusic?.stop();
// If this is a top-level scene and you want to silence everything:
// this.sound.stopAll();
}stopAll()references/audio-api.md