0
votes

I am developing a game in Libgdx and I am working on collision detection between two bodies in box 2D. I used "Contact Listener" to detect collision but nothing happens when the bodies collide.

This is my code

  public Player(World world,float x,float y,float width)
  {
   this.width=width; //IMP
   height=width*2;
   BodyDef polygon=new BodyDef();
   polygon.type=BodyType.DynamicBody;
   polygon.position.set(x,y); //

   polygon.fixedRotation=true;
   PolygonShape poly =new PolygonShape();
   poly.setAsBox(width/2,height/2); //
  //fixture defn
  polygon.position.set(5,4);
  FixtureDef polyfixture=new FixtureDef();
  polyfixture.shape=poly;

  polyfixture.friction=0.8f;  //
  polyfixture.restitution=0.1f; //
  polyfixture.density=3; //


  //creating actual body
  polybody=world.createBody(polygon);
  polybody.createFixture(polyfixture);


  polysprite=new Sprite(new Texture("img/car.jpg"));

  polysprite.setSize(2, 3); //size of mario
  polysprite.setOrigin(polysprite.getWidth()/2, polysprite.getHeight()/2);
  polybody.setUserData(polysprite);

2nd body

   BodyDef polygons=new BodyDef();
   polygons.type=BodyType.DynamicBody;

   PolygonShape polys=new PolygonShape();
   polys.setAsBox(2,2);

   FixtureDef polyxfixture=new FixtureDef();
   polyxfixture.shape=polys;
   polyxfixture.friction=0.8f;
   polyxfixture.restitution=0.1f;
   polyxfixture.density=3;
   polybodys=world.createBody(polygons);
   polybodys.createFixture(polyxfixture);
   poly.dispose();    
   }
   @Override
    public void beginContact(Contact contact) {
// TODO Auto-generated method stub

Fixture fixtureA=contact.getFixtureA();
Fixture fixtureB=contact.getFixtureB();

if(fixtureA.getUserData() != null && fixtureA.getUserData().equals("polybody") &&
        fixtureB.getUserData() !=null && fixtureB.getUserData().equals("polybodys")){
    Gdx.app.log("Contact","1");
    System.out.println("its colliding");

}

if(fixtureB.getUserData() !=null && fixtureB.getUserData().equals("polybody") &&
        fixtureA.getUserData() !=null && fixtureA.getUserData().equals("polybodys"))
{
    System.out.println("its colliding");
}
}

I have added world.setContactListener(player); also where "player" is the name of above class.

This is my code for detecting collision. When I run the code and test for collision between bodies nothing happens. I tested using "println" statement in console. I don't know which is wrong here. Please help. Thanks in advance !!

1
When you're checking user data 1) you should be using .equals() for string comparing, and 2) should they both be "polybody" and not "polybodys"? I also don't see any point at which you set user data to be "polybody" so there is no way it would evaluate to True.Samich
Thanks a lot. I just tried it up because I don't know how to use getBody()and getUserData() correctly. What am I supposed to do to detect collision between two bodies(Polybody and Polyboyds) @SamichAnusha
I responded to a question, much like I think you can help stackoverflow.com/questions/27388199/…Angel Angel
@AngelAngel responded with basically the exact code I was going to write. That is the correct approach.Samich
I have tried as per the code in the link you gave but it still is not working.. I have added world.setContactListener(player); in the place where I created the world ,where "player" is the instance of the class "Player" .See my updated code above@AngelAngelAnusha

1 Answers

0
votes

I think the link reponde a way to do what you want, maybe it is not the best way but it can help the other hand I will try to adapt it to code your samples, but not if it worked because not complete, and is somewhat confusing to me

your code with changes:

public Player(World world,float x,float y,float width){

   this.width = width; 
   height     =width*2;

   BodyDef polygon = new BodyDef();
   polygon.type    = BodyType.DynamicBody;

   polygon.position.set(x,y); //<-- you use position one
   polygon.fixedRotation = true;

   PolygonShape poly = new PolygonShape();
                poly.setAsBox(width/2,height/2); 

  //fixture defn

  polygon.position.set(5,4);   //<-- you use position two, twice, 
                               //this overrides the previous consider this

  FixtureDef polyfixture = new FixtureDef();
             polyfixture.shape = poly;

  polyfixture.friction    = 0.8f;  
  polyfixture.restitution = 0.1f; 
  polyfixture.density     = 3; 

  //creating actual body
  polybody = world.createBody(polygon);

  //add.setUserData("YourBody1Name");
  // polybody.createFixture(polyfixture); <-- this original code
  // change for example:
  polybody.createFixture(polyfixture).setUserData("YourBody1"); 

  polysprite = new Sprite(new Texture("img/car.jpg"));

  polysprite.setSize(2, 3); //size of mario
  polysprite.setOrigin(polysprite.getWidth()/2, polysprite.getHeight()/2);

2nd body <-- you are creating two body, inside the player class, that is your intention?

   BodyDef polygons = new BodyDef();
           polygons.type = BodyType.DynamicBody;

   //you do not use it for poligons position?
   //for example:
   //polygons.position.set(yourPosX,yourPosY); 

   PolygonShape polys = new PolygonShape();
                polys.setAsBox(2,2);

   FixtureDef polyxfixture = new FixtureDef();
              polyxfixture.shape       = polys;
              polyxfixture.friction    = 0.8f;
              polyxfixture.restitution = 0.1f;
              polyxfixture.density     = 3;

   polybodys = world.createBody(polygons);

  //add.setUserData("YourBody2Name");
  // polybodys.createFixture(polyxfixture); <-- this original code
  // change for example:
   polybodys.createFixture(polyxfixture).setUserData("YourBody2"); 

   poly.dispose(); 
   //polys.dispose(); //<-- I do not see this dispose in your code. 

   }

now in class where you create the World. copy this code:

private class CrearContactListener implements ContactListener {

        public CrearContactListener(){

        }
        @Override
        public void preSolve(Contact contact, Manifold oldManifold) {
            // TODO Auto-generated method stub

        }

        @Override
        public void postSolve(Contact contact, ContactImpulse impulse) {
            // TODO Auto-generated method stub

        }

        @Override
        public void endContact(Contact contact) {
            // TODO Auto-generated method stub

        }

        @Override
        public void beginContact(Contact contact) {
            // TODO Auto-generated method stub

            Fixture fixtureA = contact.getFixtureA();
            Fixture fixtureB = contact.getFixtureB();

            if(fixtureA.getUserData() != null 
               && fixtureA.getUserData().equals("YourBody1") 
               && fixtureB.getUserData() != null 
               && fixtureB.getUserData().equals("YourBody2")){

                Gdx.app.log("Contact","1");
            }

            if(fixtureB.getUserData() != null 
               && fixtureB.getUserData().equals("YourBody1")
               && fixtureA.getUserData() != null 
               && fixtureA.getUserData().equals("YourBody2")){

                Gdx.app.log("Contact","2");
            }
        }
}

Note that is a private class, you must place it in a suitable location for the class, you do not know where find some information on how to use private class inside an other class more.

and use this code to assign the ContactListener:

YourWorld.setContactListener(new CrearContactListener());

in the body 2 look what position, it may be necessary one.

in this example, delete the implemetation of public void beginContact (Contact contact) in your class player one reason for this is that I do not know if your player class implements ContactListener or simply you put it there.

I eh this code not tested, but I think it could work, considering what you mentioned, on the other hand, apologize for my English and I hope you understand me.