Jump to content

Drop-in replacement for Camera.updateFollow to allow leading

Cameron Foale

Recommended Posts

The built in Phaser camera following is nice and robust, but I wanted to add camera leading based on object velocity.


Here's a drop-in replacement. We use a PhaserPatch.js for this sort of stuff, and this probably isn't engineered well enough for a pull request :)

Phaser.Camera.prototype.updateTarget = function () {    this.lead = this.lead || new Phaser.Point(0, 0);    var velocityObject = this.target.body || this.target;    this.newOffset = this.newOffset || new Phaser.Point(0, 0);    this.newOffset.setTo(        Phaser.Math.clamp(velocityObject.velocity.x, -this.lead.x, this.lead.x),        Phaser.Math.clamp(velocityObject.velocity.y, -this.lead.y, this.lead.y)    );    this.targetOffset = this.targetOffset || new Phaser.Point(this.newOffset.x, this.newOffset.y);    // This bit uses a nice exponential smoothing.    // The 0.2 is a half-life of the smoothing, in seconds    var smoothing = Math.pow(0.2, this.game.time.physicsElapsed);    this.targetOffset.setTo(        this.targetOffset.x * smoothing + this.newOffset.x * (1-smoothing),        this.targetOffset.y * smoothing + this.newOffset.y * (1-smoothing)    );    this.followPoint = this.followPoint || new Phaser.Point(0, 0);    this.followPoint.setTo(        Math.round(this.target.x + this.targetOffset.x),        Math.round(this.target.y + this.targetOffset.y)    );   if (this.deadzone)   {       this._edge = this.followPoint.x - this.deadzone.x;       if (this.view.x > this._edge)       {           this.view.x = this._edge;       }       this._edge = this.followPoint.x + this.target.width - this.deadzone.x - this.deadzone.width;       if (this.view.x < this._edge)       {           this.view.x = this._edge;       }       this._edge = this.followPoint.y - this.deadzone.y;       if (this.view.y > this._edge)       {           this.view.y = this._edge;       }       this._edge = this.followPoint.y + this.target.height - this.deadzone.y - this.deadzone.height;       if (this.view.y < this._edge)       {           this.view.y = this._edge;       }   }   else   {       this.focusOnXY(this.followPoint.x, this.followPoint.y);   }};

Here's how you use it:

this.game.camera.follow(this.avatar.]]);this.game.camera.deadzone = new Phaser.Rectangle(    this.game.width / 4, 0, this.game.width / 2, this.game.height);// here's the new bit: what is the maximum leadthis.game.camera.lead = new Phaser.Point(this.game.width * 3/4, 0);
Link to comment
Share on other sites

Because camera following really influences the feel of a game a lot, there's not really one fixed solution. This one is working ok, but there are some tweaks you could make:


- Make it depend on a facing value, rather than a velocity.

this.newOffset.setTo(        velocityObject.facing == Phaser.RIGHT ? this.lead.x : (velocityObject.facing == Phaser.LEFT ? -this.lead.x : 0),        velocityObject.facing == Phaser.DOWN ? this.lead.y : (velocityObject.facing == Phaser.UP ? -this.lead.y : 0))    );

- Switch to using the sign of the acceleration rather than the value of the velocity.

this.newOffset.setTo(        Phaser.Math.clamp(velocityObject.acceleration.x * 1000, -this.lead.x, this.lead.x),        Phaser.Math.clamp(velocityObject.acceleration.y * 1000, -this.lead.y, this.lead.y)    );

- Switch to a linear interpolation rather than exponential

Link to comment
Share on other sites

That's not a bad idea.


Unfortunately there isn't a plugin hook for this sort of thing right now, as far as I know.


It's a shame, because I also have 2 camera shake plugins that need more info about Phaser internals than they should too. I can't think offhand of a clean design for such a plugin either, without making the current camera plugin-driven too.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...