Jump to content

remove sprites onBeginContact in a loop


wernersbacher
 Share

Recommended Posts

Hello,

I have a for loop which spawns some coins. They have a onBeginContact signal fired, and then they will get removed (player collects them)

My code looks like this, but the problem is that only the last coin gets removed:

for (i = 0; i < 5; i++) {
            coin = coins.create(WIDTH + i*16*(YFACTOR + 2), (HEIGHT - 16) * rand, "coins");
            game.physics.p2.enable(coin, false);
            coin.body.data.shapes[0].sensor = true;
            coin.body.onBeginContact.add(function () {
                removeCoin(coin);
            }, this);
        }

 

(removeCoin will then remove the coin with coins.remove(coin).)

Can somebody tell me where I made a mistake (and how to fix it)

 

Thank you! :)

Link to comment
Share on other sites

Your problem is you are reusing the coin variable...
By the time the callback is triggered, coin is pointing at the last coin only...
You need a different way to reference the coin you want to remove in the callback...

Without whipping up some test code, I can suggest:
- putting var in front of coin to see if that helps...
- storing the coins in an array, putting the index on the coin object, and using that to refer to the coin
- See if this will help you: http://phaser.io/docs/2.5.0/Phaser.Physics.P2.Body.html#onBeginContact Specifically, this part:

 

Quote

 

The event will be sent 5 arguments in this order:

The Phaser.Physics.P2.Body it is in contact with. This might be null if the Body was created directly in the p2 world. The p2.Body this Body is in contact with. The Shape from this body that caused the contact. The Shape from the contact body. The Contact Equation data array.

 

I haven't used P2 before, I am assuming that 'The Shape' is referring to the sprite you attached the body to...

Link to comment
Share on other sites

It is indeed because the collision gets the last item in the group.

I am not experienced enough in P2 to know whether XekeDeath's suggestions will work, but you can also try to loop through your group to get the correct object for onBeginContact.

Replace your onBeginContact with something like this:

//Loop through the group
for (var i = 0; i < coins.length; i++) {
   //Get each child form the group
   child = coins.children[i];
   //Check for each child whether you are beginning a contact
   child.body.onBeginContact.add(function () {
      removeCoin(child);
   }, this);
}

 

Link to comment
Share on other sites

This last code snippet has the same problem: the loop is going to make "child" point to the last element by the time that onBeginContact handler runs. It has more to do with JavaScript closures than it does with anything Phaser-specific. You *probably* need something that looks more like this:

function createBeginContactHandlerFor(child) {
  return function() {
    removeCoin(child);
  }
}

//Loop through the group
for (var i = 0; i < coins.length; i++) {
   //Get each child form the group
   child = coins.children[i];
   //Check for each child whether you are beginning a contact
   child.body.onBeginContact.add(createBeginContactHandlerFor(child), this);
}

See how the outer function, "createBeginContactHandlerFor", takes the child as an argument? That "closes" the inner function over the variable "child", so it's value will be what you expect. Read more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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