How do I start music in one scene and stop it in another?

I have some music playing in my main menu scene and I want to stop that music on game over from within my game scene. How do I do this?

My music code for the main menu is just:

class MainMenu extends Phaser.Scene{
constructor(){
    //super() inherits all the characteristics of the Phaser "scene" class
    super("menuGame");
}
create(){
    //Start playing menu music
    this.menuMusic = this.sound.add("menuMusic");
    var musicConfig = {
        mute: 0,
        volume: 0.6,
        seek: 0,
        loop: false, //DEBUG. Change back to true for final build
        delay: 0
    }
    this.menuMusic.play(musicConfig); // Start Playing the menu bg music
    this.scene.start("playGame");
  }
}

Now how would I stop menuMusic from within the playGame (Game.js) scene?

1 Like

Why not just stop the music before starting the game scene?
For communication between scenes, you can use emitEvent

1 Like

Because I want a seamless transition between the menu and game scene. If I started the music again in the game, it wouldn’t be seamless since it would start again from the beginning.

Hmm I’ve never used emitEvent before I’ll definitely check that out, glad to know there’s a proper way to communicate across scenes.

Hi @pritster5 ,
You can pass data between scenes. Try something like this:

// In sceneA
create(){
    let mymusic = this.sound.add('musickey');
    this.scene.start('sceneB', { music: mymusic });
// ...

// In sceneB
create(data){
    setTimeout(() => {
        data.music.stop();
    }, 2000);
// .....

Regards.

2 Likes

This solution isn’t working for me.

Here is my scene A:

class MainMenu extends Phaser.Scene{
constructor(){
    super("menuGame");
}
create(){
    let menuMusic = this.sound.add("menuMusic");
    var musicConfig = {
        mute: 0,
        volume: 0.6,
        seek: 0,
        loop: false, //DEBUG. Change back to true for final build
        delay: 0
    }
    menuMusic.play(musicConfig); // Start Playing the menu bg music
    this.scene.start("playGame", {menuMusicData: menuMusic}); // start new scene
    }    
}

And in my scene B:

update(time, data){
    if (gameOver == true){
        data.menuMusicData.stop(); //Stop music that was passed to this scene in MainMenu.js
        return;
    }

Am I doing anything wrong? Can the update() method also access data?

No. update() receive two arguments: time and delta.
data is receibed by init() and create().
But you can save data in a property and use it later in update().

2 Likes

There will be

this.sound.stopByKey('menuMusic');

if I have my way :wink:

2 Likes

@samme Those methods would be super useful. :slight_smile:

@pritster5 If you don’t need to reuse the original sound object, then you can do

this.sound.removeByKey('menuMusic');

Is that in the engine right now? Because I would love to use this since I am recreating the menuMusic object everytime I go back to the main menu anyways.

Yes, removeByKey() is in Phaser already.

2 Likes