Loading Scenes Dynamically

Hi everyone, I’m trying to create a MMORPG using phaser. I’m still learning the framework so bear with me here. What i’m trying to do is to load the scenes in dynamically once the players moves to the new scene.

Currently, I have all my scenes extending the base scene which extends the phaser scene.

I have a function that checks if the player is on the portal, if it is then it calls the movePlayerToNextMap function.

The two issues I am facing is:

  1. I am unable to dynamically create the scene without creating a class object of that scene.
    Lets say my next scene is ForestScene and I have a corresponding class called ForestScene which extends the Phaser.Scene. I am unable to add this scene to the scene manager, unless I create an instance of ForestScene and then pass this object into the SceneManager.

  2. I have a function called movePlayerToNextMap inside the outter most child scene because I have it extend BaseScene which extends the Phaser scene. Therefore, I cannot put movePlayerToNextMap in the BaseScene class because if I have another scene called DesertScene which extends BaseScene, then i cannot create an instance of the DesertScene within the BaseScene since it is a child of BaseScene. However, all my Scenes should extend BaseScene and all BaseScene should have movePlayerToNextMap method.

Here is my implementation of movePlayerToNextMap

 movePlayerToNextMap(nextScenePortalObj) {
        const nextSceneKey = nextScenePortalObj.name;
        const sceneObj = new DesertScene();
        if (!this.scene.manager.getScene(nextSceneKey)) {
            this.scene.add(nextScenePortalObj.name, sceneObj, true);
            this.scene.remove('forestScene);
        }
    }

Welcome Meitou,
It sounds like you’re just trying to go through a portal in your game and load the corresponding scene, right? If that’s the case, you should load all of your scenes in your main.js class, right after you create your phaser game. Here’s an example:

this.game.scene.add('Boot', new Boot());
this.game.scene.add('Preloader', new Preloader());
this.game.scene.add('DesertScene', new DesertScene());
this.game.scene.add('World', new World());

Once completed, in any of your scenes, you can progress to a different scene like so:
this.scene.start('Boot');

So in your example, I would create a portal with a property such as portal.sceneKey = "DesertScene". Once the player has interacted with the portal, you can simply do: this.scene.start(portal.sceneKey);.

1 Like

You can also use webpack to lazyload your scenes with code splitting. See the snippet below which is from my phaser template.

export default class PreloadScene extends Phaser.Scene {
  constructor() {
    super({ key: 'PreloadScene' })
  }

  preload() {
    this.load.image('phaser-logo', 'assets/img/phaser-logo.png')
  }

  create() {
    this.scene.start('MainScene')

    /**
     * This is how you would dynamically import the mainScene class (with code splitting),
     * add the mainScene to the Scene Manager
     * and start the scene.
     * The name of the chunk would be 'mainScene.chunk.js
     * Find more about code splitting here: https://webpack.js.org/guides/code-splitting/
     */
    // let someCondition = true
    // if (someCondition)
    //   import(/* webpackChunkName: "mainScene" */ './mainScene').then(mainScene => {
    //     this.scene.add('MainScene', mainScene.default, true)
    //   })
    // else console.log('The mainScene class will not even be loaded by the browser')
  }
}

Can you explain? There’s no problem with adding multiple scenes from the same class as long as you use distinct keys, e.g.,

this.scene.add('DesertScene1', DesertScene, true); // …
this.scene.add('DesertScene2', DesertScene, true); // … etc.