Now we have a space ship on the screen, it’s time to start giving the player something to do! You can’t have a game without taking some user input into consideration - so lets get to making it so that the player can move their space ship left and right on the screen.

Phaser comes with a complete Physics system which we can use to simulate realistic movement. Later on we will use it to help us figure out when things collide but for now, we will simply enable it and use it to allow us to move our player ship around. The nice thing about using the physics system for this is that the player ship will always move at the same speed, even if the user’s computer slows down and fails to call ‘update’ 60 times per second.

Task Definition

The main steps for completing this task are as follows;

  1. Enable the Phaser Physics system using game.physics.startSystem(Phaser.Physics.ARCADE).
  2. Allow the physics system to control the player ship by using game.physics.arcade.enable(this.playerShip);.
  3. Create a ‘cursors’ object in Phaser which tracks which cursor keys are pressed using this.cursors = game.input.keyboard.createCursorKeys();.
  4. Track when the user is pressing an arrow key using this.cursors.right.isDown.
  5. Set the velocity for the player ship in the update function depending on which keys are pressed using this.playerShip.body.velocity.x = ??.

Walkthrough

For this task we will look at Phaser’s input system. We want to know when the user has pressed a certain key on their keyboard so that we can move the player’s ship around the screen in response. Let’s break this task down into smaller steps.

1. Enable Phaser Physics

First of all, we should enable the Phaser physics system. You won’t see anything immediately after doing this, but we want to be able to set the ‘velocity’ on the player ship when the user is pressing a key on the keyboard - so we need to turn this on. We only need to do this once when we create the our state.

The following code can be used to enable the physics system.

game.physics.startSystem(Phaser.Physics.ARCADE);

2. Allows Physics to Control the Player Ship

You have to tell Phaser that it’s okay for the physics system to take control of each sprite after creating it. Use the following line of code after you have created the PlayerShip in order to allow Phaser to control the player ship.

game.physics.arcade.enable(this.playerShip);

3. Track Player Input

Next up we want to start keeping track of which arrow keys the user has pressed down. Phaser provides a ‘CursorKeys’ object to do this for you. You can create a cursor keys object in your game state by doing the following;

this.cursors = game.input.keyboard.createCursorKeys();

Later on in your code, you can then use this object to see if the user is pressing one of the arrow keys. The following code will print out text to the console whenever the player is holding down the right arrow key.

if (this.cursors.right.isDown) {
    console.log("RIGHT PRESSED");
}

Try it out! Once you’ve implemented the following code - check that you can see the messages in the Developer Console while you’re holding down the right arrow key. You should see a lot of messages if you hold it down, even just for a second!

4. Move the Player Ship

Now that you’re able to keep track of when the user is pressing down a cursor key, you just need one more piece of the puzzle to make the player ship move.

Just like sprites have an x,y position - they also have an ‘x,y’ velocity in the physics system. If a sprite has a positive X velocity, then it will move to the right. A positive Y position and it will move down the screen. You can set the velocity of the player ship at any point using the following function;

this.playerShip.body.velocity.x = 200;

Warning: If the user isn’t pressing any keys on the keyboard, you should reset the velocity to zero!

In pseudo-code, your solution might look something like the following;

if ( pressing-right ) {
    set-right-velocity
} else if ( pressing-left ) {
    set-left-velocity
} else {
    set-zero-velocity
}

Bonus. Confine the Ship to the Screen!

If you’ve completed this task early, then it would be a good idea to confine the player ship to the screen. In your update loop it would be a good idea to check if the player’s X coordinate is too high or too low. If it is you should now allow the player ship to move in that direction any longer.

In psuedo-code, your solution might look something like this;

if ( pressing-right ) {
    set-right-velocity
} else if ( pressing-left ) {
    set-left-velocity
} else {
    set-zero-velocity
}

if ( at-right-edge-of-screen && moving-right ) {
    set-zero-velocity
}

if ( at-left-edge-of-screen && moving-left ) {
    set-zero-velocity
}

Experiments / Extensions

If you want to take your solution further, you should consider doing the following;

  • It’s best to break your game down into as many functions as possible. At this point, it could be a good idea to add an updatePlayer() function to your mainGameState. Put your update code from this task in there and call it from the main update function.
  • It’s also a good idea to use constants instead of ‘magic numbers’ in your code. Define the playerShipSpeed as a constant (const) at the top of the file and use that to set the player’s velocity when moving.
  • You might also want to experiment with the player ship’s speed so that it feels fast enough to be fair but not too fast!
  • It could also be cool to allow the player ship to move up and down around the bottom half of the screen also.

Standard Solution

This solution contains all of the code for the entire project up to this point.

var mainGameState = { } 

mainGameState.preload = function() {
    console.log("Pre-loading the game!");
    game.load.image("space-bg", "assets/images/space-bg.jpg");
    game.load.image("player-ship", "assets/images/player-ship.png");
}

mainGameState.create = function() {
    game.physics.startSystem(Phaser.Physics.ARCADE);

    game.add.sprite(0, 0, "space-bg");

    var shipX = game.width * 0.5;
    var shipY = game.height * 0.8;

    this.cursors = game.input.keyboard.createCursorKeys();        

    this.playerShip = game.add.sprite(shipX, shipY, 'player-ship');
    this.playerShip.anchor.setTo(0.5, 0.5);
    game.physics.arcade.enable(this.playerShip);
}

mainGameState.update = function() {
    if ( this.cursors.left.isDown ) {
        this.playerShip.body.velocity.x = -200;
    } else if ( this.cursors.right.isDown ) {
        this.playerShip.body.velocity.x = 200;
    } else {
        this.playerShip.body.velocity.x = 0;
    }
}

Bonus Task Solution

In order to satisfy the bonus task, you should add the following code to your update loop;

    if ((this.playerShip.x > game.width) && (this.playerShip.body.velocity.x > 0)) {
        this.playerShip.body.velocity.x = 0;
    }

    if ((this.playerShip.x < 0) && (this.playerShip.body.velocity.x < 0)) {
        this.playerShip.body.velocity.x = 0;
    }