# How to create a platformer game with Phaser.js

> Build a complete platformer game with Phaser.js: set up the project, add platforms and a player, handle arrow-key movement and jumping, and collect stars.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2021-07-21 | Topics: [Phaser](https://flaviocopes.com/tags/phaser/) | Canonical: https://flaviocopes.com/phaserjs-platform-game-tutorial/

In this tutorial I'll use [Phaser.js](https://flaviocopes.com/tags/phaser/) to create a platformer game.

![Phaser.js platform game showing player character on ground with floating platforms and yellow stars, score displays 0](https://flaviocopes.com/images/phaserjs-platform-game-tutorial/Screenshot_2020-03-24_at_16.24.33.png)

The player can move around with the left/right arrow keys, and jump with the up arrow key. The goal is to pick up all the stars in the game:

![Platform game showing player character positioned on middle platform after collecting 2 stars, score shows 2](https://flaviocopes.com/images/phaserjs-platform-game-tutorial/Screenshot_2020-03-24_at_16.24.40.png)

When the player picks up all the stars, we're going to display "Game over" on top, and there's nothing else to do.

It's very very simple, but it's a start of a game that can be very fun to continue making, and it's a great way to demonstrate both Phaser and how [JavaScript](https://flaviocopes.com/javascript/) can work as a game creation programming language.

## Setup the project
Create an empty folder, and run

```sh
npm init -y
```

to initialize a minimal `package.json` file.

Then run

```sh
npm install phaser
```

Install Parcel if you haven't:

```
npm install -g parcel-bundler
```

Now create an `app.js` file, and run

```
parcel watch app.js
```

This will tell Parcel to build our game in the `dist/app.js` file.

Create an `index.html` file with this content:

```html
<!DOCTYPE html>
<html>
  <head>
    <script src="./dist/app.js"></script>
  </head>
</html>
```

Install `browser-sync` to run an HTTP server with the content of this folder:

```sh
npm install -g browser-sync
```

then run

```sh
browser-sync start --server --files "."
```

The above command watches all files in the current folder (and all subfolders) for changes, and launches a web server on port 3000, automatically opening a browser window to connect to the server.

Any time you change a file, the browser will refresh, so we can be more speedy in our development process.

Great! We can start.

## Initialize Phaser
Open `app.js` and write:

```js
import Phaser from 'phaser'
```

Let's add a minimal configuration:

```js
const config = {
  width: 800,
  height: 600,
  backgroundColor: 0xffffff,
  scene: {
    preload,
    create,
    update
  },
  physics: {
    default: 'arcade',
    arcade: {
      gravity: { y: 300 },
      debug: false
    }
  }
}

const game = new Phaser.Game(config)
```

Now create the 3 functions `preload()`, `create()` and `update()`:

```js
function preload() {

}

function create() {

}

function update() {

}
```

## Add the artwork
I call it "artwork", but I made it and it's the ugliest artwork you'll ever find.

But it works for our simple game. Download those files and save them as:

> `ground.png`
![Black pixelated ground platform sprite with textured surface for game development](https://flaviocopes.com/images/phaserjs-platform-game-tutorial/ground.png)

> `island.png`
![Small black floating platform island sprite for platformer game](https://flaviocopes.com/images/phaserjs-platform-game-tutorial/island.png)

> `player.png`

![Player character sprite sheet showing 9 animation frames of simple stick figure in different poses](https://flaviocopes.com/images/phaserjs-platform-game-tutorial/player.png)

> `star.png`

![Yellow star collectible sprite for platform game](https://flaviocopes.com/images/phaserjs-platform-game-tutorial/star.png)

Create an `assets` folder, and put them in there.

## Create a canvas
Now get back to `app.js`.

The first thing we'll do is to load the assets in `preload()`:

```js
function preload() {
  this.load.image('ground', 'assets/ground.png')
  this.load.image('island', 'assets/island.png')
  this.load.image('star', 'assets/star.png')
  this.load.spritesheet('player', 'assets/player.png', {
    frameWidth: 32,
    frameHeight: 48
  })
}
```

We assign a label to each asset. The first 3 are loaded using `this.load.image()`, the last one using `this.load.spritesheet()` because the image contains several little images, that we'll use to animate the player.

Therefore we must also set the dimensions of each image in the sprite sheet (32x48 pixels).

## Create the platforms
Let's create the platforms now.

We're going to create a new physics static group to hold them, because they are not moving objects: they are still.

```js
let platforms = this.physics.add.staticGroup()
```

Then we add the ground:

```js
platforms.create(400, 588, "ground")
```

And 5 islands:

```js
platforms.create(600, 450, "island")
platforms.create(50, 250, "island")
platforms.create(650, 220, "island")
platforms.create(250, 520, "island")
platforms.create(250, 320, "island")
```

The numbers here indicate the X and Y coordinates in the 2D space, relative to the top left corner, and refer to the middle of each image.

This is what you should see at this point:

![Game canvas showing just the platform layout with ground and 5 floating islands arranged at different heights](https://flaviocopes.com/images/phaserjs-platform-game-tutorial/Screenshot_2020-03-24_at_17.13.58.png)

## Add the player

Now let's add the player.

Create a variable on top of the file, outside any function, called `player`:

```js
let player
```

Then in `create()` I'm going to add it near the middle bottom of the screen:

```js
player = this.physics.add.sprite(380, 500, "player")
```

We set it to have a small bounce:

```js
player.setBounce(0.2)
```

so it will quickly stand still after being put in the screen, and we set it to not go outside of the screen:

```js
player.setCollideWorldBounds(true)
```

In this way it will appear and after a couple bounces it will sit at the bottom of the screen:

![Game showing player character positioned at bottom of screen on the ground platform](https://flaviocopes.com/images/phaserjs-platform-game-tutorial/Screenshot_2020-03-24_at_17.19.17.png)

However, we want the player to stay in top of the ground.

We can do this by adding a collider physics rule between the player and the platforms:

```js
this.physics.add.collider(player, platforms)
```

In this way, the player will not just stay on top of the ground, but also of the other 5 platforms (islands) we have floating on the screen:

![Player character now properly standing on the ground platform after collision physics were added](https://flaviocopes.com/images/phaserjs-platform-game-tutorial/Screenshot_2020-03-24_at_17.28.58.png)

## Make the player move

Now let's make it possible for the player to move.

Let's add a variable on top of the file, near the `player` declaration:

```js
let cursors
```

Then in `create()` add:

```js
cursors = this.input.keyboard.createCursorKeys()
```

to allow access to the keyboard events.

Now in the `update()` function, which is now empty, we're going to inspect this variable:

```js
function update() {
  if (cursors.left.isDown) {
    player.setVelocityX(-160)
  } else if (cursors.right.isDown) {
    player.setVelocityX(160)
  } else {
    player.setVelocityX(0)
  }
}
```

`update()` is continuously called by the game loop, so whenever one key is down we change the player velocity (speed) on the X axis. If no key is pressed, we set it to stand still.

## Animate the player
Let's now make the player image change when it's moving.

We create 3 animations in `create()`: one when the player is still, one when it's moving to the left, one when it's moving to the right:

```js
this.anims.create({
  key: 'still',
  frames: [{ key: 'player', frame: 4 }],
  frameRate: 20
})

this.anims.create({
  key: 'left',
  frames: this.anims.generateFrameNumbers('player', { start: 0, end: 3 }),
  frameRate: 10,
  repeat: -1
})

this.anims.create({
  key: 'right',
  frames: this.anims.generateFrameNumbers('player', { start: 5, end: 8 }),
  frameRate: 10,
  repeat: -1
})
```

`still` is not really an animation, because it only has one frame. But `left` and `right` are composed by 4 frames each, and they are infinitely repeated to simulate walking.

Now we need to activate those animations in `update()`:

```js
function update() { 
  if (cursors.left.isDown) {
    player.setVelocityX(-160)
    player.anims.play('left', true)
  } else if (cursors.right.isDown) {
    player.setVelocityX(160)
    player.anims.play('right', true)
  } else {
    player.setVelocityX(0)
    player.anims.play('still')
  }
}
```

The `true` parameter for `left` and `right` sets the animation to loop.

## Jump

To allow the player to jump, add this code into `update()`:

```js
if (cursors.up.isDown && player.body.touching.down) {
  player.setVelocityY(-330)
}
```

Whenever the player sits on the bottom (`player.body.touching.down`) and the up arrow is pressed, we push it to the top. Gravity will simulate a jump like the ones we do in the real world.


## Add the stars
Let's now add the stars to the screen.

We add 8 stars by creating a physics group, and we make them collide with the platforms, so they'll sit on top of them:

```js
let stars = this.physics.add.group()
stars.create(22, 0, "star")
stars.create(122, 0, "star")
stars.create(222, 0, "star")
stars.create(322, 0, "star")
stars.create(422, 0, "star")
stars.create(522, 0, "star")
stars.create(622, 0, "star")
stars.create(722, 0, "star")

this.physics.add.collider(stars, platforms)
```

![Game now shows yellow stars placed on each platform for the player to collect](https://flaviocopes.com/images/phaserjs-platform-game-tutorial/Screenshot_2020-03-24_at_17.44.02.png)

## Allow the player to pick up the stars
To make the player pick up the stars, we're going to add an overlap physics effect in `create()` that is fired when the player meets a star:

```js
this.physics.add.overlap(player, stars, (player, star) => {}, null, this)
```

When this happens, we hide the star:

```js
this.physics.add.overlap(
  player,
  stars,
  (player, star) => {
    star.disableBody(true, true)
  },
  null,
  this
)
```

Let's make a stars counter. When one star is picked up, we increment it:

```js
let score = 0

this.physics.add.overlap(
  player,
  stars,
  (player, star) => {
    star.disableBody(true, true)
    score += 1
  },
  null,
  this
)
```

and we can display it on top of the screen:

```js
let score = 0
let scoreText = this.add.text(16, 16, "Stars: 0", {
  fontSize: "32px",
  fill: "#000",
})

this.physics.add.overlap(
  player,
  stars,
  (player, star) => {
    star.disableBody(true, true)
    score += 1
    scoreText.setText("Stars: " + score)
  },
  null,
  this
)
```

That's it! Our little game works!

![Final game showing score counter displaying Stars: 3 with player character on platform after collecting stars](https://flaviocopes.com/images/phaserjs-platform-game-tutorial/Screenshot_2020-03-24_at_17.50.26.png)
