Fixed issue with the camera being slightly out of sync with 'fixedToCamera' sprites. Also fixed 'jitter' issue with camera targets.

This commit is contained in:
photonstorm 2014-01-31 03:32:12 +00:00
parent 6e4e99f436
commit 68b7d22e0d
7 changed files with 121 additions and 80 deletions

View file

@ -34,6 +34,9 @@ console.log(' --- state create start ---');
game.step(); game.step();
}); });
// game.stage.backgroundColor = '#124184';
marker = new Phaser.Line(256, 0, 256, 600); marker = new Phaser.Line(256, 0, 256, 600);
map = game.add.tilemap('map'); map = game.add.tilemap('map');
@ -48,22 +51,21 @@ console.log(' --- state create start ---');
// layer.debug = true; // layer.debug = true;
// layer.resizeWorld(); layer.resizeWorld();
game.physics.gravity.y = 200; // game.physics.gravity.y = 200;
sprite = game.add.sprite(100, 300, 'phaser'); // up test sprite = game.add.sprite(100, 300, 'phaser'); // up test
// sprite = game.add.sprite(200, 240, 'phaser'); // 3-block corner test // sprite = game.add.sprite(200, 240, 'phaser'); // 3-block corner test
sprite.debug = true; // sprite.debug = true;
// game.stepping = true;
game.stepping = true;
// sprite.body.velocity.y = -300; // sprite.body.velocity.y = -300;
sprite.body.velocity.y = 200; // sprite.body.velocity.y = 200;
// sprite.anchor.setTo(0.5, 0.5); // sprite.anchor.setTo(0.5, 0.5);
@ -79,7 +81,7 @@ console.log(' --- state create start ---');
// sprite.angle = 35; // sprite.angle = 35;
// game.camera.follow(sprite); game.camera.follow(sprite);
// game.input.onDown.add(getIt, this); // game.input.onDown.add(getIt, this);
@ -89,7 +91,7 @@ console.log(' --- state create start ---');
function update() { function update() {
console.log(' --- state update start ---'); // console.log(' --- state update start ---');
/* /*
if (cursors.left.isDown) if (cursors.left.isDown)
@ -114,8 +116,8 @@ console.log(' --- state update start ---');
// sprite.body.velocity.y = -300; // sprite.body.velocity.y = -300;
// sprite.body.velocity.x = 0; sprite.body.velocity.x = 0;
// sprite.body.velocity.y = 0; sprite.body.velocity.y = 0;
// sprite.body.angularVelocity = 0; // sprite.body.angularVelocity = 0;
// sprite.body.acceleration.x = 0; // sprite.body.acceleration.x = 0;
@ -157,8 +159,8 @@ console.log(' --- state update start ---');
if (cursors.up.isDown) if (cursors.up.isDown)
{ {
console.log('cursor up'); // console.log('cursor up');
sprite.body.velocity.y = -300; sprite.body.velocity.y = -200;
} }
else if (cursors.down.isDown) else if (cursors.down.isDown)
{ {
@ -167,14 +169,13 @@ console.log(' --- state update start ---');
if (cursors.left.isDown) if (cursors.left.isDown)
{ {
sprite.body.velocity.x = -100; sprite.body.velocity.x = -200;
} }
else if (cursors.right.isDown) else if (cursors.right.isDown)
{ {
sprite.body.velocity.x = 100; sprite.body.velocity.x = 200;
} }
} }
function render() { function render() {

View file

@ -39,7 +39,7 @@ Phaser.Camera = function (game, id, x, y, width, height) {
* Camera view. * Camera view.
* The view into the world we wish to render (by default the game dimensions). * The view into the world we wish to render (by default the game dimensions).
* The x/y values are in world coordinates, not screen coordinates, the width/height is how many pixels to render. * The x/y values are in world coordinates, not screen coordinates, the width/height is how many pixels to render.
* Objects outside of this view are not rendered (unless set to ignore the Camera, i.e. UI?). * Objects outside of this view are not rendered if set to camera cull.
* @property {Phaser.Rectangle} view * @property {Phaser.Rectangle} view
*/ */
this.view = new Phaser.Rectangle(x, y, width, height); this.view = new Phaser.Rectangle(x, y, width, height);
@ -86,6 +86,9 @@ Phaser.Camera = function (game, id, x, y, width, height) {
*/ */
this._edge = 0; this._edge = 0;
/**
* @property {PIXI.DisplayObject} displayObject - The display object to which all game objects are added. Set by World.boot
*/
this.displayObject = null; this.displayObject = null;
}; };
@ -203,11 +206,15 @@ Phaser.Camera.prototype = {
}, },
/**
* Internal method
* @method Phaser.Camera#updateTarget
* @private
*/
updateTarget: function () { updateTarget: function () {
if (this.deadzone) if (this.deadzone)
{ {
// this._edge = this.target.bounds.x - this.deadzone.x;
this._edge = this.target.x - this.deadzone.x; this._edge = this.target.x - this.deadzone.x;
if (this.view.x > this._edge) if (this.view.x > this._edge)
@ -215,7 +222,6 @@ Phaser.Camera.prototype = {
this.view.x = this._edge; this.view.x = this._edge;
} }
// this._edge = this.target.bounds.right - this.deadzone.x - this.deadzone.width;
this._edge = this.target.x + this.target.width - this.deadzone.x - this.deadzone.width; this._edge = this.target.x + this.target.width - this.deadzone.x - this.deadzone.width;
if (this.view.x < this._edge) if (this.view.x < this._edge)
@ -223,7 +229,6 @@ Phaser.Camera.prototype = {
this.view.x = this._edge; this.view.x = this._edge;
} }
// this._edge = this.target.bounds.y - this.deadzone.y;
this._edge = this.target.y - this.deadzone.y; this._edge = this.target.y - this.deadzone.y;
if (this.view.y > this._edge) if (this.view.y > this._edge)
@ -231,7 +236,6 @@ Phaser.Camera.prototype = {
this.view.y = this._edge; this.view.y = this._edge;
} }
// this._edge = this.target.bounds.bottom - this.deadzone.y - this.deadzone.height;
this._edge = this.target.y + this.target.height - this.deadzone.y - this.deadzone.height; this._edge = this.target.y + this.target.height - this.deadzone.y - this.deadzone.height;
if (this.view.y < this._edge) if (this.view.y < this._edge)
@ -246,6 +250,10 @@ Phaser.Camera.prototype = {
}, },
/**
* Update the Camera bounds to match the game world.
* @method Phaser.Camera#setBoundsToWorld
*/
setBoundsToWorld: function () { setBoundsToWorld: function () {
this.bounds.setTo(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height); this.bounds.setTo(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height);
@ -268,10 +276,10 @@ Phaser.Camera.prototype = {
this.view.x = this.bounds.x; this.view.x = this.bounds.x;
} }
if (this.view.x > this.bounds.right - this.width) if (this.view.right > this.bounds.right)
{ {
this.atLimit.x = true; this.atLimit.x = true;
this.view.x = (this.bounds.right - this.width) + 1; this.view.x = this.bounds.right - this.width;
} }
if (this.view.y < this.bounds.top) if (this.view.y < this.bounds.top)
@ -280,10 +288,10 @@ Phaser.Camera.prototype = {
this.view.y = this.bounds.top; this.view.y = this.bounds.top;
} }
if (this.view.y > this.bounds.bottom - this.height) if (this.view.bottom > this.bounds.bottom)
{ {
this.atLimit.y = true; this.atLimit.y = true;
this.view.y = (this.bounds.bottom - this.height) + 1; this.view.y = this.bounds.bottom - this.height;
} }
this.view.floor(); this.view.floor();

View file

@ -592,7 +592,7 @@ Phaser.Game.prototype = {
} }
this.plugins.preUpdate(); this.plugins.preUpdate();
console.log('world preUpdate'); // console.log('world preUpdate');
this.world.preUpdate(); this.world.preUpdate();
this.stage.update(); this.stage.update();
@ -606,7 +606,7 @@ Phaser.Game.prototype = {
this.particles.update(); this.particles.update();
this.plugins.update(); this.plugins.update();
console.log('world postUpdate'); // console.log('world postUpdate');
this.world.postUpdate(); this.world.postUpdate();
this.plugins.postUpdate(); this.plugins.postUpdate();
} }

View file

@ -61,7 +61,8 @@ Phaser.World.prototype.boot = function () {
} }
/** /**
* This is called automatically every frame, and is where main logic happens. * This is called automatically after the plugins preUpdate and before the State.update.
* Most objects have preUpdate methods and it's where initial movement, drawing and calculations are done.
* *
* @method Phaser.World#update * @method Phaser.World#update
*/ */
@ -90,7 +91,8 @@ Phaser.World.prototype.preUpdate = function () {
} }
/** /**
* This is called automatically every frame, and is where main logic happens. * This is called automatically after the State.update, but before particles or plugins update.
* Most objects won't have an update method set unless explicitly given one.
* *
* @method Phaser.World#update * @method Phaser.World#update
*/ */
@ -121,31 +123,58 @@ Phaser.World.prototype.update = function () {
} }
/** /**
* This is called automatically every frame, and is where main logic happens. * This is called automatically before the renderer runs and after the plugins have updated.
* In postUpdate this is where all the final physics calculatations and object positioning happens.
* The objects are processed in the order of the display list.
* The only exception to this is if the camera is following an object, in which case that is updated first.
*
* @method Phaser.World#postUpdate * @method Phaser.World#postUpdate
*/ */
Phaser.World.prototype.postUpdate = function () { Phaser.World.prototype.postUpdate = function () {
this.camera.update(); if (this.camera.target && this.camera.target['postUpdate'])
if (this.game.stage._stage.first._iNext)
{ {
var currentNode = this.game.stage._stage.first._iNext; this.camera.target.postUpdate();
do this.camera.update();
if (this.game.stage._stage.first._iNext)
{ {
if (currentNode['postUpdate']) var currentNode = this.game.stage._stage.first._iNext;
{
currentNode.postUpdate();
}
currentNode = currentNode._iNext; do
{
if (currentNode['postUpdate'] && currentNode !== this.camera.target)
{
currentNode.postUpdate();
}
currentNode = currentNode._iNext;
}
while (currentNode != this.game.stage._stage.last._iNext)
}
}
else
{
this.camera.update();
if (this.game.stage._stage.first._iNext)
{
var currentNode = this.game.stage._stage.first._iNext;
do
{
if (currentNode['postUpdate'])
{
currentNode.postUpdate();
}
currentNode = currentNode._iNext;
}
while (currentNode != this.game.stage._stage.last._iNext)
} }
while (currentNode != this.game.stage._stage.last._iNext)
} }
this.camera.update();
} }
/** /**
@ -154,8 +183,8 @@ Phaser.World.prototype.postUpdate = function () {
* @method Phaser.World#setBounds * @method Phaser.World#setBounds
* @param {number} x - Top left most corner of the world. * @param {number} x - Top left most corner of the world.
* @param {number} y - Top left most corner of the world. * @param {number} y - Top left most corner of the world.
* @param {number} width - New width of the world. * @param {number} width - New width of the world. Can never be smaller than the Game.width.
* @param {number} height - New height of the world. * @param {number} height - New height of the world. Can never be smaller than the Game.height.
*/ */
Phaser.World.prototype.setBounds = function (x, y, width, height) { Phaser.World.prototype.setBounds = function (x, y, width, height) {

View file

@ -117,6 +117,12 @@ Phaser.Physics.Arcade = function (game) {
*/ */
this._p = new Phaser.Point(0, 0); this._p = new Phaser.Point(0, 0);
/**
* @property {number} _intersection - Internal cache var.
* @private
*/
this._intersection = [0,0,0,0];
/** /**
* @property {number} _gravityX - Internal cache var. * @property {number} _gravityX - Internal cache var.
* @private * @private
@ -715,10 +721,7 @@ Phaser.Physics.Arcade.prototype = {
*/ */
collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) { collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
// At this stage the body.left value is WRONG (it's the old value) // console.log('collideSpriteVsTilemapLayer x:', sprite.body.x, 'y:', sprite.body.y, 'body left:', sprite.body.left, 'right:', sprite.body.right);
// console.log('collideSpriteVsTilemapLayer sx:', sprite.x, 'sy:', sprite.y, 'body left:', sprite.body.left, 'right:', sprite.body.right);
console.log('collideSpriteVsTilemapLayer x:', sprite.body.x, 'y:', sprite.body.y, 'body left:', sprite.body.left, 'right:', sprite.body.right);
this._mapData = tilemapLayer.getTiles(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height, true); this._mapData = tilemapLayer.getTiles(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height, true);
@ -865,30 +868,27 @@ Phaser.Physics.Arcade.prototype = {
if (body.width <= 0 || body.height <= 0 || tile.width <= 0 || tile.height <= 0) if (body.width <= 0 || body.height <= 0 || tile.width <= 0 || tile.height <= 0)
{ {
return null; this._intersection[4] = 0;
return this._intersection;
} }
console.log('____ tileIntersects'); // console.log('____ tileIntersects');
console.log('body: ', body.left, body.top, body.right, body.bottom); // console.log('body: ', body.left, body.top, body.right, body.bottom);
console.log('tile: ', tile.x, tile.y, tile.right, tile.bottom); // console.log('tile: ', tile.x, tile.y, tile.right, tile.bottom);
// console.log('intersect #1', body.right < tile.x, body.right, tile.x);
// console.log('intersect #2', body.bottom < tile.y, body.bottom, tile.y);
// console.log('intersect #3', body.left > tile.right, body.left, tile.right);
// console.log('intersect #4', body.top > tile.bottom, body.top, tile.bottom);
if (!(body.right < tile.x || body.bottom < tile.y || body.left > tile.right || body.top > tile.bottom)) if (!(body.right < tile.x || body.bottom < tile.y || body.left > tile.right || body.top > tile.bottom))
{ {
var out = [0,0,0,0]; this._intersection[0] = Math.max(body.left, tile.x); // x
this._intersection[1] = Math.max(body.top, tile.y); // y
this._intersection[2] = Math.min(body.right, tile.right) - this._intersection[0]; // width
this._intersection[3] = Math.min(body.bottom, tile.bottom) - this._intersection[1]; // height
this._intersection[4] = 1;
out[0]= Math.max(body.left, tile.x); // x return this._intersection;
out[1] = Math.max(body.top, tile.y); // y
out[2] = Math.min(body.right, tile.right) - out[0]; // width
out[3] = Math.min(body.bottom, tile.bottom) - out[1]; // height
return out;
} }
return null; this._intersection[4] = 0;
return this._intersection;
}, },
@ -901,7 +901,7 @@ Phaser.Physics.Arcade.prototype = {
*/ */
separateTiles: function (body, tiles) { separateTiles: function (body, tiles) {
console.log('!!! separateTiles', tiles); // console.log('!!! separateTiles', tiles);
var tile; var tile;
var result = false; var result = false;
@ -929,17 +929,17 @@ Phaser.Physics.Arcade.prototype = {
*/ */
separateTile: function (body, tile) { separateTile: function (body, tile) {
var intersection = this.tileIntersects(body, tile); this._intersection = this.tileIntersects(body, tile);
// If the intersection area is either entirely null, or has a width/height of zero, we bail out now // If the intersection area is either entirely null, or has a width/height of zero, we bail out now
if (intersection === null || intersection[2] === 0 || intersection[3] === 0) if (this._intersection[4] === 0 || this._intersection[2] === 0 || this._intersection[3] === 0)
{ {
console.log('Tile does not intersect body'); // console.log('Tile does not intersect body');
return false; return false;
} }
console.log('*** separateTile', tile); // console.log('*** separateTile', tile);
console.log('intersection', intersection); // console.log('intersection', this._intersection);
tile.tile.debug = true; tile.tile.debug = true;
@ -969,7 +969,7 @@ Phaser.Physics.Arcade.prototype = {
// LEFT // LEFT
body.overlapX = body.left - tile.right; body.overlapX = body.left - tile.right;
console.log('ST left', body.overlapX, body.deltaX(), 'bt', body.left, tile.right); // console.log('ST left', body.overlapX, body.deltaX(), 'bt', body.left, tile.right);
if (body.overlapX < 0) if (body.overlapX < 0)
{ {
@ -985,7 +985,7 @@ Phaser.Physics.Arcade.prototype = {
// RIGHT // RIGHT
body.overlapX = body.right - tile.x; body.overlapX = body.right - tile.x;
console.log('ST right', body.overlapX, body.deltaX(), 'bt', body.right, tile.x); // console.log('ST right', body.overlapX, body.deltaX(), 'bt', body.right, tile.x);
if (body.overlapX > 0) if (body.overlapX > 0)
{ {
@ -1002,7 +1002,7 @@ Phaser.Physics.Arcade.prototype = {
// UP // UP
body.overlapY = body.top - tile.bottom; body.overlapY = body.top - tile.bottom;
console.log('ST up', body.overlapY, body.deltaY(), 'bt', body.top, tile.bottom); // console.log('ST up', body.overlapY, body.deltaY(), 'bt', body.top, tile.bottom);
if (body.overlapY < 0) if (body.overlapY < 0)
{ {
@ -1018,7 +1018,7 @@ Phaser.Physics.Arcade.prototype = {
// DOWN // DOWN
body.overlapY = body.bottom - tile.y; body.overlapY = body.bottom - tile.y;
console.log('ST down', body.overlapY, body.deltaY(), 'bt', body.bottom, tile.y); // console.log('ST down', body.overlapY, body.deltaY(), 'bt', body.bottom, tile.y);
if (body.overlapY > 0) if (body.overlapY > 0)
{ {
@ -1064,7 +1064,7 @@ Phaser.Physics.Arcade.prototype = {
*/ */
processTileSeparation: function (body) { processTileSeparation: function (body) {
console.log('PRE processTileSeparation xy', body.x, body.y, 'left', body.left, 'right', body.right, 'up', body.up, 'down', body.down); // console.log('PRE processTileSeparation xy', body.x, body.y, 'left', body.left, 'right', body.right, 'up', body.up, 'down', body.down);
if (body.overlapX < 0) if (body.overlapX < 0)
{ {
@ -1109,7 +1109,7 @@ Phaser.Physics.Arcade.prototype = {
body.touching.none = false; body.touching.none = false;
} }
console.log('POST processTileSeparation xy', body.x, body.y, 'left', body.left, 'right', body.right, 'up', body.up, 'down', body.down); // console.log('POST processTileSeparation xy', body.x, body.y, 'left', body.left, 'right', body.right, 'up', body.up, 'down', body.down);
return true; return true;

View file

@ -100,7 +100,7 @@ Phaser.Physics.Arcade.Body = function (sprite) {
this.bounce = new Phaser.Point(); this.bounce = new Phaser.Point();
/** /**
* @property {Phaser.Point} minVelocity - When a body rebounds off another or a wall the minVelocity is checked. If the new velocity is lower than minVelocity the body is stopped. * @property {Phaser.Point} minVelocity - When a body rebounds off another body or a wall the minVelocity is checked. If the new velocity is lower than minVelocity the body is stopped.
* @default * @default
*/ */
this.minVelocity = new Phaser.Point(5, 5); this.minVelocity = new Phaser.Point(5, 5);
@ -521,14 +521,14 @@ if (this.sprite.debug)
if (this.blocked.left || this.blocked.right && (Math.floor(this.x) !== this.blocked.x || Math.floor(this.y) !== this.blocked.y)) if (this.blocked.left || this.blocked.right && (Math.floor(this.x) !== this.blocked.x || Math.floor(this.y) !== this.blocked.y))
{ {
console.log('resetBlocked unlocked left + right'); // console.log('resetBlocked unlocked left + right');
this.blocked.left = false; this.blocked.left = false;
this.blocked.right = false; this.blocked.right = false;
} }
if (this.blocked.up || this.blocked.down && (this.x !== this.blocked.x || this.y !== this.blocked.y)) if (this.blocked.up || this.blocked.down && (this.x !== this.blocked.x || this.y !== this.blocked.y))
{ {
console.log('resetBlocked unlocked up + down'); // console.log('resetBlocked unlocked up + down');
this.blocked.up = false; this.blocked.up = false;
this.blocked.down = false; this.blocked.down = false;
} }

View file

@ -734,6 +734,9 @@ Phaser.TilemapLayer.prototype.render = function () {
this._ty = this._dy; this._ty = this._dy;
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
// this.context.fillStyle = '#ff00ff';
// this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
this.context.fillStyle = this.tileColor; this.context.fillStyle = this.tileColor;
var tile; var tile;