Speed is often an important performance metric in a game. If players have to react in realtime then framerate is a big deal.
One common reason for framerate problems is memory allocation inside update loops.
Memory allocation happens when creating new instances.
You generally want to avoid doing that as much as you can but making things appear in response to player interaction is unavoidable.
The solution is to use Object Pools.
In this article, we will take a look at using Object Pools in Phaser 3.
What is an Object Pool?
The big idea behind an Object Pool is to create instances of objects ahead of time to reuse them later.
Instead of creating a new instance of something you would take an unused instance from the pool.
Once finished with the instance it is returned to the pool for later use.
Like recycling. ♻️
Object Pools in Phaser
Phaser 3 has
Groups that are designed to let you create, manipulate, or recycle similar
While not described as an Object Pool, they have the fundamental features of an Object Pool.
Our example will look something like this:
Setting Up the Scene
We will keep all logic in a single Scene for simplicity. In the next article, we will look at encapsulating the Object Pool logic.
For now, just keep it simple. Note that the code is in TypeScript. 😎
All the code in
update() is only to show information about the state of our Object Pool.
Group instance that will act as our Object Pool is created on line 26.
crate.png is an image we are using from Kenney.nl and the project structure is from the phaser3-parcel-template.
Next, let's add logic to the
spawnCrate(x, y) method on line 56 to handle spawning crates.
Creating or Reusing
Phaser.GameObjects.Group class has a
get() method that will create a new instance under 2 cases:
- when the group is empty
- when all member instances are active
When there are inactive instances in the group it will return the first inactive instance it finds by checking the
Let's see how we can use
get() and add a simple scale and fade tween animation to each spawned crate.
this.group.get() on line 19 to get a member instance. It will be of type
Phaser.GameObjects.Sprite by default. We can change that by providing
classType when adding the group in
The next 4 lines are there to make sure the instance is properly reset because it could be a reused instance.
visible properties need to be reset because we set them to
false at the end of the tween by calling
scale properties are reset to 1 because they are changed by the tween.
Now let's use this method to see some crates!
We added lines 22 - 24 to listen to the
POINTER_DOWN event and then spawn a crate at the pointer location.
Run the Scene and you'll get something this:
The information text shows the size of the pool, the number of active instances spawned, and the number of inactive instances despawned.
You'll notice that the pool only gets bigger when there are no inactive instances to reuse.
That's the basics for using Object Pools with Phaser 3
In the next article, we will take this one step further and create an Object Pool class based on
Phaser.GameObjects.Group to keep specific spawn and despawn logic in one place.
Using the Phaser
Group is not strictly necessary and you can roll your own Object Pool implementation. Let us know in the comments below if you'd like to know more.
If anything doesn’t work or is unclear please leave it in the comments as well. We’ll be happy to fix or clarify!
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.