I am making an Angry Birds like game for my project. Most of the things are done except the most basic: giving a realistic feel in game physics. The part I am struggling with the most is damage. I am using libgdx which provides a wrapper around Box2d so the code should not be alien to anybody who knows Box2d. This is the postSolve method
@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
float[] forces = impulse.getNormalImpulses();
int index1 = (Integer) contact.getFixtureA().getBody().getUserData();
int index2 = (Integer) contact.getFixtureB().getBody().getUserData();
if( forces[0] > 0.3 )
bodies.get(index1).handleCollision(forces[0]);
if( forces[1] > 0.3 )
bodies.get(index2).handleCollision(forces[1]);
}
This pulls out the bodies that are colliding and passes to them the normal collision impulses so that they can handle damage. Now this is the damage handler function of one of the bodies
@Override
public void handleCollision(float impulse) {
health -= impulse;
else if( health < 50 )
isFlaggedForDelete = true;
}
I give health values to all bodies based on their sizes initially and they are supposed to get damaged accordingly each time a strong enough collision happens.
The problem is that the bodies are arranged in a fashion shown in the image. Whenever even a slight collision happens at any of the blocks, which doesnt even make it move, the whole structure (I presume) starts to vibrate and the blocks down below are destroyed (because of health) and the whole structure falls down.

I have set the b2VelocityThreshold to a maximum value (further increasing it introduces bad behavior of bodies in the game). The postSolve method also sets a high enough threshold. What is wrong with my approach?
Thanks.
I think you are using the normalImpulses array incorrectly here. Although this array is always two elements long, it only holds as many valid values as there are points in the collision manifold, which can often be just one. The impulse values it holds are not for bodyA and bodyB, they are for the points of the manifold.
To get a correct value for how 'heavy' the collision is you would need to check how many collision points actually exist for the collision, and if there are two then you could take the average of the impulses, or the maximum maybe.
I say 'heavy' rather than 'damaging' because these impulses will be higher for heavier bodies even if the speed of impact does not change. PreSolve happens every frame for all contacting bodies, so even if you have two bodies sitting almost motionless, one on top of the other, you will still get a large normalImpulse if the bodies are heavy. I guess you would need to take the mass of the bodies involved into account before deciding that a collision was damaging or not.
PostSolve is called every frame while two fixtures are touching, unless their bodies are asleep. When you say the whole structure gets damaged by vibration, I would guess it's just that the bodies are sleeping until part of their structure is bumped, and all of the PostSolve suddenly start adding up.
If I was you I would set up a much simpler scene, say with just one body sitting on the ground, and drop another body on it. Look at the values of normalImpulse you get from that until the bodies sleep. Change their masses, change the drop height etc and do it again to see how the normalImpulse values are affected. This should give you an idea of what kind of threshold values to use when deciding if a collision is causing damage, or is simply the result of bodies sitting on top of each other.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With