Jump to content

Arcade.Collide returning false on successful collision


Overkitty
 Share

Recommended Posts

I'm using arcade.collide to detect collision between a single Sprite and a group of Sprites. The documentation states collide should return true if there was a successful collision. Whether there is a successful collision or not the collide function always returns false for me. I just updated to 2.4.2 to see if that would fix my issue but no luck. Here's basically what my code looks like.

 

if (this.game.physics.arcade.collide(this, groupOfSprites, null, this.collisionProcess, this)) {
                console.log("Successful collision!");
}

 

The "Successful collision!" log will not be hit even if the collision was successful. Has anyone else experienced this? Is there an alternative way to determine if a collision was successful and have separate code paths for each outcome?

 

Some more information about my setup.

 

Windows 10

Chrome
Phaser 2.4.2
TypeScript

Link to comment
Share on other sites

You've over-ridden the collision process handler, and that function must return 'true' for the actual collision to take place - does yours?

 

Also I'd recommend using the collision callback rather than relying on the method result, but even so it should still work as long as the process passes.

Link to comment
Share on other sites

I am returning true in the processCallback but the collide method still returns false. Here's more of the code in case I'm doing something else wrong.

 

fire() {    

    if (this.protoGame.physics.arcade.collide(this, this.level2State.buildingGroup, this.collideCallback, this.processCallback, this)) {
        console.log("Hit Building!");
    }
    else {
        console.log("Hit nothing!");
    }
}

collideCallback(reticle, building) {
    console.log("collideCallback");
}

processCallback(reticle, building): boolean {
    console.log("processCallback");
    return true;
}

 

The 'this' is a class extending Phaser.Sprite. When 'this' is colliding with a sprite in buildingGroup the console spits out "processCallback" and "Hit nothing!". If 'this' is not colliding with a building then none of those logs are printed out in the console. So when processCallback returns true the collideCallback is never being called which could be related. The reason I am trying to use the method result is because I need to have two different things happen when the collision happens and when it doesn't.

I also tried removing the callback overrides ('collide(this, this.level2State.buildingGroup)') and it still returns false if the collision does happen.

Link to comment
Share on other sites

Are you sure both bodies haven't been set to immovable? If they have then it won't return true as it only does that on successful separation, but two immovable bodies don't separate - you need to use overlap instead of collide in that specific case.

Link to comment
Share on other sites

Overlap works perfectly, thanks for pointing me towards that. Though I am not setting them to immovable. On the single sprite I am using setSize to adjust the bounding box but besides that I'm simply calling arcade.enable on all of them. Would there be some other way I'm inadvertently setting them to immovable?

Link to comment
Share on other sites

Here's a test case that works just fine for me. It uses assets from the Phaser Examples repo:

var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update });function preload() {    game.load.image('phaser', 'assets/sprites/phaser-dude.png');    game.load.spritesheet('veggies', 'assets/sprites/fruitnveg32wh37.png', 32, 32);}var sprite;var group;var cursors;function create() {    game.physics.startSystem(Phaser.Physics.ARCADE);    game.stage.backgroundColor = '#2d2d2d';    sprite = game.add.sprite(32, 200, 'phaser');    game.physics.arcade.enable(sprite);        group = game.add.physicsGroup();    for (var i = 0; i < 50; i++)    {        var c = group.create(game.rnd.between(100, 770), game.rnd.between(0, 570), 'veggies', game.rnd.between(0, 35));        c.body.mass = -100;    }    for (var i = 0; i < 20; i++)    {        var c = group.create(game.rnd.between(100, 770), game.rnd.between(0, 570), 'veggies', 17);    }    cursors = game.input.keyboard.createCursorKeys();}function update() {    if (game.physics.arcade.collide(sprite, group, collisionHandler, processHandler, this))    {        console.log('boom');    }    // game.physics.arcade.overlap(sprite, group, collisionHandler, null, this);    sprite.body.velocity.x = 0;    sprite.body.velocity.y = 0;    if (cursors.left.isDown)    {        sprite.body.velocity.x = -200;    }    else if (cursors.right.isDown)    {        sprite.body.velocity.x = 200;    }    if (cursors.up.isDown)    {        sprite.body.velocity.y = -200;    }    else if (cursors.down.isDown)    {        sprite.body.velocity.y = 200;    }}function processHandler (player, veg) {    return true;}function collisionHandler (player, veg) {    if (veg.frame == 17)    {        veg.kill();    }}

The logs come out fine, the collision works fine, so all I can assume is that this does actually work on a Phaser level, but something else in your code that we've not seen yet is the root of it. I'd start boiling it down to the bare essentials. It could be as simple as a context issue, or an accidentally overridden property.

Link to comment
Share on other sites

Thanks for the example code. I was unable to reproduce my problem with that code so I went back to mine and started digging deeper. After debugging into the collideSpriteVsSprite function I found the issue and realize I left out useful information when describing my issue. In my code the single sprite (first sprite in my example above) is being moved by a tween. Even though the sprite is moving the body.deltaY() still returns 0. So because deltaY() returns 0 for both sprites they are marked as embedded inside seperateY(). Due to that overlap is set to 0 causing no separation and no collision. You can reproduce this behavior by adding the following line to your example.

game.add.tween(sprite).to({ x: 700 }, 3000, Phaser.Easing.Linear.None, true);

Would there be a proper way to have a sprite being moved by a tween collide with arcade physics bodies? I tried tweening the body position but that didn't work either.

Link to comment
Share on other sites

You cannot collide a Sprite that is being moved outside of physics as it has no velocity and therefore no way to resolve the collision.

 

You could always tween the velocity values of the body, or alternatively you need to use an overlap check, not a collide check, and then resolve the penetration and response (if any) in your callback.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...