Greetings stackoverflow community!
I am working on an Android game that uses Box2D for collision detection and physics. Right now, I’m implementing a basic platformer system. Jumping is in place, but it has a small glitch. The following function is meant to determine if a player is on the ground. Simple, right? Well, it works okay, unless the player is right next to a wall, in which case it’ll just let him constantly jump up, as the function will still return true, even if the wall isn’t directly below the player.
I have tried adding additional x-checks to make sure that I’m colliding with something that’s directly under me, but to no avail.
private boolean isGrounded(float deltaTime) {
List<Contact> contactList = world.getContactList();
for(int i = 0; i < contactList.size(); i++) {
Contact contact = contactList.get(i);
if(contact.isTouching() && (contact.getFixtureA() == sensorFixture ||
contact.getFixtureB() == sensorFixture)) {
Vector2 pos = body.getPosition();
WorldManifold manifold = contact.getWorldManifold();
boolean below = true;
Vector2 cpoint;
for(int j = 0; j < manifold.getNumberOfContactPoints(); j++) {
cpoint = manifold.getPoints()[j];
below &= (
(cpoint.y < pos.y - 0.15f)
&& (cpoint.x > pos.x - w/2 + 3f)
&& (cpoint.x < pos.x + w/2 - 3f)
);
if(below) return true;
}
return false;
}
}
return false;
}
So, does anyone have any pointers towards what I could do to make the isGrounded check more efficient?
Thanks in advance! 🙂
I’m not familiar with Box2d, but my first thought would be to check the orientation of the object you are in contact with. A quick check of the documentation will tell you that WorldManifold has a getNormal which provides a local normal that points from fixtureA to fixtureB. From there you compare the orientation to the X-axis or Y-axis using a dot product. Then you can threshold how steep a surface you want to let the player be able to jump on. You may need to convert the local normal to world space.
Sources: