Jump to content

Box2d contact


Vishal Gupta
 Share

Recommended Posts

Hi

I am using phaser box2d plugin and using setBodyContactCallback for getting call back when body touch how can i get the touching point x and y so that i can play some animation there.

The call back params are body1 body2 fixture1 fixture2 callback

 

Link to comment
Share on other sites

Hi, callback params are these: (body1, body2, fixture1, fixture2, begin, contact). Below is my code that in callback calls method for calculating contact point. It is in separate method to use it from various callbacks. Settings.PTM is my setting for Box2D PTM ratio (points to meters - default is 50 in plugin).

 Point of contact is stored in _hitPoint. I do not do any expensive operations in callback, so I just store it and process later.

        //------------------------------------------------------------------------
        public onCollisionBall(body1: Phaser.Physics.Box2D.Body, body2: Phaser.Physics.Box2D.Body,
            fixture1: box2d.b2Fixture, fixture2: box2d.b2Fixture, begin: boolean, contact: box2d.b2Contact): void {
                                    
            // This callback is also called for EndContact events, which we are not interested in.
            if (!begin) {
                return;
            }

            this.calcContactPoint(contact, this._hitPoint);
        }


        //------------------------------------------------------------------------
        public calcContactPoint(contact: box2d.b2Contact, out: Phaser.Point): Phaser.Point {
            contact.GetWorldManifold(this._worldManifold);

            if (this._worldManifold.points.length > 0) {
                var point = this._worldManifold.points[0];
                out.set(-point.x * Settings.PTM, -point.y * Settings.PTM);

                //console.log("ball " + this.position + ", contact " + this._hitPoint);
            }

            return out;
        }

 

Link to comment
Share on other sites

10 hours ago, Tom Atom said:

Hi, callback params are these: (body1, body2, fixture1, fixture2, begin, contact). Below is my code that in callback calls method for calculating contact point. It is in separate method to use it from various callbacks. Settings.PTM is my setting for Box2D PTM ratio (points to meters - default is 50 in plugin).

 Point of contact is stored in _hitPoint. I do not do any expensive operations in callback, so I just store it and process later.


        //------------------------------------------------------------------------
        public onCollisionBall(body1: Phaser.Physics.Box2D.Body, body2: Phaser.Physics.Box2D.Body,
            fixture1: box2d.b2Fixture, fixture2: box2d.b2Fixture, begin: boolean, contact: box2d.b2Contact): void {
                                    
            // This callback is also called for EndContact events, which we are not interested in.
            if (!begin) {
                return;
            }

            this.calcContactPoint(contact, this._hitPoint);
        }


        //------------------------------------------------------------------------
        public calcContactPoint(contact: box2d.b2Contact, out: Phaser.Point): Phaser.Point {
            contact.GetWorldManifold(this._worldManifold);

            if (this._worldManifold.points.length > 0) {
                var point = this._worldManifold.points[0];
                out.set(-point.x * Settings.PTM, -point.y * Settings.PTM);

                //console.log("ball " + this.position + ", contact " + this._hitPoint);
            }

            return out;
        }

 

Thanks Tom i will try and let you know.

Link to comment
Share on other sites

On 7/6/2016 at 11:44 AM, Tom Atom said:

Hi, callback params are these: (body1, body2, fixture1, fixture2, begin, contact). Below is my code that in callback calls method for calculating contact point. It is in separate method to use it from various callbacks. Settings.PTM is my setting for Box2D PTM ratio (points to meters - default is 50 in plugin).

 Point of contact is stored in _hitPoint. I do not do any expensive operations in callback, so I just store it and process later.


        //------------------------------------------------------------------------
        public onCollisionBall(body1: Phaser.Physics.Box2D.Body, body2: Phaser.Physics.Box2D.Body,
            fixture1: box2d.b2Fixture, fixture2: box2d.b2Fixture, begin: boolean, contact: box2d.b2Contact): void {
                                    
            // This callback is also called for EndContact events, which we are not interested in.
            if (!begin) {
                return;
            }

            this.calcContactPoint(contact, this._hitPoint);
        }


        //------------------------------------------------------------------------
        public calcContactPoint(contact: box2d.b2Contact, out: Phaser.Point): Phaser.Point {
            contact.GetWorldManifold(this._worldManifold);

            if (this._worldManifold.points.length > 0) {
                var point = this._worldManifold.points[0];
                out.set(-point.x * Settings.PTM, -point.y * Settings.PTM);

                //console.log("ball " + this.position + ", contact " + this._hitPoint);
            }

            return out;
        }

 

Hi Tom,

i have tried this code but its not working i am having a circle inside a circle i have an object when they collide i needs the point of collide so that i can play animation on object touch the circle boundary.

 

 

Link to comment
Share on other sites

Hi,

 It should work... at least it works in my game, where I spawn particles in point of ball impact. So, lets go step by step:

1) get this basic box2D example: http://phaser.io/examples/v2/box2d/contact-callbacks
2) add new global variables:

var emitter;
var worldManifold;
var hitPoint;

3) in the end of create method add this:

    emitter = game.add.emitter(0, 0, 100);
    emitter.makeParticles('firstaid');
    emitter.minParticleScale = 0.25;
    emitter.maxParticleScale = 0.25;
    emitter.gravity = 0;
    
    worldManifold = new box2d.b2WorldManifold();
    hitPoint = new Phaser.Point();

 particle emitter is for visual feedback when hero hits enemy.
4) add this to enemyCallback after test for begin:

    contact.GetWorldManifold(worldManifold);

    if (worldManifold.points.length > 0) {
      var point = worldManifold.points[0];
      hitPoint.set(-point.x * game.physics.box2d.ptmRatio, -point.y * game.physics.box2d.ptmRatio);

      console.log("x = " + hitPoint.x + ", " + hitPoint.y);

      emitter.x = hitPoint.x;
      emitter.y = hitPoint.y;
      emitter.start(true, 2000, null, 10);
    }

 On picture below see small first aid kit particles emitted in point of contact between hero and enemy:

contact.png

 This method does not work when touching sensors. Try to move code added in step 4) into healthCallback. As First aid kits are sensors, you will get always point 0,0.

 If you have circle inside circle and your circles are modeled as box2d circles, then it is bad by design, because both circles are filled from box2D point of view and inner circle is always colliding with outer one in all its points. You have to model outer circle by aproximating it with polygon with empty inner (or box2D edge).

 

Link to comment
Share on other sites

23 minutes ago, Tom Atom said:

Hi,

 It should work... at least it works in my game, where I spawn particles in point of ball impact. So, lets go step by step:

1) get this basic box2D example: http://phaser.io/examples/v2/box2d/contact-callbacks
2) add new global variables:


var emitter;
var worldManifold;
var hitPoint;

3) in the end of create method add this:


    emitter = game.add.emitter(0, 0, 100);
    emitter.makeParticles('firstaid');
    emitter.minParticleScale = 0.25;
    emitter.maxParticleScale = 0.25;
    emitter.gravity = 0;
    
    worldManifold = new box2d.b2WorldManifold();
    hitPoint = new Phaser.Point();

 particle emitter is for visual feedback when hero hits enemy.
4) add this to enemyCallback after test for begin:


    contact.GetWorldManifold(worldManifold);

    if (worldManifold.points.length > 0) {
      var point = worldManifold.points[0];
      hitPoint.set(-point.x * game.physics.box2d.ptmRatio, -point.y * game.physics.box2d.ptmRatio);

      console.log("x = " + hitPoint.x + ", " + hitPoint.y);

      emitter.x = hitPoint.x;
      emitter.y = hitPoint.y;
      emitter.start(true, 2000, null, 10);
    }

 On picture below see small first aid kit particles emitted in point of contact between hero and enemy:

contact.png

 This method does not work when touching sensors. Try to move code added in step 4) into healthCallback. As First aid kits are sensors, you will get always point 0,0.

 If you have circle inside circle and your circles are modeled as box2d circles, then it is bad by design, because both circles are filled from box2D point of view and inner circle is always colliding with outer one in all its points. You have to model outer circle by aproximating it with polygon with empty inner (or box2D edge).

 

Thanks Tom its working great. thanks a ton :)

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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