Learn to Code via Tutorials on Repl.it!

← Back to all posts
Phaser 3 Tutorial + Template
h
TereDeJugo (6)

Phaser3 Game Tutorial + Template!

Introduction

Phaser3 is a javascript game engine made to make 100% web games, here you can find a template for your phaser project, accompanied by a tutorial for beginners, it should be noted that it is best that you already have knowledge of Javascript.
I hope it helps you!

Read the docs!

Step by step

The first thing is to have our html project empty, we will have the following hierarchy of folders and files

/index.html - we'll call the phaser 3 library and our initial script
/assets/ - we'll put our assets, such as audio, images and others
/objects/ - here we will put our objects as our player
/scenes/ - we'll put our scenes, to have greater order
/script.js - it will be our main file where we will call the scenes
/style.css - our styles css, in case we want the page to be centered, and others

(you can use any file hierarchy you want, like with a src folder, or others, but this is the one we'll use in the template!)

Now, in our html, we will write a basic html structure, with head and body, and we will call the library and our initial script.

index.html

<!DOCTYPE html>
<html>
    <head>
	    <meta charset="utf-8">
	    <title>Phaser Template</title>
	    <link href="style.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
	    <script src="//cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script> <!--Import phaser3 lib-->
            <script src="script.js" type="module"></script> <!--Import initial js file-->
    </body>
</html>

Ready, we have already called our library and our main script, now let's start configuring the first steps of our game.

We will go to our main script and create a constant with the game configuration.

script.js

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    scene: []
};

The type of our game will be the way it will be rendered, it can be with Canvas, Headless or Webgl, but we can put auto so that Phaser decides which is the best for us.

The width and height will be the size of the game screen (in pixels).

In the scene we will leave an empty array for now, while we create our first scene.

Time to create a new scene, we create in the scenes folder a file called game.js and extend the Phaser scene class.

Our first action will be, in the constructor, to put a super which assigns the key with which Phaser will recognize this scene.

game.js

class Game extends Phaser.Scene {
    constructor() {
        super({key:"game"});
    };
};

Once we assign the key of the scene, it is time to start building the things that will make up our scene, the preload, the create and the update

  • preload() - we will load the assets before we can use them.
  • create() - it is executed when the scene is created, here we will start some variables and objects, like our player.
  • update() - this function is executed every frame that passes in the game

We will create these 3 empty functions, and we will start loading them little by little, starting with the preload, where we will load our sprite for the player

game.js

class Game extends Phaser.Scene {
    constructor() {
        super({key:"game"});
    };

    preload() {

    }

    create() {

    }

    update() {

    }
};

To load our sprite in the scene, we use the method of our scene, load.image, note that this will not put the image in the scene, it will only load it!

load.image receives two parameters, the name with which phaser will identify this image, and the path of the image file, I will use the following image, and put it in /assets/ with the name mark.png.

game.js

preload() {
    this.load.image('mark', 'assets/mark.png');
};

Ready, we can use our Mark! you want to see? we use the method of the scene add.image

add.image receives three parameters, the position in x, the position in y, and the name of the image that we have assigned, we will use the function in thecreate method so that it is only executed when the scene is created

game.js

create() {
    this.add.image(40, 40, 'mark');
};

Well, it looks great! But it doesn't do anything, so let's delete that line and create a new object in /objects/, in my case, I'll call it mark.js, you can call it whatever you want , obviously always with the .js

We will extend the class of Phaser.GameObjects.Sprite and we will add to the constructor 4 parameters, the scene where the object will be instantiated, the initial x and y position and the name of the image that will be used as a sprite.

mark.js

class Mark extends Phaser.GameObjects.Sprite {
    constructor(scene, x, y, sprite) {
        super(scene, x, y, sprite);
    };
};

Now, we will create a new method to move, with 4 parameters for each movement key, what the method will do is to add the position of our character if one of the keys is being pressed or not, then we will see with defining the keys, but I need you to know that the isDown property of a key istrue when it is pressed, so we will be verifying if that key is pressed, and if it does, we will gradually change the position of our character.

mark.js

class Mark extends Phaser.GameObjects.Sprite {
    constructor(scene, x, y, sprite) {
        super(scene, x, y, sprite);
    };

    move(up, left, down, right) {
        if(up.isDown) this.y--
        if(left.isDown) this.x--
        if(down.isDown) this.y++
        if(right.isDown) this.x++
    };
};

Ready, now that we have created our class and our method, we will add something else in the constructor, the function of the scene parameter add.existing, which in turn receives our player class as a parameter, so we place it.

mark.js

class Mark extends Phaser.GameObjects.Sprite {
    constructor(scene, x, y, sprite) {
        super(scene, x, y, sprite);

        scene.add.existing(this);
    };
};

We will have ready, our Mark class, we would only have to export!

mark.js

class Mark extends Phaser.GameObjects.Sprite {
    constructor(scene, x, y, sprite) {
        super(scene, x, y, sprite);

        scene.add.existing(this);
    };

    move(up, left, down, right) {
        if(up.isDown) this.y--
        if(left.isDown) this.x--
        if(down.isDown) this.y++
        if(right.isDown) this.x++
    };
};

export default Mark;

Now, we go back to our scene file game.js, and import our Mark class.

game.js

import Mark from '/objects/mark.js'
class Game extends Phaser.Scene {
    //(...)
};

Now we must create the keys, we use the method of our scene input.keyboard.addKeys, which will receive as a parameter an object with the codes of the keys that we want to map

game.js

create() {
    this.keys = this.input.keyboard.addKeys({
        UP: Phaser.Input.Keyboard.KeyCodes.UP,
        LEFT: Phaser.Input.Keyboard.KeyCodes.LEFT,
        DOWN: Phaser.Input.Keyboard.KeyCodes.DOWN,
        RIGHT: Phaser.Input.Keyboard.KeyCodes.RIGHT
    });
};

We already have our keys, now we can instantiate our Mark and see how it appears in the scene, we will pass t as a parameter of the instance, the corresponding keys (To see the other keycodes, click here)

game.js

create() {
    this.mark = new Mark(this, 50, 50, 'mark');
};

update() {
    this.mark.move(this.keys.UP, this.keys.LEFT, this.keys.DOWN, this.keys.RIGHT);
};

Nothing happens, of course, we have to export the scene and put it in our configuration, of our main script

script.js

import Game from '/scenes/game.js';

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    scene: [Game]
};

const game = new Phaser.Game(config);

Now our character moves, great !, but we have 2 problems, the first is that, at least, I would like Mark to be in the center, and also, to be faster, we will see how to solve the first problem

We create a variable and put the following value to it, it will receive the dimensions that we have chosen in the game configuration, at the beginning of the guide

game.js

this.screenSize = this.sys.scale.gameSize;

Now the width and height properties will give us the size of the game, so we will divide them and put it in the Mark instance

game.js

create() {
    this.mark = new Mark(this, this.screenSize.width / 2, this.screenSize.height / 2, 'mark');
};

Done, our Mark is centered, now let's look at the speed issue, let's go back to our Mark's script and add a variable with reference to speed

mark.js

constructor(scene, x, y, sprite) {
        super(scene, x, y, sprite);

        this.speed = 20;

        scene.add.existing(this);
};

Now we change the function to move, and instead of it being added by 1, we will make it add / subtract and assign with the velocity, using the += and -= operators

mark.js

move(up, left, down, right) {
        if(up.isDown) this.y -= this.speed;
        if(down.isDown) this.y += this.speed;
        if(left.isDown) this.x -= this.speed;
        if(right.isDown) this.x += this.speed;  
};

You can adjust the speed to your liking, now we can continue to the following, create texts!

We will go to the create method of our project and use the function of our scene add.text, which will receive 3 parameters, x-axis, y-axis and a string with the text

game.js

create() {
    this.text.setOrigin(0.5, 0.5); // The x and y position of the text is centered
    this.text.setColor("#FFFFFF");
    this.text.setFontSize(30);
}

Ready, we also place the function setOrigin(0.5, 0.5), basically what it will do is position the x and y axis in the middle of the text, so that it is centered, and setColor(), which receives a color as a parameter, and it will come us jewel for that the color is white, since by defense, it comes black

Also add the space key to my keys variable and create the next function:

game.js`

update() {
    if (this.keys.SPACE.isDown) {
        this.add.image(Math.random() * this.screenSize.width, Math.random() * this.screenSize.height, 'mark')
    };
};

Basically what it does is add an image of Mark when the space key is pressed, we do not use anything not seen before.

Another problem that arises is the issue of the z axis, and the positioning of the objects, when the Marks are created, our Mark stays down, but we can use the setDepth () function and set the parameter "z axis"

create() {
    mark.setDepth(1000);
};

Ready, you would have your first project in Phaser ready, I hope it has served you!

Comments
hotnewtop
TereDeJugo (6)

This is my first tutorial!

English is not my native language, any questions or errors, let me know here, thank you!