Note: all examples in this post assume you have already loaded Phaser in a browser session or development environment.
Building from the last post, we move on to input and Arcade physics…
Adding and removing sprites isn’t very interesting in and of itself. If we are making a game, we inevitably want a player to interact with something at some point. Be that clicking on something or pressing a button to move a character, players want to have some agency.
Pressing buttons to do things
Now that we can add sprites to the screen, we want to be able to move them about. To to that, we use the game.input functionality AND finally start to use the update function.
See, it isn’t enough to move an object just once. We want to check on some recurring basis and, if the player has supplied some input, move something according. To do that, we need to check the input in the update function.
n the above example, we are using a specialized function of game.input.keyboard called isDown that takes an argument of some Phaser.Keyboard object and checks if it is actually down (currently pressed) or not. And if it is, in our example, we move ‘sprite’ four pixels to the left.
Note: If you are not familiar, nearly all drawing systems on computers use a coordinate system of 0,0 in the upper left-hand corner and some n, n at the bottom right-hand side. Moving to the right, then, is adding to the ‘x’ position. Moving down is adding to the ‘y’ position. Subtracting (or adding negative numbers) would mean moving up or to the left as in our example.
Different buttons, different things
Adding more buttons to press is simply a matter of checking those same buttons. If we wanted to move up, we would check some button for that. For down, some button for that. For every action we wanted the player to take involving pressing a button, we would need to check for that.
In the above example, we can move the sprite around on the screen by using the arrow keys. As long as one of the four keys that are checked are ‘down’, the sprite will move in that direction. However, what if we had another sprite on the screen at the same time — and what if they collided with each other? For that, we need some physics.
How (Arcade) Physics Works
Phaser comes with three different physics systems: Arcade, Box2D, and P2. Each acts in a different way and can be used to check for a variety of issues between two items colliding on the screen.
However, for these examples, and in general, it is probably enough to use the Arcade system to detect if two or more objects might be colliding on the screen.
To enable the Arcade (or other) physics system, we start said system and, on the objects on which we want to use it, enable its “physics body.”
Note: In game design terms, a “physics body” is how some object is understood by the physics system or engine. Generally, it is how the ‘body’ is shaped, too. In the case of Phaser and Arcade physics in particular, this means a square matching the sprite’s image and some default values about how it can move.
With a physics system enabled, we can move sprites in a new way. Instead of using the pixel movements of adding or subtracting numbers, we can use the concept of velocity.
Note: Within the general study of physics, a velocity is some speed and a direction. Things like gravity, for example, can be described in terms of velocity.
Note in the above example, velocity works via some object’s body and, like the pixel movements on the screen, matches the negative and positive changes (i.e. negative for up and left, positive for right and down).
In video game design terms, “collision detection” is critically important. Within a physics system, we need to know if a character is touching some spikes, is about to be hit by a barrel, or if bullets are impacting something.
To detect a collision with the Arcade system in Phaser, we use game.physics.arcade.collide and provide it with either two objects or groups. If any of the entries used as arguments are colliding, the function will return true. Put within the update function, we check to see in each loop if this is happening and then do something about about as a result.
In its most common form, game.physics.arcade.collide is simply two collections or objects and acts, upon detecting a collision between any of the objects, to separate them. Without any other instructions, it simply does that.
However, if we want a more detailed check from the Arcade physics system, we can also supply two more arguments to game.physics.arcade.collide: collision and process callbacks. If we want to perform some actions when things collide other than simply separating them, we can supply a function that is called when a collision is detected. If on the other hand, we wanted to add to the rules of collision, for example they collide AND their health is at a certain amount, we can add some extra process function that would make some decision and return true or false as a result.
Energy transference (i.e. hitting things with other things)
Sure, we can move objects using velocity, but what if we wanted to collide things moving at different speeds? Instead of having them cancel each other out, what if we had objects moving at different speeds or with different masses? What would happen then?
Within many physics systems (including the Arcade on in Phaser), this is known as “energy transference.” Think of it in terms of some fast moving thing hitting something sitting still. Energy is transferred between the objects.
In the above example, energy is transferred between the objects upon their collision. When one moving (via velocity) object touches another, the amount of change as divided by their mass is transferred.
What if we didn’t want both objects to move, though? Is there a way to make an immovable object?
Immovable objects (and how to move them)
Sometimes, we want to have objects that obey the physics rules, but we don’t want them to move as a result of collisions. These are immovable — and, yes, they can be moved, too.
In the case of Arcade physics in Phaser, we set this option as a boolean on the sprites themselves using body.immovable. Once set, the object will not be acted upon as a result of collisions. It can still be moved using its coordinates or using its velocity, though, but will “absorb” any energy transferred to it when it collides or or other things run into it.