From 0f438d5221dca118db08b270f2f329b9a39a32a1 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Tue, 3 Sep 2013 19:34:38 +0100 Subject: [PATCH] separateX up and working sweet with gc spike removal too --- examples/body3.php | 9 +- src/gameobjects/Sprite.js | 4 +- src/physics/arcade/ArcadePhysics.js | 128 ++++++++++++++-------------- src/physics/arcade/Body.js | 46 +++++----- 4 files changed, 98 insertions(+), 89 deletions(-) diff --git a/examples/body3.php b/examples/body3.php index 4fd01d89..f6a39407 100644 --- a/examples/body3.php +++ b/examples/body3.php @@ -20,6 +20,7 @@ } var bunny; + var wall; var bot; function create() { @@ -27,14 +28,18 @@ game.world._stage.backgroundColorString = '#182d3b'; bunny = game.add.sprite(200, 200, 'bunny'); + bunny.body.bounce.x = 0.8; - bunny.body.acceleration.x = 10; - // bunny.body.velocity.y = 20; + wall = game.add.sprite(700, 200, 'bunny'); + wall.body.immovable = true; + + bunny.body.velocity.x = 180; } function update() { + game.physics.separateX(bunny.body, wall.body); } diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js index 1ef20759..72884303 100644 --- a/src/gameobjects/Sprite.js +++ b/src/gameobjects/Sprite.js @@ -243,10 +243,10 @@ Phaser.Sprite.prototype.update = function() { } // Update our physics bounds - this.body.update(this.center.x, this.center.y, this._cache.scaleX, this._cache.scaleY); + this.body.updateBounds(this.center.x, this.center.y, this._cache.scaleX, this._cache.scaleY); } - this.body.updateMotion(); + this.body.update(); } diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js index bf7bf6d9..77fcc2bc 100644 --- a/src/physics/arcade/ArcadePhysics.js +++ b/src/physics/arcade/ArcadePhysics.js @@ -20,6 +20,20 @@ Phaser.Physics.Arcade = function (game) { this.FLOOR = this.DOWN; this.WALL = this.LEFT | this.RIGHT; this.ANY = this.LEFT | this.RIGHT | this.UP | this.DOWN; + // console.log('any', this.ANY); + this.OVERLAP_BIAS = 4; + this.TILE_OVERLAP = false; + + // avoid creating these every frame, per collision + this._obj1Bounds = new Phaser.Rectangle; + this._obj2Bounds = new Phaser.Rectangle; + this._overlap = 0; + this._maxOverlap = 0; + this._obj1Velocity = 0; + this._obj2Velocity = 0; + this._obj1NewVelocity = 0; + this._obj2NewVelocity = 0; + this._average = 0; // this.angularDrag = 0; // this.gravity = new Phaser.Point; @@ -50,13 +64,13 @@ Phaser.Physics.Arcade.prototype = { body.velocity.x += this._velocityDelta; this._delta = body.velocity.x * this.game.time.physicsElapsed; body.velocity.x += this._velocityDelta; - body._x += this._delta; + body.x += this._delta; this._velocityDelta = (this.computeVelocity(body.velocity.y, body.gravity.y, body.acceleration.y, body.drag.y) - body.velocity.y) / 2; body.velocity.y += this._velocityDelta; this._delta = body.velocity.y * this.game.time.physicsElapsed; body.velocity.y += this._velocityDelta; - body._y += this._delta; + body.y += this._delta; }, @@ -184,49 +198,46 @@ Phaser.Physics.Arcade.prototype = { } // First, get the two object deltas - var overlap = 0; - var obj1Delta = object1.x - object1.last.x; - var obj2Delta = object2.x - object2.last.x; + this._overlap = 0; - if (obj1Delta != obj2Delta) + if (object1.deltaX() != object2.deltaX()) { // Check if the X hulls actually overlap - var obj1DeltaAbs = (obj1Delta > 0) ? obj1Delta : -obj1Delta; - var obj2DeltaAbs = (obj2Delta > 0) ? obj2Delta : -obj2Delta; - var obj1Bounds = new Quad(object1.x - ((obj1Delta > 0) ? obj1Delta : 0), object1.last.y, object1.width + ((obj1Delta > 0) ? obj1Delta : -obj1Delta), object1.height); - var obj2Bounds = new Quad(object2.x - ((obj2Delta > 0) ? obj2Delta : 0), object2.last.y, object2.width + ((obj2Delta > 0) ? obj2Delta : -obj2Delta), object2.height); - if ((obj1Bounds.x + obj1Bounds.width > obj2Bounds.x) && (obj1Bounds.x < obj2Bounds.x + obj2Bounds.width) && (obj1Bounds.y + obj1Bounds.height > obj2Bounds.y) && (obj1Bounds.y < obj2Bounds.y + obj2Bounds.height)) + this._obj1Bounds.setTo(object1.x - ((object1.deltaX() > 0) ? object1.deltaX() : 0), object1.lastY, object1.width + ((object1.deltaX() > 0) ? object1.deltaX() : -object1.deltaX()), object1.height); + this._obj2Bounds.setTo(object2.x - ((object2.deltaX() > 0) ? object2.deltaX() : 0), object2.lastY, object2.width + ((object2.deltaX() > 0) ? object2.deltaX() : -object2.deltaX()), object2.height); + + if ((this._obj1Bounds.x + this._obj1Bounds.width > this._obj2Bounds.x) && (this._obj1Bounds.x < this._obj2Bounds.x + this._obj2Bounds.width) && (this._obj1Bounds.y + this._obj1Bounds.height > this._obj2Bounds.y) && (this._obj1Bounds.y < this._obj2Bounds.y + this._obj2Bounds.height)) { - var maxOverlap = obj1DeltaAbs + obj2DeltaAbs + Collision.OVERLAP_BIAS; + this._maxOverlap = object1.deltaAbsX() + object2.deltaAbsX() + this.OVERLAP_BIAS; // If they did overlap (and can), figure out by how much and flip the corresponding flags - if (obj1Delta > obj2Delta) + if (object1.deltaAbsX() > object2.deltaAbsX()) { - overlap = object1.x + object1.width - object2.x; + this._overlap = object1.x + object1.width - object2.x; - if ((overlap > maxOverlap) || !(object1.allowCollisions & Collision.RIGHT) || !(object2.allowCollisions & Collision.LEFT)) + if ((this._overlap > this._maxOverlap) || !(object1.allowCollisions & this.RIGHT) || !(object2.allowCollisions & this.LEFT)) { - overlap = 0; + this._overlap = 0; } else { - object1.touching |= Collision.RIGHT; - object2.touching |= Collision.LEFT; + object1.touching |= this.RIGHT; + object2.touching |= this.LEFT; } } - else if (obj1Delta < obj2Delta) + else if (object1.deltaX() < object2.deltaX()) { - overlap = object1.x - object2.width - object2.x; + this._overlap = object1.x - object2.width - object2.x; - if ((-overlap > maxOverlap) || !(object1.allowCollisions & Collision.LEFT) || !(object2.allowCollisions & Collision.RIGHT)) + if ((-this._overlap > this._maxOverlap) || !(object1.allowCollisions & this.LEFT) || !(object2.allowCollisions & this.RIGHT)) { - overlap = 0; + this._overlap = 0; } else { - object1.touching |= Collision.LEFT; - object2.touching |= Collision.RIGHT; + object1.touching |= this.LEFT; + object2.touching |= this.RIGHT; } } @@ -235,34 +246,34 @@ Phaser.Physics.Arcade.prototype = { } // Then adjust their positions and velocities accordingly (if there was any overlap) - if (overlap != 0) + if (this._overlap != 0) { - var obj1Velocity = object1.velocity.x; - var obj2Velocity = object2.velocity.x; + this._obj1Velocity = object1.velocity.x; + this._obj2Velocity = object2.velocity.x; if (!object1.immovable && !object2.immovable) { - overlap *= 0.5; - object1.x = object1.x - overlap; - object2.x += overlap; + this._overlap *= 0.5; + object1.x = object1.x - this._overlap; + object2.x += this._overlap; - var obj1NewVelocity = Math.sqrt((obj2Velocity * obj2Velocity * object2.mass) / object1.mass) * ((obj2Velocity > 0) ? 1 : -1); - var obj2NewVelocity = Math.sqrt((obj1Velocity * obj1Velocity * object1.mass) / object2.mass) * ((obj1Velocity > 0) ? 1 : -1); - var average = (obj1NewVelocity + obj2NewVelocity) * 0.5; - obj1NewVelocity -= average; - obj2NewVelocity -= average; - object1.velocity.x = average + obj1NewVelocity * object1.elasticity; - object2.velocity.x = average + obj2NewVelocity * object2.elasticity; + this._obj1NewVelocity = Math.sqrt((this._obj2Velocity * this._obj2Velocity * object2.mass) / object1.mass) * ((this._obj2Velocity > 0) ? 1 : -1); + this._obj2NewVelocity = Math.sqrt((this._obj1Velocity * this._obj1Velocity * object1.mass) / object2.mass) * ((this._obj1Velocity > 0) ? 1 : -1); + this._average = (this._obj1NewVelocity + this._obj2NewVelocity) * 0.5; + this._obj1NewVelocity -= this._average; + this._obj2NewVelocity -= this._average; + object1.velocity.x = this._average + this._obj1NewVelocity * object1.bounce.x; + object2.velocity.x = this._average + this._obj2NewVelocity * object2.bounce.x; } else if (!object1.immovable) { - object1.x = object1.x - overlap; - object1.velocity.x = obj2Velocity - obj1Velocity * object1.elasticity; + object1.x = object1.x - this._overlap; + object1.velocity.x = this._obj2Velocity - this._obj1Velocity * object1.bounce.x; } else if (!object2.immovable) { - object2.x += overlap; - object2.velocity.x = obj1Velocity - obj2Velocity * object2.elasticity; + object2.x += this._overlap; + object2.velocity.x = this._obj1Velocity - this._obj2Velocity * object2.bounce.x; } return true; @@ -297,10 +308,10 @@ Phaser.Physics.Arcade.prototype = { // Check if the Y hulls actually overlap var obj1DeltaAbs = (obj1Delta > 0) ? obj1Delta : -obj1Delta; var obj2DeltaAbs = (obj2Delta > 0) ? obj2Delta : -obj2Delta; - var obj1Bounds: Quad = new Quad(object1.x, object1.y - ((obj1Delta > 0) ? obj1Delta : 0), object1.width, object1.height + obj1DeltaAbs); - var obj2Bounds: Quad = new Quad(object2.x, object2.y - ((obj2Delta > 0) ? obj2Delta : 0), object2.width, object2.height + obj2DeltaAbs); + this._obj1Bounds = new Phaser.Rectangle(object1.x, object1.y - ((obj1Delta > 0) ? obj1Delta : 0), object1.width, object1.height + obj1DeltaAbs); + this._obj2Bounds = new Phaser.Rectangle(object2.x, object2.y - ((obj2Delta > 0) ? obj2Delta : 0), object2.width, object2.height + obj2DeltaAbs); - if ((obj1Bounds.x + obj1Bounds.width > obj2Bounds.x) && (obj1Bounds.x < obj2Bounds.x + obj2Bounds.width) && (obj1Bounds.y + obj1Bounds.height > obj2Bounds.y) && (obj1Bounds.y < obj2Bounds.y + obj2Bounds.height)) + if ((this._obj1Bounds.x + this._obj1Bounds.width > this._obj2Bounds.x) && (this._obj1Bounds.x < this._obj2Bounds.x + this._obj2Bounds.width) && (this._obj1Bounds.y + this._obj1Bounds.height > this._obj2Bounds.y) && (this._obj1Bounds.y < this._obj2Bounds.y + this._obj2Bounds.height)) { var maxOverlap = obj1DeltaAbs + obj2DeltaAbs + Collision.OVERLAP_BIAS; @@ -339,8 +350,8 @@ Phaser.Physics.Arcade.prototype = { // Then adjust their positions and velocities accordingly (if there was any overlap) if (overlap != 0) { - var obj1Velocity = object1.velocity.y; - var obj2Velocity = object2.velocity.y; + this._obj1Velocity = object1.velocity.y; + this._obj2Velocity = object2.velocity.y; if (!object1.immovable && !object2.immovable) { @@ -348,18 +359,18 @@ Phaser.Physics.Arcade.prototype = { object1.y = object1.y - overlap; object2.y += overlap; - var obj1NewVelocity = Math.sqrt((obj2Velocity * obj2Velocity * object2.mass) / object1.mass) * ((obj2Velocity > 0) ? 1 : -1); - var obj2NewVelocity = Math.sqrt((obj1Velocity * obj1Velocity * object1.mass) / object2.mass) * ((obj1Velocity > 0) ? 1 : -1); - var average = (obj1NewVelocity + obj2NewVelocity) * 0.5; - obj1NewVelocity -= average; - obj2NewVelocity -= average; - object1.velocity.y = average + obj1NewVelocity * object1.elasticity; - object2.velocity.y = average + obj2NewVelocity * object2.elasticity; + this._obj1NewVelocity = Math.sqrt((this._obj2Velocity * this._obj2Velocity * object2.mass) / object1.mass) * ((this._obj2Velocity > 0) ? 1 : -1); + this._obj2NewVelocity = Math.sqrt((this._obj1Velocity * this._obj1Velocity * object1.mass) / object2.mass) * ((this._obj1Velocity > 0) ? 1 : -1); + this._average = (this._obj1NewVelocity + this._obj2NewVelocity) * 0.5; + this._obj1NewVelocity -= this._average; + this._obj2NewVelocity -= this._average; + object1.velocity.y = this._average + this._obj1NewVelocity * object1.elasticity; + object2.velocity.y = this._average + this._obj2NewVelocity * object2.elasticity; } else if (!object1.immovable) { object1.y = object1.y - overlap; - object1.velocity.y = obj2Velocity - obj1Velocity * object1.elasticity; + object1.velocity.y = this._obj2Velocity - this._obj1Velocity * object1.elasticity; // This is special case code that handles things like horizontal moving platforms you can ride if (object2.active && object2.moves && (obj1Delta > obj2Delta)) { @@ -369,7 +380,7 @@ Phaser.Physics.Arcade.prototype = { else if (!object2.immovable) { object2.y += overlap; - object2.velocity.y = obj1Velocity - obj2Velocity * object2.elasticity; + object2.velocity.y = this._obj1Velocity - this._obj2Velocity * object2.elasticity; // This is special case code that handles things like horizontal moving platforms you can ride if (object1.active && object1.moves && (obj1Delta < obj2Delta)) { @@ -385,11 +396,4 @@ Phaser.Physics.Arcade.prototype = { } }, - - - }; - -Phaser.Physics.Arcade.prototype.OVERLAP_BIAS = 4; -Phaser.Physics.Arcade.prototype.TILE_OVERLAP = false; - diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index 7ad0df5a..72b769b7 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -27,12 +27,12 @@ Phaser.Physics.Arcade.Body = function (sprite) { this.immovable = false; this.touching = 0; this.wasTouching = 0; - this.allowCollisions = 1; + this.allowCollisions = 4369; - this._x = sprite.x; - this._y = sprite.y; - this._ox = sprite.x; - this._oy = sprite.y; + this.x = sprite.x; + this.y = sprite.y; + this.lastX = sprite.x; + this.lastY = sprite.y; }; @@ -42,7 +42,7 @@ Phaser.Physics.Arcade.Body.prototype = { game: null, hitArea: null, - update: function (x, y, scaleX, scaleY) { + updateBounds: function (x, y, scaleX, scaleY) { if (scaleX != this._sx || scaleY != this._sy) { @@ -57,10 +57,10 @@ Phaser.Physics.Arcade.Body.prototype = { }, - updateMotion: function () { + update: function () { - this._ox = this._x; - this._oy = this._y; + this.lastX = this.x; + this.lastY = this.y; this.game.physics.updateMotion(this); @@ -71,8 +71,8 @@ Phaser.Physics.Arcade.Body.prototype = { postUpdate: function () { - sprite.x = this._x; - sprite.y = this._y; + this.sprite.x = this.x; + this.sprite.y = this.y; }, @@ -113,44 +113,44 @@ Phaser.Physics.Arcade.Body.prototype = { hullX: function () { - if (this._x < this._ox) + if (this.x < this.lastX) { - return this._x; + return this.x; } else { - return this._ox; + return this.lastX; } }, hullY: function () { - if (this._y < this._oy) + if (this.y < this.lastY) { - return this._y; + return this.y; } else { - return this._oy; + return this.lastY; } }, - deltaXAbs: function () { - return (this.deltaX > 0 ? this.deltaX : -this.deltaX); + deltaAbsX: function () { + return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX()); }, - deltaYAbs: function () { - return (this.deltaY > 0 ? this.deltaY : -this.deltaY); + deltaAbsY: function () { + return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY()); }, deltaX: function () { - return this._x - this._ox; + return this.x - this.lastX; }, deltaY: function () { - return this._y - this._oy; + return this.y - this.lastY; } }; \ No newline at end of file