The best practices for using es6 constructor?

  1. What can we do in our constructor and what we can’t?
  2. The difference between constructor and ‘create’ method?
  3. What we must put to the constructor and what to the ‘create’ method?
  4. How do you use the constructor in your code?

Now I am using constructor when I want to get a scene in the derived class and then I use this scene to create new objects and move all ‘this.’ initialization from ‘create’ method to constructor because 80% depends on the received scene. So the ‘create’ method becomes useless and empty. Maybe I do something wrong.

Hi!

  1. Normally, you can do pretty much anything you want in a constructor. A constructor is just the initialization function that gets called when you use the ‘new’ keyword to instantiate an object.

  2. create is a Phaser defined function that gets called once a scene’s preload sequence is complete. It’s your entry point in your scene when the engine is ready for you to begin ‘creating’ the game objects that are going to be in your scene. Again, constructor is the initialization function called when using ‘new’.

Also: it’s very possible that ‘create’ could be called multiple times on a scene object, whereas the constructor generally is only ever called once when you instantiate the object.

  1. In ‘create’ instantiate the game objects you want in the scene. In the constructor, put any one shot initialization stuff.

  2. In my code, I generally use my constructors to lay out what member variables I plan to use in my class. I defined my member variables with default values to avoid undefined object reference. This will very from developer to developer though.

2 Likes

Good answer already but I wanted to add the Golden Rule of ES6 constructors: If you extend a class, you MUST call the super class’s constructor, every time. Even if it doesn’t seem like it is doing anything to you:

class Example extends Parent {
    constructor() {
        super();
    }
}

My IDE actually yells at me if I forget to do this which is helpful. Forgetting to do it can either cause a runtime exception or strange behavior.

Try to get in the habit of calling the super’s constructor every time you extend a class.

2 Likes

Also: it’s very possible that ‘create’ could be called multiple times on a scene object

Oh, it’s so unexpected for me. I have some game logic that depends on one call of ‘create’ method and it will be ruined otherwise. Can you provide some examples when it occurs?

Hi @strol,
From the constructor you can’t access the properties and methods of the scene. For example, this.add.image(…) would cause an error (Can not read property … of undefined).
Regards.

1 Like

Hi, why? When I check this I get something strange :

class Scene1 extends Phaser.Scene {
    constructor() {
        super();
        console.log(this); // image exist
        console.log(this.add.image); // image doesn't exist
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    scene: [Scene1]
};

const game = new Phaser.Game(config);

Outpust of first console.log is :


So why image is there and console.log(this) prove it but if I write console.log(this.add.image) or console.log(this.add) it returns undefined

In some browsers (Chrome …), console.log has an asynchronous behavior with objects.

1 Like

And how about this code :

class Animal {
  constructor() {
	this.name = "Jon";
  }
  getName(){
	console.log(this.name);
  }
}

class Rabbit extends Animal {
  constructor() {
    super();
    this.getName(); // Already existed
  }
}

new Rabbit(); 

demo
this.getName() has already been accessible. Therefore what’s wrong with this.add.image?

The GameObjectFactory (this.add. …) is a scene plugin, so it is not available until the sceneManager calls the sys.init() method of the scene.

1 Like

Thank you for your clarification, now it’s totally clear:)

An example of multiple calls to create would be if you had a title screen scene. When you’re game loads up, the player is showed that title screen so create is called then. Then you enter your game and the player then exits the game via a menu back to the title screen so create is called again the second time you enter the title screen.

The way Phaser manages its states is when you call this.state.add(…), this call will instantiate the state object (calling new MyState). It then store that instantiated object in a map using the key you provide to store it. Then when you call this.state.start(…), it pulls the state object from that map and calls init->preload->create.

EDIT: It’s also important to note that if you manually instantiate something in create and it isn’t added to the display lists in the scene, then you need to clean it up in shutdown. Because scenes aren’t nuked when you switch scene any object instantiated and not cleaned up will hang around until the scene is reentered and object is overwritten. It’s very easy to run into memory issues if you’re not aware of how the state system works.

2 Likes