Have you gone through our Making Your First phaser 3 Game in Modern JavaScript series? And maybe the Infinite Jumper in Phaser 3 with Modern JavaScript book as well?
That means you've got the basics down so let's try making something a little bit more complicated!
We nominate Memory Match. It is 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.
Here's a video of it from Mario Party on the Nintendo 64.
In this series, we will go over creating a 2D version using Phaser 3 and 2 assets from Kenney: Sokoban assets and Animal Pack Redux assets.
We also have a video version on YouTube if you prefer to watch or want to see how it is coded in real-time.
Getting Started
We'll be using the phaser3-parcel-template to quickly set up our project. You'll need Nodejs and NPM installed to use it.
See this article for detailed instructions on how to set it up.
Make sure you run these commands to ensure that the project is working properly:
|
|
You'll get a basic Phaser 3 logo bouncing around the screen when you go to http://localhost:8080.
The template will start you off with a HellowWorldScene
in the Scenes
folder so let's start by deleting it. We'll make a Game
Scene instead.
Create a new Game.js
file in the Scenes
folder with this barebones Scene code:
|
|
Then go to main.js
and replace the references to HelloWorldScene
with Game
like this:
|
|
The result will be a black screen. 🎉
You can try stopping the local web server and running it again with npm run start
if you see any strange errors.
Adding Assets
First, download the Sokoban assets from Kenney here.
Then, create a public
folder in your project at the same level as your src
folder.
.
├── node_modules
├── public 👈
├── src
├── package.json
Inside the public
folder, create a textures
folder. Look for the sokoban_tilesheet.png
from the Sokoban assets and copy it into the textures
folder.
.
├── node_modules
├── public
│ ├── textures
│ │ ├── sokoban_tilesheet.png
├── src
├── package.json
Now that we have the assets in our project, we can preload and then use them.
Preloading Assets
Let's start by creating a Preloader
Scene. We will preload all necessary assets here before the game starts.
Create a Preloader.js
file in the Scenes
folder like this:
|
|
Next, we can preload the sokoban_tilesheet.png
as a spritesheet in Phaser:
|
|
Spritesheet? Tilesheet?
In Phaser 3, a spritesheet is an atlas where each frame is the same size and can be referenced by their frame index. Kenney's Sokoban asset has another file called sokoban_spritesheet.png
but each frame in that atlas is not the same size.
This difference is just a matter of opinion on what the term spritesheet means. All that matters is that you want to use sokoban_tilesheet.png
and load it into Phaser as a spritesheet. 😎
Next, we can add code to switch Scenes in the create()
method so that the Game
Scene is started after all assets are preloaded:
|
|
The last thing we need to do is register the Preloader
Scene with the game in main.js
like this:
|
|
Add an Image from a Spritesheet
Let's make sure everything is loading correctly by adding an image to the Game
Scene from the loaded spritesheet.
Each frame in the spritesheet can be referenced by their index where 0
is the 64 x 64 square at the top left of the spritesheet. Then index 1
is the next 64 x 64 square to the right. Index 2
is the square to the right of that and so on.
We will use frame 52
to show a character facing down or towards the bottom of the screen.
In the create()
method of the Game
Scene:
|
|
This should result in a little man standing in the middle of the screen.
Create Animations
Our character will need to move around so let's make some animations for walking down, up, left, and right as well as being idle when facing down, up, left, and right.
This means we'll need 8 animations. 4 for walking in each direction and 4 for standing idle in each direction.
Let's start by creating the simpler idle animations in the create()
method of the Preloader
Scene:
|
|
These are all animations that are 1 frame long. Notice that we only define 1 frame in the frames
array for each created animation.
Each is also given a key
value with a consistent naming convention of “FACING_DIRECTION-idle”. We will use the same convention for the walk animations. You'll see how this is useful when we add keyboard input. 🤓
Now for the walk animations:
|
|
Notice that these are multi-frame animations and we use Phaser's generateFrameNumbers()
helper method to automatically generate the frames from a start
value to an end
value.
Then we set repeat
to -1
so that it loops forever and give it a frameRate
of 10
. Feel free to adjust this to your liking.
Playing an Animation
Let's make sure everything is working by testing the down-walk
animation in the Game
Scene:
|
|
You should see a little man facing down while running in place. 👌
Add Player Movement
We will wrap up part 1 with some player movement when using the keyboard arrow keys.
Let's start by creating an instance of Phaser's CursorKeys
that will quickly give us access to the arrow keys and the space key.
Create an init()
method in the Game
Scene like this:
|
|
Optionally, you can also add a property declaration as a class field like this:
|
|
Class fields make it easier to understand the code at first glance by clearly specifying what properties a class has. You don't need to do this but we recommend it.
Next, let's add a player
property and create a Phaser.Physics.Arcade.Sprite
to represent our player:
|
|
Destructuring
We are using some new syntax on line 12 called Destructuring Assignment. This specific operation is known as Object Destructuring where we take the width
and height
properties from this.scale
and create 2 variables of the same name from it.
It is a shortcut that is the same as this:
|
|
You'll see that the player gets created and then falls into the abyss.
This is from the gravity
of the Arcade Physics engine. We don't need gravity in this game so let's turn it off in main.js
:
|
|
Next, we can handle movement in the update()
method. Our character can move up, down, left, and right one at a time. That means he won't be able to move diagonally.
We'll enforce this using if/else
and setVelocity()
so that only 1 direction will be handled at any given time. Then we will consider the player idle if no arrow keys are being pressed.
Add this update()
method to the Game
Scene:
|
|
Notice that setVelocity()
always sets the direction not being handled to 0
so that the player cannot move up and left or up and right, etc.
We use a speed
value of 200
and make it negative or positive depending on the direction. Feel free to adjust this value for a faster or slower character.
Then we handle the idle case in the final else
block where we set velocity to 0, 0
and create an animation key from the current animation key based on the convention we used in the Preloader
Scene.
We need to do this because the player can be moving in any of the 4 directions before he stops and would need to become idle while facing that same direction.
Because all our animations keys adhere to a convention, we can just take the current animation key, split it by '-'
, and take the first element. This will give us the direction the player last faced.
Then we take that direction and create an idle animation key to have the player properly stop while facing the same direction he was moving in. 🤓
Your player should now respond to keyboard arrow keys and move around as expected.
Next Steps
That's it for part 1. We ended with a character that can walk around with different animations.
In the next part, we will add boxes for the player to interact with and use depth sorting to make sure everything layers properly.
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.