When building a game with Phaser you will likely have various objects on the screen. You might have the players character, a floor or some walls, some enemies, items, and so on.
These entities are going to need to interact with one another in some way to make the game playable. If a player touches a powerup then the powerup should be destroyed and the player should gain its effects, if the player hits an enemies bullet they should probably be hurt or killed, if a player jumps onto a platform they should land on the platform (not fall through it).
Phaser has a built-in physics system that makes it quite easy to handle these sorts of scenarios. Take a look at this example from a game I am currently developing:
The player must navigate through the level to reach the flag, but there are multiple potential collisions that need to be handled along the way. First of all, the player needs to collide with the ground that they are standing on (but nothing has to happen as a result of that collision, we will just have Phaser’s physics applied). If the player falls into the water they should be killed, and likewise, if they collide with a spike they should also be killed. If they manage to reach the end, they should collide with the flag and as a result of this, it should trigger the end of the level.
In this tutorial, I will provide some examples of handling various types of collisions in a Phaser game.
Before We Get Started
This post assumes that you are already at least somewhat familiar with Phaser. If you have never set up a Phaser game before, I would recommend reading Level up Your Phaser Games with ES6 first. This will set you up with a nice structure to start building HTML5 mobile games with Phaser.
For more Phaser tutorials, you can also check out the games category on the blog.
The Update Loop
Before we get into collisions, it’s important to understand the role of the
update method. In your Phaser states you may have an
update method that looks like this:
This method is called constantly throughout the life of the game, and it is used to check the current state of the game. This is where you will add your code for checking for collisions between entities and handling those.
Setting up Properties on a Sprite
update method will handle specifying which entities should collide with what other entities, but we can also set some properties on those entities beforehand to determine how they will behave in the case of a collision.
In the game I posted a picture of above, I want the player to collide with the ground. If you’re familiar with Newton’s 3rd law “For every action, there is an equal and opposite reaction” then you would know that if this were real life then the player would exert the same amount of force on the ground as the ground exerts on the player. This should mean that if the player jumps on the ground then, naturally, the ground should move downwards as a result of that collision.
Since the Earth is so massive, this effect is negligible in real life, and the ground stays right where it is. Phaser doesn’t naturally know that our ground should be immovable, though, it will just treat it like any other entity and apply the physics of a collision to it. To stop that from happening, we can do something like this:
this.game.physics.arcade.enable(sprite); sprite.enableBody = true; sprite.body.immovable = true;
Now in the case of a collision, this sprite will not be affected, but sprites that collide with it will. There are also other properties that you can specify for collisions like the friction between entities and whether a sprite should bounce or not.
There are primarily two ways to handle collisions in Phaser: collide and overlap. You can trigger a
collide by using the following code inside of the
sprite2 will collide physically, but nothing else will happen as a result of that collision. If you would like something to happen as a result of that collision, you can do something like this:
this.game.physics.arcade.collide(sprite1, sprite2, this.someFunction, null, this);
which will still cause a collision between the two sprites, but it will also trigger
someFunction. So, if you wanted to kill the player as a result of this collision you could do so inside of
someFunction. If you don’t want two sprites to interact with each other physically, but you do want to make something happen when they touch, you can instead use overlap:
this.game.physics.arcade.overlap(sprite1, sprite2, this.someFunction, null, this);
someFunction will be triggered when the sprites overlap each other, but they won’t actually collide with each other.
Collisions with Groups
It would be quite difficult to set up a collision for every single entity in our game – the floor in my game above is made up of a bunch of different squares, and I certainly don’t want to set up a collision for each of those squares.
To deal with this we can use groups. You can add a sprite to a group, and then you can set up a collision for that entire group:
this.someGroup = this.game.add.group(); this.someGroup.add(sprite1); this.someGroup.add(sprite2); this.someGroup.add(sprite3);
You can also set physical properties, like
immovable on an entire group at once as well.
Phasers inbuilt physics system makes it quite easy for us to handle collisions in Phaser games – all we need to worry about is what we want to cause a collision, and what we want to happen as a result, but Phaser will automatically handle the physical result of that collision for us.