We suggest Memory Match. A Mario Party-inspired memory game where you control a character to pick boxes until all matches are found within a limited amount of time.
In this final part, we will look at adding a countdown timer that will cause the player to lose when time runs out.
We also have a video version on YouTube if you prefer to watch or want to see how it is coded in real-time.
Controlling a Countdown
We can add some challenge to Memory Match by adding a timer that shows how much time the player has left to find all the matches.
Let's start by creating a
CountdownController class to hold all the logic for counting down and updating a
Text display to show how much time is left.
Create a new
CountdonwController.js file in the
scenes folder with this barebones set up:
This class takes in a
Scene reference and
Text reference. We will pass these in when we created a new
CountdownController in the
Then we have 3 unimplemented methods:
start() method will begin the countdown and then call a callback function when it is finished. An optional
duration can be passed in to change how long the countdown should be.
stop() method will stop the countdown and the
update() method will handle calculating the current time remaining and updating the passed in
Text instance stored in
Text object. Hence the name Countdown Controller.
Creating a Timer
CountdownController skeleton ready, we can simply implement each method to perform their specific tasks.
Let's start with the
start() method. It will create a
TimerEvent and then invoke a given callback when it is finished.
First, we call
stop() just in case there is already another
TimerEvent running. This
CountdownController assumes just 1 countdown at a time.
Then we create a
this.scene.time.addEvent() by passing in a configuration object with a duration or delay and a callback.
timerEvent is a class property so we should add that to the class like this:
Lastly, once this timer is finished we execute the
callback if one was given.
Next, let's see what the
stop() method looks like:
This very simply checks if
this.timerEvent exists and then destroys it if it does. Nothing will happen if
this.timerEvent is already
Last method left is the
update() method. This is where the countdown time math happens.
We early exit if there is no
timerEvent or if the duration is
0 or less.
Then we get the elapsed time from the
timerEvent and subtract it from the total duration to get time remaining. Time remaining is in milliseconds so we divide by
1000 to get time in seconds.
With time in seconds, we set
this.label to show the time up to 2 decimal places with
Finally, notice that we are using
this.duration which is a class property so add that to the class and set it to the
duration argument given to
start() like this:
And that is the complete
Using CountdownController from Game
CountdownController means we need to create an instance by passing in the
Scene and a
Text object. Then we call
start() to begin the countdown and make sure that
update() is called from the Scene's
Here's how we create a
CountdownController in the
First, we import the
CountdownController class so that we can use it in the
Then we create a class property on line 11 and set it to a new instance on line 22 with a newly added
Next, we need to make sure the countdown's
update() method is being called:
Make sure to also call
stop() when all matches have been found in the
Now, we need to call
start() and pass in a callback method when the countdown is finished.
Add this after we create a new instance of
CountdownController in the
We are passing in the
handleCountdownFinished() method so we'll have to create it.
Notice that we are using
.bind(this). This will return a new function based on the
handleCountdownFinished() method with its context set as
this whenever it is invoked.
handleCountdownFinished() looks like:
This should look fairly similar to the logic when a level is completed except we show a “You Lose!” message instead.
You should see something like this when the countdown expires and not all matches have been found 👇
Memory Match Extras
We hope you've enjoyed making Memory Match! There's a bunch more you can add to this game to make it your own.
Some core improvements you can add are:
- sound effects
- restart after losing
- better fonts (Web or Bitmap)
- preload animation
That's why we created the Memory Match Extras video course that covers all these things plus gamepad support 🎮, code organization & clean-up 💻, using nineslice for dialogs 🔪, and more!
Learn more in this short preview 👇
There are even bonuses to help you debug code and navigate the official Phaser documentation better so that you can solve more of your own problems without hoping for a response on forums or Discord.
Use it as a way to compare and contrast against what you did. The Memory Match Extras course comes with an updated & improved source code plus a TypeScript version.
If you are not yet ready for a course then 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.