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