Write better camera for Phaser — Part 2

Write a more advance camera for Phaser HTML5 game framework.


On my previous post, I’ve written a easy to use zooming functionality for Phaser camera. I had it smoothly zoom the camera to any scale I want.

I feel you, Obama
And then I realized, I wanted everything to be smooth.

How about a smooth follow functionality…

Don’t get me wrong, Phaser camera does have follow functionality, it’s just too…strict. It’s more like you stick the camera on to the entity. Seriously, when I hear follow, I think stalker.

A stalker doesn’t stick on his target, he keeps distance and quietly follow. That’s mean, when the target moves, he doesn’t move immediately and slowly chase after. So I let my hands dirty again.


As always, my method is very simple: make an actual stalker and make the camera follow the stalker instead of the target. And this is what I came up with (remember my code from previous post?):

class Camera extends Phaser.Group {
constructor() {
...
this.stalker = game.add.sprite(0, 0, null);
game.physics.arcade.enable(this.stalker);
game.camera.follow(this.stalker);
}
follow(world) {
this.target = target;
}
update() {
super.update();
if (this.target) {
var arcade = game.physics.arcade;
var stalker = this.stalker;
arcade.moveToObject(stalker, target);
}
}
}
Aha, isn’t that easy?
Yes it is.
Does it work?
Not so fast.

First, if the target is in a group, it’s position is relative to that group. The stalker however, doesn’t belong the that group, so he couldn’t know where his target is. So instead of let the stalker follow the target position, I let him follow the target’s GPS position (aka target.world):


follow(world) {
this.target = target.world;
}

Second, when the stalker is far away from the target, everything works awesome, he chase after the target beautifully. But he doesn’t slow down when he is near the target and runs pass it. He realizes that, and turns around and runs back, but again, he moves too fast and runs pass it again.

Let me remind you: a stalker keeps his distance.

When he is too close, he would stop:

constructor() {
...
this.safeDistance
...
}
update() {
...
if (this.target) {
...
var position = this.stalker.position;
var distance = position.distance(this.target);
if (distance >= this.safeDistance) {
arcade.moveToObject(this.stalker, this.target);
}
}
}

For complete source code, check out the gist here.


What’s next?

In the following posts, I would cover the topics I mentioned in the previous post as well as ES6 with Babel and using ES6 with Phaser. Which ever come to my mind first ☺

Follow me on Twitter and check out my blog for interesting topics.

If you are seeking for a freelancer on game and web development, please feel free to contact me at anhnt.fami@gmail.com.