In last week’s post, we explored how to use gravity in Phaser 3. Now we will defy that gravity and make the ball jump. We can do this by setting the velocity of the ball to counteract the gravity.
So far in the code, we’ve set up a ball that falls until it collides against a platform. Here is the code up to this point:
class SceneMain extends Phaser.Scene {
constructor() {
super('SceneMain');
}
preload() {
//load our images or sounds
this.load.image("ball", "images/ball.png");
this.load.image("block", "images/block.png");
}
create() {
//define our objects
let ball = this.physics.add.sprite(this.sys.game.config.width / 2, 0, "ball");
//set the gravity
ball.setGravityY(100);
//place the ground
let groundX = this.sys.game.config.width / 2;
let groundY = this.sys.game.config.height * .95;
let ground = this.physics.add.sprite(groundX, groundY, "block");
//size the ground
ground.displayWidth = this.sys.game.config.width * 1.1;
//make the ground stay in place
ground.setImmovable();
//add the colliders
this.physics.add.collider(ball, ground);
}
update() {
//constant running loop
}
}
Add input to the game
In this example, we will make the ball jump whenever the game is clicked. Let’s add some input detection at the end of the create function
this.input.on('pointerdown', this.jump, this);
Scope of the ball
We need to write the jump function, but we’ve got a problem. When making the gravity example, we only needed a local variable. Now we need to access it in the new jump function. We need to change the let ball to this.ball, or for a shortcut just make a new reference.
//define our objects
let ball = this.physics.add.sprite(this.sys.game.config.width / 2, 0, "ball");
//make a class reference
this.ball=ball;
The jump function
To make the ball jump, we just need to counteract the gravity by setting the y velocity of the ball to a negative number.
function jump()
{
this.ball.setVelocityY(-100);
}
Now when you click the game, the ball should jump and the gravity pull it back down. If you keep clicking the ball will keep moving up as it is pulled down by the gravity. This is how the flappy bird game was made.
The long click
The works well for a quick jump, but what if we want to have the ball jump higher based on how long we hold our finger or the mouse down? To make a power jump like this, we need to either measure the time between pointer down and pointer up. Alternatively, we can start and stop a timer that adds value to a power variable. We can create the timer on the pointer down event and remove the timer when released. Let’s change the name of the jump function to startJump just to keep things clear, and add an onpointerup event listener.
Make event listeners in the create function:
this.input.on('pointerdown', this.startJump, this);
this.input.on('pointerup', this.endJump, this);
add the timer
Now change the jump function to the startJump function and create a timer with a delay of 100 milliseconds that loops. We will make a function called tick to use as the timer’s callback later.
startJump() {
this.timer = this.time.addEvent({
delay: 100,
callback: this.tick,
callbackScope: this,
loop: true
});
// this.ball.setVelocityY(-100);
}
stop the timer
In the endJump function that is called when the pointer is release we stop the timer
endJump() {
this.timer.remove();
}
Keeping track of the power
Now all we need to do is make a power variable and increment it while the pointer is down
First create a power variable at the top of the create function
this.power=0;
And then make the tick function.
tick()
{
this.power+=.1;
}
If you run the game now, you’ll see that you can make the ball jump by holding and releasing the mouse. You’ll also note that you can make the ball go quite far off the screen!
Limit the jump
It is a good idea to limit how far a sprite can jump in your game. In this case we can limit the power variable to a value of 5.
tick() {
if (this.power < 5) {
this.power += .1;
console.log(this.power);
}
}
Here is how the entire code should look now
class SceneMain extends Phaser.Scene {
constructor() {
super('SceneMain');
}
preload() {
//load our images or sounds
this.load.image("ball", "images/ball.png");
this.load.image("block", "images/block.png");
}
create() {
this.power = 0;
//define our objects
//
//
//ball
this.ball = this.physics.add.sprite(this.sys.game.config.width / 2, 0, "ball");
this.ball.setGravityY(100);
//
//
//
//ground
//
//
let ground = this.physics.add.sprite(this.sys.game.config.width / 2, this.sys.game.config.height * .95, "block");
ground.displayWidth = this.sys.game.config.width * 1.1;
ground.setImmovable();
//
//
//
//set collider
//
//
this.physics.add.collider(this.ball, ground);
this.input.on('pointerdown', this.startJump, this);
this.input.on('pointerup', this.endJump, this);
}
/*
start the jump when the pointer goes down
*/
startJump() {
this.timer = this.time.addEvent({
delay: 100,
callback: this.tick,
callbackScope: this,
loop: true
});
// this.ball.setVelocityY(-100);
}
/*
end the jump when the pointer is up
*/
endJump() {
this.timer.remove();
this.ball.setVelocityY(-this.power * 100);
this.power = 0;
}
tick() {
if (this.power < 5) {
this.power += .1;
console.log(this.power);
}
}
update() {
//constant running loop
}
}
While there are a lot of things you can add to it, this should get you started if you want to add jumps to your game.
That wraps ups the basics of jumping in Phaser 3. You can download the source code below.