Jump to content

Drop-in replacement for Camera.updateFollow to allow leading


Cameron Foale
 Share

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

 Share

  • Recently Browsing   0 members

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