Problem with foot sensor, in some cases it does

Discuss issues specific the Java port of Box2D
gb99pm10
Posts: 2
Joined: Sat May 16, 2015 4:33 am

Problem with foot sensor, in some cases it does

Postby gb99pm10 » Sat Jun 13, 2015 6:15 am

Good morning.
To detect if the character in my platform game can jump, i added a sensor to his feet. I loaded a rectangle from Tiled and using the MapObject properties i set it to be a sensor. I wrote the Sensor class and i passed it to the Sensor constructor. The Sensor class has 2 method called by my ContactListener implementation. This is my simple class:

Code: Select all

import java.util.ArrayList;

import com.badlogic.gdx.maps.MapProperties;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.Fixture;



public class Sensor {
   private Fixture sensorFixture;
        // it's a list of all bodies wich currently are in the sensor
   private ArrayList<Body> detectedBodies = new ArrayList<Body>();
   private String id;
   
   public Sensor(Fixture sensorFixture)
   {
            //ignore all this, i use the MapProperties to load automatically the sensor using reflection

      this.sensorFixture = sensorFixture;
      if(((MapProperties)sensorFixture.getUserData()).containsKey("Name"))
         id = ((MapProperties)sensorFixture.getUserData()).get("Name", String.class);
      else System.out.println("There isn't the Name property in a sensor");
      
              //the userData is an instance of the class Sensor, so i can use it in ContactListener
      this.sensorFixture.setUserData(this);
   }

        //it's called when a body "enter" in the sensor (the beginContact in ContactListener )
   public void onCollisionEnter(Body colliderBody)
   {
                //if the body is already in the list, then i don't need to store it again
      if(!detectedBodies.contains(colliderBody))
      {
         System.out.println("i'm adding the body to my List!");
         detectedBodies.add(colliderBody);
      }
      System.out.println("this is my collection: " + detectedBodies);
   }
        //it's called when a body "exit" from the sensor (the endContact in ContactListener )
   public void onCollisionExit(Body colliderBody)
   {
                detectedBodies.remove(colliderBody);
      System.out.println("i'm REMOVING the body to my List!");
   }
   public ArrayList<Body> getDetectedBodies()
   {
      return detectedBodies;
   }
   public String getId(){return id;}
   
}


After that i'm using a class which "listen to this sensor" and will write on an ObjectMap, which is like a HashMap, the key "GROUNDED" and the value "true" if there is a body in the sensor, else the value will be "false".

I post there the Listener class, but the problem isn't here:

Code: Select all

import com.EscapeHeroe.helpers.Sensor;
import com.EscapeHeroe.helpers.SensorCallback;
import com.EscapeHeroe.helpers.SensorListener;

public class JumpListener implements SensorListener{

   private SensorCallback sensorCallback;
   private Sensor sensor;
   public JumpListener(Sensor sensor, SensorCallback sensorCallback)
   {
      this.sensor = sensor;
      this.sensorCallback = sensorCallback;
      this.sensorCallback.add("GROUNDED", false);
   }
   @Override
   public void listenSensor() {
      
      
      if(!sensor.getDetectedBodies().isEmpty())
      {
         sensorCallback.set("GROUNDED", true);
      }
      else
      {
         sensorCallback.set("GROUNDED", false);
      }
   }
}


finally I add the ContactListener implementation:

Code: Select all

import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.ContactImpulse;
import com.badlogic.gdx.physics.box2d.ContactListener;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.Manifold;

public class CustomContactListener implements ContactListener {

   @Override
   public void beginContact(Contact contact) {
      
      Fixture a = contact.getFixtureA();
      Fixture b = contact.getFixtureB();
      if(a.isSensor() && !b.isSensor())
         ((Sensor)a.getUserData()).onCollisionEnter(b.getBody());
      else if(!a.isSensor() && b.isSensor())
         ((Sensor)b.getUserData()).onCollisionEnter(a.getBody());
      
   }

   @Override
   public void endContact(Contact contact) {
      Fixture a = contact.getFixtureA();
      Fixture b = contact.getFixtureB();
      if(a.isSensor() && !b.isSensor())
         ((Sensor)a.getUserData()).onCollisionExit(b.getBody());
      else if(!a.isSensor() && b.isSensor())
         ((Sensor)b.getUserData()).onCollisionExit(a.getBody());
   }

   @Override
   public void preSolve(Contact contact, Manifold oldManifold) {
      
      
   }

   @Override
   public void postSolve(Contact contact, ContactImpulse impulse) {
      
      
   }
}


All works perfectly, but there is a bug.
i explaned it here http://s15.postimg.org/8lg86vi9n/super_ ... 4qb7i2.jpg

Pratically in that particular situation, the sensor removes the platform from the detected bodies and it doesn't add the platform anymore, so the player can't jump.

I know the problem is a bit confusing, but i couldn't explain it better, and sorry form my poor english, i'm 15 and i'm not english so my language is quite poor...

Thanks a lot just because you have read all this mess :lol:

gb99pm10
Posts: 2
Joined: Sat May 16, 2015 4:33 am

Re: Problem with foot sensor, in some cases it does

Postby gb99pm10 » Sat Jun 13, 2015 3:25 pm

Thanks for reading. I understood what is the problem and i post it for people who will need it.
Imagine a rectangle which is a sensor... we will have a top corner and a down corner. Imagine that the sensor is falling down in a body. When the down corner enters the body there will be the beginContact call, when the top corner enters the body there will be the endContact call; when the down corner exit from the body there will be another beginContact call and when the top corner exit the body there will be the endContact call again. In my case the sensor first entered with a corner to the platform, then when the character was sliding to the right, another corner entered in the platform causing the endContact call, so the sensor thought that there wasn't any body inside him... that was the bug.

Thanks to the people who read the post. Hope it helped!


Return to “Java”



Who is online

Users browsing this forum: Google [Bot] and 1 guest