Jump to content

Box2D plugin - How to reset the x,y of a body when it hits an object?


tonky
 Share

Recommended Posts

I am trying to reset the position of a body when it hits an object/ground. 

I had already achieved this successfully in p2 but for some reason, body.x and body.y wont alter in box2d. 

Heres the relevant code.           
    this.physics.startSystem(Phaser.Physics.BOX2D);
    this.physics.box2d.gravity.y = 500; // large gravity to make scene feel smaller
    this.physics.box2d.friction = 0.8;
    this.physics.box2d.setBoundsToWorld();

      
    var rockResetTriggerVertices = [
        13000,188,
        13500,288,
    ];

    // Make the ground body
    var rockResetTrigger = new Phaser.Physics.Box2D.Body(this.game, null, 0, 0, 0);
    rockResetTrigger.setChain(rockResetTriggerVertices);
      
    // ROCKS
    this.rocks1 = this.game.add.group();
    this.rocks1.enableBody = true;
    this.rocks1.physicsBodyType = Phaser.Physics.BOX2D;

    this.rockg1 = this.rocks1.create(this.game.width*16.5, 100, 'rock3');

    for(var i = 0; i < this.rocks1.children.length; i++){        
            this.rocks1.children[i].body.setRectangle(50, 50);
//            this.rocks1.children[i].body.kinematic = true;
            this.rocks1.children[i].body.dynamic = true;
            this.rocks1.children[i].body.setBodyContactCallback(rockResetTrigger, this.rockReset, this);
    }

    rockReset: function(body1, body2, fixture1, fixture2, begin){
//        a.reset(this.game.width*16.5, 10);
        body1.x = this.game.width*16.5;
        body1.y = 10;
        console.log(body1);
    }

 


You can see it in action at phaser.site44.com

Link to comment
Share on other sites

Hi, it is not good idea to change physics objects (move, destroy, ...) in callbacks, because it is in the middle of physics world calculations. I think, that in past objects were locked during physics step and it looks it is still valid (not sure, but your results looks like it).

Add two variables into your class:

    resetRock: false,
    rockBody: null,

then in callback just READ colision:

    rockReset: function(body1, body2, fixture1, fixture2, begin){
        this.resetRock = true;
        this.rockBody = body1;

        console.log(body1);
	},

...and in update process what you read:

  update: function () {
      if (this.resetRock) {
          this.resetRock = false;

          this.rockBody.x = this.game.width * 16.5;
          this.rockBody.y = 10;
      }

 

Link to comment
Share on other sites

Hi Tomas. Thanks again for helping me, but the thing is, I want a rain of rocks/obstacles - not just one rock. And I can only reset a rocks position once that rock touches the ground. I dont want to reset all the rocks when one touches the ground. 

Link to comment
Share on other sites

Also Tomas, is there a cleaner way whereby I can destroy or kill a physics body and its sprite in the callback? 

For example, 

    this.ballBody.body.setBodyContactCallback(this.truck, this.collectableFunc, this);
    collectableFunc: function(a, b){
//        var item = a.sprite;
//        item.kill();
//        a.destroy();
//        a.sprite.kill();
    },

lol, either the body stays or the sprite. I want to remove both as cleanly as possible. 

Link to comment
Share on other sites

No, do not do any changes in box2D callbacks. What I do is, that I add some property to sprite - like "toBeDestroyed" and in update I check if sprite is marked for destruction.

If you want to avoid iteration, then create something like the stack as in my previous answer. You can just kill/destroy everything, what is on stack.

This is from Box2D manual:

Quote

It is tempting to implement game logic that alters the physics world inside a contact callback. For
example, you may have a collision that applies damage and try to destroy the associated actor and its
rigid body. However, Box2D does not allow you to alter the physics world inside a callback because you
might destroy objects that Box2D is currently processing, leading to orphaned pointers.

 

... and yes, almost forgot - from plugin manual. To destroy sprite and body:

Quote

However, if you created the body from a sprite, in most cases you will want to destroy the
sprite and the body together, which you can do like:

mySprite.destroy();

Phaser plugin is doing a lot of stuff for you. If you were not using it you would have to take care for sprite and body destruction in two steps by yourself...
 

Link to comment
Share on other sites

Morning Tom. I did what you advised and I did think you were right but have a look at this. Stacking body.sprite and then destroying it in update, gives me an error "Uncaught TypeError: Cannot read property 'destroy' of null". I am making sure that I am stacking the sprite and not just the body. If I stack just the body, then it gets removed without errors as expected but the body-less sprite gets left behind obv. 

Have a look yourself. http://phaser.site44.com/

 

 

Link to comment
Share on other sites

Hi, your contact callback is called alwasy twice: when contact begins and when it ends. So, if you destroy body after first call (when contact begin), then when contact end, body is already destroyed and you get error.

It only looks like body is not destoryed, because game stops before debug draw is redrawn

So, to make things work:

1] make sure, you are clearing your array (setting to 0, assigning [], splicing, ... http://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript):

    update: function () {
        if (this.collectedArray.length !== 0) {

            this.collectedArray.forEach(function (item) {
                console.log("destory");
                item.destroy();
            });

            // clearing...
            this.collectedArray.length = 0;
        }

2] adjust your callback to listen only when contact begins:

    collectableFunc: function (a, b, f1, f2, begin) {
        if (!begin) {
            return;
        }

        this.collectedArray.push(a.sprite);
    },

btw - examples comming with Box2D plugin are really great. I went through them and it covers everything you need in box2D. For this, I was stuck at first, but then I looked into "Contact Callbacks" example and it reminded me about calling twice (begin / end)

 

Link to comment
Share on other sites

Makes sense now. Finally, am getting comfortable with box2d now and getting to know it better thanks to you and you alone. I downloaded your game btw and will send u a pm over the weekend on your monetary numbers as I have been doing a lot of research on monitizing games and ads. ThinkGaming is a very helpful site but your blog is amazing. Thank you for being such a helpful person. 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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