diff --git a/README.md b/README.md index 6751febb0..2a16b0b08 100644 --- a/README.md +++ b/README.md @@ -329,6 +329,8 @@ You can read all about the philosophy behind Lazer [here](http://phaser.io/news/ * ArcadePhysics.World.separateCircle is a new method that handles all circular body collisions internally within Arcade Physics (thanks @VitaZheltyakov) * All of the Arcade Physics internal methods, such as `collideGroupVsSelf`, `collideSpriteVsSprite` and so on, have been updated to work with circular body shapes (thanks @VitaZheltyakov) * ArcadePhysics.Body.onWorldBounds is a new Signal that is dispatched whenever the Body collides with the world bounds, something that was previously difficult to detect. Due to the potentially high volume of signals this could create it is disabled by default. To use this feature set this property to a Phaser.Signal: `sprite.body.onWorldBounds = new Phaser.Signal()` and it will be called when a collision happens, passing one argument: the sprite on which it occurred. +* ArcadePhysics.Body.onCollide is a new Signal that is dispatched whenever the Body collides with another Body. Due to the potentially high volume of signals this could create it is disabled by default. To use this feature set this property to a Phaser.Signal: `sprite.body.onCollide = new Phaser.Signal()` and it will be called when a collision happens, passing two arguments: the sprites which collided. +* ArcadePhysics.Body.onOverlap is a new Signal that is dispatched whenever the Body overlaps with another Body. Due to the potentially high volume of signals this could create it is disabled by default. To use this feature set this property to a Phaser.Signal: `sprite.body.onOverlap = new Phaser.Signal()` and it will be called when an overlap happens, passing two arguments: the sprites which collided. ### Updates diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index da4bdb36e..392ae5f50 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -191,13 +191,52 @@ Phaser.Physics.Arcade.Body = function (sprite) { /** * A Signal that is dispatched when this Body collides with the world bounds. * Due to the potentially high volume of signals this could create it is disabled by default. - * To use this feature set this property to a Phaser.Signal: - * `sprite.body.onWorldBounds = new Phaser.Signal()` + * To use this feature set this property to a Phaser.Signal: `sprite.body.onWorldBounds = new Phaser.Signal()` * and it will be called when a collision happens, passing one argument: the sprite on which it occurred. * @property {Phaser.Signal} onWorldBounds */ this.onWorldBounds = null; + /** + * A Signal that is dispatched when this Body collides with another Body. + * + * You still need to call `game.physics.arcade.collide` in your `update` method in order + * for this signal to be dispatched. + * + * Usually you'd pass a callback to the `collide` method, but this signal provides for + * a different level of notification. + * + * Due to the potentially high volume of signals this could create it is disabled by default. + * + * To use this feature set this property to a Phaser.Signal: `sprite.body.onCollide = new Phaser.Signal()` + * and it will be called when a collision happens, passing two arguments: the sprites which collided. + * The first sprite in the argument is always the owner of this Body. + * + * If two Bodies with this Signal set collide, both will dispatch the Signal. + * @property {Phaser.Signal} onCollide + */ + this.onCollide = null; + + /** + * A Signal that is dispatched when this Body overlaps with another Body. + * + * You still need to call `game.physics.arcade.overlap` in your `update` method in order + * for this signal to be dispatched. + * + * Usually you'd pass a callback to the `overlap` method, but this signal provides for + * a different level of notification. + * + * Due to the potentially high volume of signals this could create it is disabled by default. + * + * To use this feature set this property to a Phaser.Signal: `sprite.body.onOverlap = new Phaser.Signal()` + * and it will be called when a collision happens, passing two arguments: the sprites which collided. + * The first sprite in the argument is always the owner of this Body. + * + * If two Bodies with this Signal set collide, both will dispatch the Signal. + * @property {Phaser.Signal} onOverlap + */ + this.onOverlap = null; + /** * @property {Phaser.Point} maxVelocity - The maximum velocity in pixels per second sq. that the Body can reach. * @default diff --git a/src/physics/arcade/World.js b/src/physics/arcade/World.js index e1edcbe6c..fa28a2935 100644 --- a/src/physics/arcade/World.js +++ b/src/physics/arcade/World.js @@ -1019,7 +1019,37 @@ Phaser.Physics.Arcade.prototype = { } } - return (resultX || resultY); + var result = (resultX || resultY); + + if (result) + { + if (overlapOnly) + { + if (body1.onOverlap) + { + body1.onOverlap.dispatch(body1.sprite, body2.sprite); + } + + if (body2.onOverlap) + { + body2.onOverlap.dispatch(body2.sprite, body1.sprite); + } + } + else + { + if (body1.onCollide) + { + body1.onCollide.dispatch(body1.sprite, body2.sprite); + } + + if (body2.onCollide) + { + body2.onCollide.dispatch(body2.sprite, body1.sprite); + } + } + } + + return result; }, @@ -1175,6 +1205,19 @@ Phaser.Physics.Arcade.prototype = { // Can't separate two immovable bodies, or a body with its own custom separation logic if (overlapOnly || overlap === 0 || (body1.immovable && body2.immovable) || body1.customSeparateX || body2.customSeparateX) { + if (overlap !== 0) + { + if (body1.onOverlap) + { + body1.onOverlap.dispatch(body1.sprite, body2.sprite); + } + + if (body2.onOverlap) + { + body2.onOverlap.dispatch(body2.sprite, body1.sprite); + } + } + // return true if there was some overlap, otherwise false return (overlap !== 0); } @@ -1263,6 +1306,16 @@ Phaser.Physics.Arcade.prototype = { body2.y += (body2.velocity.y * this.game.time.physicsElapsed) + overlap * Math.sin(angleCollision); } + if (body1.onCollide) + { + body1.onCollide.dispatch(body1.sprite, body2.sprite); + } + + if (body2.onCollide) + { + body2.onCollide.dispatch(body2.sprite, body1.sprite); + } + return true; }, diff --git a/typescript/phaser.d.ts b/typescript/phaser.d.ts index 8cf102f1e..a23be5f3c 100644 --- a/typescript/phaser.d.ts +++ b/typescript/phaser.d.ts @@ -3011,7 +3011,10 @@ declare module Phaser { movementCallbackContext: any; newVelocity: Phaser.Point; offset: Phaser.Point; + onCollide: Phaser.Signal; onMoveComplete: Phaser.Signal; + onOverlap: Phaser.Signal; + onWorldBounds: Phaser.Signal; overlapX: number; overlapY: number; phase: number;