Introduced in the 2.4.7 version of Phaser, the new camera features look really interesting and it's worth checking them out. In this tutorial you'll see how easy it is to apply camera effects in your HTML5 games built with Phaser.
Note: if you need an introduction to the Phaser framework, you can check Getting Started With Phaser: Building "Monster Wants Candy", where I break down the source code and explain it in detail.
There are three interesting new features you can use: camera flash, fade, and shake. They do exactly what you can expect from them. Let's see why those are very useful and should be considered in your next game development project with Phaser.
Until now I was using the Juicy plugin to achieve such functionalities, but the source code was abandoned a long time ago and I had to manage it myself. Now with the features being built-in and part of the Phaser source code I don't have to worry about any compatibility issues or framework updates. They are also a lot easier to implement.
Enclave Phaser Template
I'll use Enclave Phaser Template as a case study—it's a set of basic functionalities, from states through audio and highscore management to tweens and animations. The template is open sourced and available on GitHub as part of the open.enclavegames.com initiative, so you can easily see how it all got implemented, including the new camera effects.
Ok, let's move on to the actual implementation part.
Camera Flash
Flashing the camera can be used for hit or impact effects—for example, when the player is hit by the enemy's bullet, the screen can turn red for a short moment. Here's the flash camera effect with the parameters explained:
flash(color, duration, force);
It fills the screen with the solid color and fades away to alpha 0 over the given duration. You can use the force parameter to overwrite any other flash effects and have this as the only one running at the current moment. The default color is white, and the flash lasts for half a second (500 milliseconds):
flash(0xffffff, 500, false);
Flashing the camera can be used for various effects. In the Enclave Phaser Template, it makes a nice seamless transition when bringing up a new state, to show the main menu after all the resources have finished loading. Instead of showing everything instantly, we can use the flash with black color as a base:
this.camera.flash(0x000000, 500, false);
It is executed at the very end of the create function in the MainMenu.js
file representing the menu state. You can see the effect in action on a gif:
As you can see, this achieves a nice, smooth appear effect. Now let's move on to camera fade.
Camera Fade
To make the feeling of moving between states complete, we can use fade to achieve a reversed flash and make the state fade out smoothly. If done properly, this can bring a fade-out, fade-in effect, which looks really nice. Here's the theory:
fade(color, duration, force);
The parameters are exactly the same as in a camera's flash, except the default color is not white, but black:
fade(0x000000, 500, false);
It starts filling the screen from alpha 0 with the given color and ends with a solid fill. The actual source code from the clickStart
action on the Start button in the MainMenu.js
file looks like this:
clickStart: function() { this.camera.fade(0x000000, 200, false); this.time.events.add(200, function() { this.game.state.start('Story'); }, this); }
It fades the screen over a period of 200 milliseconds and then launches a new state after the same amount of time to synchronize both actions. This is what it looks like in action:
Combining flash and fade makes a nice transition between states. Now, let's move on to the shake effect.
Camera Shake
Another useful Phaser camera method is shake—it can be used for situations where a player hits the obstacles when flying through the asteroid field, or utilizing a powerful bomb from the inventory. It can be executed when colliding with the game objects floating on the screen.
shake(intensity, duration, force, direction, shakeBounds);
The first parameter controls how much the camera is shaking, and the
second one how long the shake will last. The third one is about
replacing the already running shake if this parameter is set to true
.
The fourth controls the shake horizontally, vertically or both, and the
last parameter decides on whether the camera will shake outside of the
world bounds showing whatever is there. Here's the example with the
default values:
shake(0.05, 500, true, Phaser.Camera.SHAKE_BOTH, true);
It will shake the camera with 0.05
intensity, for half a second (500 milliseconds), the force
parameter is set to true
,
the camera will shake in both directions, and also outside of the world
bounds. If you don't need to customize the shake and leave the default
parameters, then you can just omit them in the call and it will work the
same as above:
shake();
And this is how the actual shake looks in the Enclave Phaser Template source code when the points are added in the Game.js
file:
this.camera.shake(0.01, 100, true, Phaser.Camera.SHAKE_BOTH, true);
The last three parameters are exactly the same as the default ones, so could have been omitted, but were left for educational purposes. See it in action:
In this case the intensity is lower than the default value, and the duration is shorter to make it feel a little bit weaker, so it won't distract the player too much.
ResetFX
There's also a handy little method along with those three explained
above. You can reset any active effects, and from the programming point
of view you don't even have to know if there are any running at the
given time—there's a special resetFX
method you can use.
this.camera.resetFX();
It immediately clears any ongoing camera effects and removes them from the screen.
Events
If you want to know if any specific effect is active or already
ended, you can use the events provided by the framework: onFlashComplete
, onFadeComplete
, and onShakeComplete
.
Remember the fade example on button click in the main menu? It was
done by waiting a fixed amount of time, and then the state was switched
to a new one. We can do it better using the onFadeComplete
event:
clickContinue: function() { this.camera.fade(0x000000, 200, false); this.camera.onFadeComplete.add(function() { this.game.state.start('Game'); }, this); }
This way was implemented in the next step, in the Story.js
file when switching from Story state to the Game one. You have to admit
it looks better, and the state is launched exactly when the effect is
completed, no matter how long it lasts.
Summary
As you can see, those are quite powerful features when it comes to adding this extra "juice" or polish to your games. They are at the same time also very easy to use—it's great to see them natively implemented in Phaser.
Feel free to grab the source code of Enclave Phaser Template, implement the effects, and share links to your newly upgraded games with us in the comments!