phaser-ce
phaser-ce copied to clipboard
P2 `collideWorldBounds = false` disables collisions with other entities as well
This Issue is about
- A bug in the API:
- Phaser version(s): phaser-ce 2.7.7
- Live example: https://codepen.io/okaybenji/pen/oWEvLO
- What should happen:
sprite.body.collideWorldBounds = false
should disable collisions with world bounds, but do nothing else. - What happens instead:
sprite.body.onBeginContact
callback never fires for bodies withcollideWorldBounds = false
, and other bodies'onBeginContact
functions will never be passed bodies withcollideWorldBounds = false
.
In the provided example, I create two identical sprites occupying the same space. Since collideWorldBounds is set to false on one of those sprites, onBeginContact will not fire. If you comment out the line setting collideWorldBounds to false, the event will fire and 'colliding!' will be logged in the console.
Thank you!
This is the expected behavior, but it's not really mentioned in the docs.
By default P2 sets the collisionGroup and collisionMask of all the shapes to 1 (including the world bounds) so they all collide, but changing body.collideWorldBounds calls body.updateCollisionMask, which then changes that body's shapes' collision masks to the value returned by body.getCollisionMask:
getCollisionMask: function () {
var mask = 0;
if (this._collideWorldBounds) {
mask = this.game.physics.p2.boundsCollisionGroup.mask;
}
for (var i = 0; i < this.collidesWith.length; i++) {
mask = mask | this.collidesWith[i].mask;
}
return mask;
}
Which, if you haven't told your sprite to collide with anything is 0 and your sprite stops colliding at all.
It's not really a bug, but it is sort of a pain since setting collideWorldBounds on a body means you have to start explicitly telling that body what you do want it to collide with and that means setting up collision groups for those things.
I'm leaning toward leaving it the way it is and putting something in the docs since changing it would probably break compatibility, but one possible fix could be to change the default world bounds group to 0b10 (which is what p2.updateBoundsCollisionGroup sets it to), the default collision mask to 0b11, and have collideWorldBounds toggle bit 2 instead of updating the whole mask.