avatar
Filip Jerga
May 2, 2021

Create a “secret” Dino Chrome Game in 1 hour with JS and Phaser 3

Learn how to create games with JS and Phaser 3 in a short time.

TODO: provide alt

Resources:

  1. Full Course: https://academy.eincode.com/courses/phaser-3-the-complete-guide-build-publish-games-in-js
  2. Video Guide: https://youtu.be/VOtZ6yNqH84
  3. Github repo: https://github.com/Jerga99/dino-chrome-clone

After you finish reading I highly recommend watching my youtube guide. This blog post serves as a starting point.

Prepare the project

Download a zip file from:

https://github.com/Jerga99/dino-chrome-clone/archive/2e62c20a06b126b1a6128c56a60d5603b49daccd.zip

After the folder is unzipped, install all dependencies:

npm install

and start the development server:

npm run dev

this will start dev server on localhost:8080

Open your browser on localhost:8080, and you should see a blank screen.

Create Game Objects

Now let’s create our first game objects, including our main character “Dino” and the ground upon which Dino can “run”.

In PlaceScene.js, you can create these game objects in a create function:

create() {
  const { height, width } = this.game.config;
  this.gameSpeed = 10;
  this.ground = this.add.tileSprite(0, height, width, 26,    'ground').setOrigin(0, 1)
  this.dino = this.physics.add.sprite(0, height, 'dino-  idle').setOrigin(0, 1);
}
PlayScene.js

Height is 340px and width is 1000px as defined in index.js

The position of game objects is crucial. Let’s see an image of how game objects are added to the canvas.

Let’s start with Dino

When creating a Sprite game object, you need to provide x and y coordinate

The first coordinate is

x -> 0, the second one

y -> 340, and also the

key -> dino-idle (identifier of the image loaded in PreloadScene)

setOrigin defines which point of the game object is inserted into provided coordinates

you can see the origin point of 0,1 in the left-bottom corner. This corner is inserted into coordinates 0,340 as stated before.

Add the Ground

The ground we will insert as a TileSprite. A TileSprite is a Sprite that has a repeating texture.

When creating a tileSprite we need to provide five values, they include:

x -> 0

y -> 340

width -> 1000px

height -> 26px

key -> ground (identifier of the image loaded in PreloadScene)

Since tileSprite is a repeating structure, we need to provide also width and height. Width is the size of the canvas, and height is the actual height of the ground image. You can find all the images in the assets folder.

The Moving Ground Effect

If we want to create a moving effect, we need to change the tile position of the ground on every update of the game.

In this function:

update() {}

The update function is called by the Phaser framework 60 times per second. This means your game is running at 60FPS (frames per second). If you need to define dynamic behavior, then update is the right spot.

Add this to move the ground:

create() {
  this.gameSpeed = 10;
  // rest of the code
}
update() {
  this.ground.tilePositionX += this.gameSpeed;
}
index.js

Where gameSpeed is 10, the ground will move 10px on every update.

Which, in reality, looks like this:

Let Dino Jump

First, we need to handle user input.

create() {
  // rest of the code
  this.dino = this.physics.add.sprite(0, height, 'dino-idle')
   .setCollideWorldBounds(true)
   .setGravityY(5000)
   .setOrigin(0, 1);
  this.createControll();
}
createControll() {
  this.input.keyboard.on('keydown_SPACE', () => {
    if (!this.dino.body.onFloor()) { return; }
  this.dino.setTexture('dino', 0);
  this.dino.setVelocityY(-1600);
  })
}

setGravityY will apply a gravity force on Dino. This means Dino will be pulled towards the ground at the rate of 5000px, which will increase every second.

setColliderWorldBounds sets whether this Body collides with the world boundary. Without it, the game object would fall outside of the canvas.

Now to control. Whenever a user presses the space key, Dino will go in an upwards direction at the speed of 1600px per second (setVelocityY). This will overcome the gravity for the split of the second and create a jumping effect.

setTexture will change the image of the dino as the dino will jump.

Now, notice the “if” statement. To prevent jumping in mid-air, we are checking if the dino is on the floor. This will return the true value if dino is colliding with world bounds.

Here’s what it looks like:

Create Animations

First, we need the base image, which we will split into multiple frames:

assets/dino-run.png

The image we are using is defined in the assets folder. We are loading this image in PreloadScene.js with this.load.spritesheet.

create() {
  //rest of the code
  this.initAnims();
}
initAnims() {
  this.anims.create({
    key: 'dino-run',
    frames: this.anims.generateFrameNumbers('dino', 
      {start: 2, end: 3}),
    frameRate: 10,
    repeat: -1
  })
 }

First, we need to initialize the animation. Let’s explain the parameters:

  • The key: This is the identifier of the image animation
  • Frames: These are the frames that the animation will consist of. In this case, frames 2,3 (from the image above)from the image assets/dino-run.png
  • The frameRate: 10, frames(2,3) will be played at the rate of 10 frames per second
  • repeat:-1, it will loop the animation infinitely

We will play the following animation in the update function:

update() {
 // rest of the code
if (this.dino.body.deltaAbsY() > 0) {
    this.dino.anims.stop();
    this.dino.setTexture('dino', 0);
  } else {
    this.dino.play('dino-run', true);
  }
}

We will check what movement Dino is currently in. Remember, we have two states; one in which dino is standing still and the second one in which dino is jumping.

In the update function, we can check if the position of dino on the y-axis is larger than 0. If that’s the case, this means Dino is jumping, so we will set the default texture.

If that’s not the case, we want to play running animation:

Conclusion

Creating a full game takes a little more effort, which is hard to put into a single blog post. To finish this game, watch my code along with the video on youtube here: https://youtu.be/VOtZ6yNqH84 or check a full course on creating the games: https://academy.eincode.com/courses/phaser-3-the-complete-guide-build-publish-games-in-js

Best of luck, Filip.