diff --git a/examples/wip/2ball.js b/examples/wip/2ball.js index 1b75ffa2..994b8752 100644 --- a/examples/wip/2ball.js +++ b/examples/wip/2ball.js @@ -28,10 +28,87 @@ function create() { var bg = game.add.sprite(0, 0, bmd); bg.body.moves = false; - test4(); + test10(); } +function test10() { + + // game.physics.gravity.y = 150; + + sprite = game.add.sprite(300, 200, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.checkCollision.down = false; + + sprite2 = game.add.sprite(330, 400, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.9, 0.9); + + game.input.onDown.add(launch10, this); + +} + +function launch10() { + + sprite2.body.velocity.y = -100; + +} + +function test9() { + + // game.physics.gravity.y = 150; + + sprite = game.add.sprite(300, 400, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.checkCollision.up = false; + // sprite.body.checkCollision.right = false; + + sprite2 = game.add.sprite(330, 100, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.9, 0.9); + + game.input.onDown.add(launch9, this); + +} + +function launch9() { + + sprite2.body.velocity.y = 100; + +} + +function test8() { + + game.physics.gravity.y = 150; + + sprite = game.add.sprite(300, 400, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.checkCollision.left = false; + sprite.body.checkCollision.right = false; + + sprite2 = game.add.sprite(500, 400, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.9, 0.9); + + game.input.onDown.add(launch8, this); + +} + +function launch8() { + + sprite.body.velocity.x = -50; + sprite2.body.velocity.x = -200; + +} + + + function test7() { game.physics.gravity.y = 200; @@ -277,7 +354,7 @@ function render() { if (sprite) { - game.debug.renderBodyInfo(sprite, 16, 24); + game.debug.renderBodyInfo(sprite2, 16, 24); // game.debug.renderText(sprite.name + ' x: ' + sprite.x.toFixed(2) + ' dx: ' + sprite.body._dx.toFixed(2), 16, 500); // game.debug.renderText(sprite.name + ' y: ' + sprite.y.toFixed(2) + ' dy: ' + sprite.body._dy.toFixed(2), 16, 520); } diff --git a/examples/wip/land.js b/examples/wip/land.js index 3b62490d..fb191947 100644 --- a/examples/wip/land.js +++ b/examples/wip/land.js @@ -17,10 +17,10 @@ function create() { game.physics.gravity.y = 100; - sprite = game.add.sprite(200, 200, 'gameboy', 0); + sprite = game.add.sprite(200, 300, 'gameboy', 0); sprite.name = 'red'; sprite.body.collideWorldBounds = true; - sprite.body.bounce.setTo(0.9, 0.9); + // sprite.body.bounce.setTo(0.9, 0.9); // sprite2 = game.add.sprite(500, 200, 'gameboy', 2); // sprite2.name = 'green'; @@ -33,15 +33,14 @@ function create() { land.body.allowGravity = false; land.body.setSize(780, 100, 0, 0); land.body.polygons = new SAT.Polygon(new SAT.Vector(10, 490), [ - new SAT.Vector(), - new SAT.Vector(100,0), - new SAT.Vector(200,50), - new SAT.Vector(400,20), - new SAT.Vector(780,0), + new SAT.Vector(0,50), + new SAT.Vector(300,0), + new SAT.Vector(780,50), new SAT.Vector(780,100), new SAT.Vector(0,100), ]); console.log(land); + sprite.body.velocity.x = 100; game.input.onDown.add(launch, this); @@ -49,7 +48,7 @@ function create() { function launch() { - sprite.body.velocity.x = -300; + sprite.body.velocity.x = 100; sprite.body.velocity.y = -300; sprite2.body.velocity.x = 200; sprite2.body.velocity.y = -200; diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js index 3e1b0f71..32a55622 100644 --- a/src/physics/arcade/ArcadePhysics.js +++ b/src/physics/arcade/ArcadePhysics.js @@ -102,6 +102,13 @@ Phaser.Physics.Arcade = function (game) { * @private */ this._gravityY = 0; + + /** + * @property {SAT.Response} _response - Internal cache var. + * @private + */ + this._response = new SAT.Response(); + }; Phaser.Physics.Arcade.prototype = { @@ -602,8 +609,6 @@ Phaser.Physics.Arcade.prototype = { */ separate: function (body1, body2, processCallback, callbackContext, overlapOnly) { - // Can't separate two immovable bodies and the same body cannot collide with itself - // if (body1 === body2 || (body1.immovable && body2.immovable) || Phaser.Rectangle.intersects(body1, body2) === false) if (body1 === body2 || Phaser.Rectangle.intersects(body1, body2) === false) { return false; @@ -615,15 +620,17 @@ Phaser.Physics.Arcade.prototype = { return false; } + this._response.clear(); + if (overlapOnly) { - return body1.overlap(body2); + return body1.overlap(body2, this._response); } else { - if (body1.overlap(body2)) + if (body1.overlap(body2, this._response)) { - return body1.separate(body2); + return body1.separate(body2, this._response); } } diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index 5ff5a880..1a0e6b7c 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -319,9 +319,6 @@ Phaser.Physics.Arcade.Body = function (sprite) { */ this.polygons = new SAT.Box(new SAT.Vector(this.x, this.y), this.width, this.height).toPolygon(); - // This needs to move to a global ArcadePhysics one - this.response = new SAT.Response(); - this._debug = 0; }; @@ -586,13 +583,12 @@ Phaser.Physics.Arcade.Body.prototype = { * * @method Phaser.Physics.Arcade#overlap * @param {Phaser.Physics.Arcade.Body} body - The Body that collided. + * @param {SAT.Response} response - SAT Response handler. * @return {boolean} True if the two bodies overlap, otherwise false. */ - overlap: function (body) { + overlap: function (body, response) { - this.response.clear(); - - return SAT.testPolygonPolygon(this.polygons, body.polygons, this.response); + return SAT.testPolygonPolygon(this.polygons, body.polygons, response); }, @@ -788,6 +784,17 @@ Phaser.Physics.Arcade.Body.prototype = { */ hitLeft: function (body, response) { + // We know that Body is overlapping with This on the left-hand side + if ((body.deltaX() < 0 && !this.checkCollision.right) || (body.deltaX() > 0 && !this.checkCollision.left)) + { + return; + } + + if ((body.deltaY() < 0 && !this.checkCollision.down) || (body.deltaY() > 0 && !this.checkCollision.up) || (body.deltaY() > 0 && !this.checkCollision.up) || (body.deltaY() > 0 && !this.checkCollision.down)) + { + return; + } + // This body isn't moving horizontally, so it was hit by something moving right if (this.immovable || this.blocked.right) { @@ -833,6 +840,17 @@ Phaser.Physics.Arcade.Body.prototype = { */ hitRight: function (body, response) { + // We know that Body is overlapping with This on the right-hand side + if ((body.deltaX() < 0 && !this.checkCollision.right) || (body.deltaX() > 0 && !this.checkCollision.left)) + { + return; + } + + if ((body.deltaY() < 0 && !this.checkCollision.down) || (body.deltaY() > 0 && !this.checkCollision.up) || (body.deltaY() > 0 && !this.checkCollision.up) || (body.deltaY() > 0 && !this.checkCollision.down)) + { + return; + } + // This body isn't moving horizontally, so it was hit by something moving left if (this.immovable || this.blocked.left) { @@ -878,6 +896,12 @@ Phaser.Physics.Arcade.Body.prototype = { */ hitTop: function (body, response) { + // We know that Body is overlapping with This on the top side (deltaY > 0 = moving down < 0 = moving up) + if ((body.deltaY() > 0 && (!this.checkCollision.up || !this.checkCollision.down)) || (body.deltaY() < 0 && (!this.checkCollision.down || !this.checkCollision.up))) + { + return; + } + // This body isn't moving vertically, so it was hit by something moving down if (this.immovable || this.blocked.down) { @@ -923,6 +947,12 @@ Phaser.Physics.Arcade.Body.prototype = { */ hitBottom: function (body, response) { + // We know that Body is overlapping with This on the bottom side (deltaY > 0 = moving down < 0 = moving up) + if ((body.deltaY() < 0 && (!this.checkCollision.down || !this.checkCollision.up)) || (body.deltaY() < 0 && (!this.checkCollision.down || !this.checkCollision.up))) + { + return; + } + // This body isn't moving vertically, so it was hit by something moving up if (this.immovable || this.blocked.up) { @@ -993,13 +1023,14 @@ Phaser.Physics.Arcade.Body.prototype = { * @method Phaser.Physics.Arcade#separate * @protected * @param {Phaser.Physics.Arcade.Body} body - The Body to be separated from this one. + * @param {SAT.Response} response - SAT Response handler. * @return {boolean} */ - separate: function (body) { + separate: function (body, response) { if (this.customSeparateCallback) { - return this.customSeparateCallback.call(this.customSeparateContext, this, this.response); + return this.customSeparateCallback.call(this.customSeparateContext, this, response); } var distances = [ @@ -1009,32 +1040,32 @@ Phaser.Physics.Arcade.Body.prototype = { (this.bottom - body.y) // distance of box 'b' to face on 'top' side of 'a'. ]; - if (this.response.overlapN.x) + if (response.overlapN.x) { // Which is smaller? Left or Right? if (distances[0] < distances[1]) { - console.log(this.sprite.name, 'collided on the LEFT with', body.sprite.name, this.response); - this.hitLeft(body, this.response); + console.log(this.sprite.name, 'collided on the LEFT with', body.sprite.name, response); + this.hitLeft(body, response); } else if (distances[1] < distances[0]) { - console.log(this.sprite.name, 'collided on the RIGHT with', body.sprite.name, this.response); - this.hitRight(body, this.response); + console.log(this.sprite.name, 'collided on the RIGHT with', body.sprite.name, response); + this.hitRight(body, response); } } - else if (this.response.overlapN.y) + else if (response.overlapN.y) { // Which is smaller? Top or Bottom? if (distances[2] < distances[3]) { - console.log(this.sprite.name, 'collided on the TOP with', body.sprite.name, this.response); - this.hitTop(body, this.response); + console.log(this.sprite.name, 'collided on the TOP with', body.sprite.name, response); + this.hitTop(body, response); } else if (distances[3] < distances[2]) { - console.log(this.sprite.name, 'collided on the BOTTOM with', body.sprite.name, this.response); - this.hitBottom(body, this.response); + console.log(this.sprite.name, 'collided on the BOTTOM with', body.sprite.name, response); + this.hitBottom(body, response); } } @@ -1146,6 +1177,9 @@ Phaser.Physics.Arcade.Body.prototype = { this.y = this.preY; this.rotation = this.preRotation; + this.polygons.pos.x = this.x; + this.polygons.pos.y = this.y; + this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight); }, @@ -1269,3 +1303,20 @@ Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "right", { } }); + +/** +* @name Phaser.Physics.Arcade.Body#movingLeft +* @property {boolean} movingLeft - True if this Body is moving left, based on its angle and speed. +*/ +Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "movingLeft", { + + /** + * True if this Body is moving left, based on its angle and speed. + * @method movingLeft + * @return {boolean} + */ + get: function () { + return (this.speed > 0 && this.angle >= 0 && this.angle <= 0); + }, + +});