Are you at a point where you've made a few simple games in Phaser and generally know your way around?
And now you want to make a bigger game with better practices that allow for maintainable code?
One strategy is to use modern JavaScript or TypeScript.
With that strategy comes the traditional Object Oriented approach of organizing code with classes.
But Phaser code has a nice, readable style with few uses of new
:
|
|
It tells us in clear, concise English that we are adding a Sprite
. 👏
So how do we keep our code nice to read and use custom classes?
In this article, we will show how to do that with the GameObjectFactory
.
Custom GameObject Class
Let's make a simple Slime
enemy class that can change color. This example assumes the 'slime'
key is associated with a preloaded image.
|
|
At this point, you can use this class in a Scene with this.add.existing
like this:
|
|
Check out the source to see how this.add.existing
works and you'll notice that items may be added to the Scene Systems’ displayList
or updateList
.
Using this.add.existing
is a convenience method to keep things simple.
An alternative is to manually add slime
to the Scene Systems’ displayList
and updateList
.
Integrate with GameObjectFactory
Given this information, we can hack together a function that will create and add an instance of Slime
to the Scene.
But that won't be necessary because Phaser has a system for this called the GameObjectFactory
. 🎉
It has a register
function for adding creation methods. This will allow us to use them with this.add
.
|
|
The first parameter is the key that will be used with this.add
. In the example above it is 'slime'
which means we will be able to use it in the Scene as this.add.slime()
.
A Slime
instance is created and then added to the displayList
and updateList
like we saw in the code for this.add.existing
.
We didn't bother including the if
checks because we know our Slime
class extends from Sprite
and will need to be displayed and updated.
The best way to check what other code may be needed is to see what Phaser does for the GameObject
type you are subclassing.
Slime
subclasses Phaser.GameObjects.Sprite
so this is the code for the sprite
factory method.
GameObjectFactory.register with TypeScript
If you are using TypeScript then change function signature to look like this:
|
|
Adding this: Phaser.GameObjects.GameObjectFactory
lets TypeScript know that this
in the anonymous function is bound to Phaser.GameObjects.GameObjectFactory
.
VS Code will also provide proper code completion and IntelliSense this way. 🎉
Use in a Scene
The last step is to use our factory function in a Scene.
It is important to remember that we have to import our Slime.js
file for the factory function to be registered.
|
|
Now we can create Slime
instances in a way that keeps the readable style of Phaser code intact. 🤗
Add Typing for TypeScript
If you are using TypeScript then you'll need to use Declaration Merging to provide type information or you'll get compilation errors.
Add a Slime.d.ts
file to your project that looks like this:
|
|
The key point is the second half that declares slime(): ISlime
in the GameObjectFactory
.
Next Steps
One thing to watch out for are key collisions when using the GameObjectFactory
. You can overwrite existing keys by Phaser or other plugins by accident and experience unexpected behaviors.
One way to avoid this is to namespace your custom keys like this.add.oc_slime()
.
Be sure to sign up for our newsletter so you don't miss any future Phaser 3 game development tips and techniques!
Drop your email into the box below.
Don't miss any Phaser 3 game development content
Subscribers get exclusive tips & techniques not found on the blog!
Join our newsletter. It's free. We don't spam. Spamming is for jerks.