Making Your First Phaser 3 Game in Modern Javascript - Part 2

Write better code using modern JavaScript for Phaser 3

by on 5 minute read


Games can be some of the most complicated types of software you can create. And the most fun.

It helps to use modern best practices to avoid messy bugs or more easily fix ones that come up.

Doing so saves you time and headaches. Most importantly it will help you make a better game.

In this article, we will show you how to create games in Phaser 3 using modern JavaScript and best practices.

We'll be creating the same game from the official Making your first Phaser 3 game guide. This way you can compare and contrast the differences.

In Part 1 we created a new project and added a GameScene. Go check it out if you haven't already.

Creating Platforms

To add platforms and ground to our game we will use the ‘ground’ asset we preloaded in Part 1.

The code will be placed in a method instead of being added to the create() method. Organizing code into reusable functions and methods helps with writing better code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import Phaser from 'phaser'

export default class GameScene extends Phaser.Scene
{
	//...

	create()
	{
		this.add.image(400, 300, 'sky')
		// this.add.image(400, 300, 'star')
		
		this.createPlatforms()
	}

	createPlatforms()
	{
		const platforms = this.physics.add.staticGroup()

		platforms.create(400, 568, 'ground').setScale(2).refreshBody()
	
		platforms.create(600, 400, 'ground')
		platforms.create(50, 250, 'ground')
		platforms.create(750, 220, 'ground')
	}
}

The line to add the star has been commented out (line 10 above) to show that we no longer need it. You can delete it.

The platform creation code is the same as the official Phaser guide except we've organized it to be more readable. Check part 4 of the official guide if you want to understand how the code works.

You should see green platforms added to your game at http://localhost:8000. It should refresh automatically if you left the browser open from Part 1.

Don't Repeat Your Strings

You may have heard of the DRY Principle of software engineering. It is a good one to follow.

We are going to apply it to our string literals.

You can see that we used the string 'ground' 4 times in createPlatforms() and 1 time in preload().

As humans, we tend to make typos. The best way to avoid typos is to avoid typing. 😂

We can avoid typing by using a constant variable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import Phaser from 'phaser'

const GROUND_KEY = 'ground'

export default class GameScene extends Phaser.Scene
{
	//...

	preload()
	{
		this.load.image('sky', 'assets/sky.png')
		this.load.image(GROUND_KEY, 'assets/platform.png')
		this.load.image('star', 'assets/star.png')
		this.load.image('bomb', 'assets/bomb.png')

		this.load.spritesheet('dude', 
			'assets/dude.png',
			{ frameWidth: 32, frameHeight: 48 }
		)
	}

	//...

	createPlatforms()
	{
		const platforms = this.physics.add.staticGroup()

		platforms.create(400, 568, GROUND_KEY).setScale(2).refreshBody()
	
		platforms.create(600, 400, GROUND_KEY)
		platforms.create(50, 250, GROUND_KEY)
		platforms.create(750, 220, GROUND_KEY)
	}
}

The benefits you get using a constant variable is autocompletion by your code editor–no typing need!–and clear errors if you misspell the variable name. 👍

Create a Player

The player will be created using the dude.png sprite sheet that was loaded in preload(). The player creation code is placed in a createPlayer() method like we did for platforms.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import Phaser from 'phaser'

const GROUND_KEY = 'ground'
const DUDE_KEY = 'dude'

export default class GameScene extends Phaser.Scene
{
	constructor()
	{
		super('game-scene')

		this.player = undefined
	}

	preload()
	{
		this.load.image('sky', 'assets/sky.png')
		this.load.image(GROUND_KEY, 'assets/platform.png')
		this.load.image('star', 'assets/star.png')
		this.load.image('bomb', 'assets/bomb.png')

		this.load.spritesheet(DUDE_KEY, 
			'assets/dude.png',
			{ frameWidth: 32, frameHeight: 48 }
		)
	}

	create()
	{
		this.add.image(400, 300, 'sky')
		
		this.createPlatforms()
		this.createPlayer()
	}

	//...

	createPlayer()
	{
		this.player = this.physics.add.sprite(100, 450, DUDE_KEY)
		this.player.setBounce(0.2)
		this.player.setCollideWorldBounds(true)

		this.anims.create({
			key: 'left',
			frames: this.anims.generateFrameNumbers(DUDE_KEY, { start: 0, end: 3 }),
			frameRate: 10,
			repeat: -1
		})
		
		this.anims.create({
			key: 'turn',
			frames: [ { key: DUDE_KEY, frame: 4 } ],
			frameRate: 20
		})
		
		this.anims.create({
			key: 'right',
			frames: this.anims.generateFrameNumbers(DUDE_KEY, { start: 5, end: 8 }),
			frameRate: 10,
			repeat: -1
		})
	}
}

Notice that we applied DRY to the 'dude' string literal with the DUDE_KEY constant.

We added a player instance property and set it to undefined in the constructor. This is not strictly necessary. Declaring all instance properties before using them makes it easier to see all the properties are at a glance.

The player instance is later created in the createPlayer() method which is called from create().

The page at http://localhost:8000 should automatically refresh and show your player falling to the bottom of the screen.

Coming Up

We've now transformed parts 3 - 5 from the official Making your first Phaser 3 game guide into modern JavaScript.

In the next part, we will cover collisions between the player and the platforms and add keyboard controls to move the player.

Let us know in the comments below if anything doesn’t work or is unclear. 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.

Learn to make an Infinite Jumper in Phaser 3 with modern JavaScript!

Drop your email into the box below to get this free 60+ page book and join our newsletter.

Learn more about the book here.

Phaser 3 JavaScript HTML5 Guide Tutorial

Want tips and techniques more suited for you?


You may also like...


Video Guides


Beginner Guides


Articles Recommended For You

Fix Stretched Image Distortions in Phaser 3 with 9-Slice Scaling

by on

Are you having image distortion problems when scaling to make a button or panel graphic bigger? Multiple versions of the …

5 minute read

Command Pattern to Undo Player Actions

by on

Are you looking for a clean and reusable way to implement undo for player actions? Perhaps you are making a turn-based …

15 minute read

Advanced Logging with the Strategy Pattern

by on

Have you ever tried debugging a problem with your game that only seems to happen in production? The Developer Tools …

7 minute read

State Pattern for Character Movement in Phaser 3

by on

Writing clean and well-organized code is something all game developers aspire to. We want code to be reusable and easy …

7 minute read

Didn't find what you were looking for?


comments powered by Disqus