Gamedev Phaser Content Kit

Article 07: Player paddle and controls

We have the ball moving and bouncing off the walls, but it gets boring after some time. There's no interactivity, we can't do anything with the ball. It feels more like a movie than a game. We need a way to introduce the gameplay, so let's create the paddle that we will be able to move and use to hit and bounce the ball. From the framework point of view the paddle is very similar to the ball - we need a variable, load the image, and then do the magic.

First, add the paddle variable we will be using in our game, right after the ball variable:

var ball;
var paddle;

Then, in the preload function, load the paddle image:

function preload() {
    // ...
    game.load.image('ball', 'img/ball.png');
    game.load.image('paddle', 'img/paddle.png');
}

After that, we can init our paddle in the create function:

paddle = game.add.sprite(game.world.width*0.5, game.world.height-5, 'paddle');

We can use the world.width and world.height values to position the paddle exactly where we want it: game.world.width*0.5 will be right in the middle of the screen. In our case the world is the same as the Canvas, but for other types of games, like side-scrollers for example, you can tinker with it and create interesting effects.

As you probably noticed the paddle is not exactly in the middle. Why? Because the anchor from which the position is calculated always starts from the top left edge of the object. We can change that to have the anchor in the middle of the paddle's width and at the bottom of it's height, so it's easier to position against the bottom edge:

paddle.anchor.set(0.5,1);

The paddle is positioned right where we wanted it to be. Now, to make it collide with the ball we have to enable physics. Continue adding the code in the create function:

game.physics.enable(paddle, Phaser.Physics.ARCADE);

And then the magic happens - the framework will take care of checking the collision detection on every frame. To do that, just add the collide method to the update function:

function update() {
    game.physics.arcade.collide(ball, paddle);
}

The first parameter is one of the objects, in our case the ball, and the second is the paddle. It works, but not quite as we expected it to work - when the ball hits the paddle, the paddle fall off the screen! All we want is the ball bouncing off the paddle and the paddle staying in the same place. We can set the body of the paddle to be immovable, so the ball won't move it when it hits it. Add that line at the bottom of the create function:

paddle.body.immovable = true;

Now it works! The next problem is - we can't move it. To do that we can use the input (whether mouse or touch) and set the paddle position to where the input position is. Add the next line to the update function:

function update() {
    game.physics.arcade.collide(ball, paddle);
    paddle.x = game.input.x;
}

Now on every new frame the paddle's x position will adjust accordingly to the input's x position. But when we start the game, the position of the paddle is not in the middle. It's because the input position is not yet defined. To fix that we can set the default position in the middle of the screen if it's not available:

paddle.x = game.input.x || game.world.width*0.5;

It works as expected.

Compare your code

You can check the finished code for this lesson for yourself in the live demo below, and play with it to understand better how it works:

Next steps

We can move the paddle and bounce off the ball, but what's the point if the ball is bouncing off the bottom edge of the screen anyway? Let's introduce the possibility of losing - a game over logic.