Developer experiences from the trenches
There are two ways to really beat something up in a physical game: first, throw the object against the wall and, second, toss a heavy boulder on top of the object. The former can be thought of as impact damage. The velocity of the two objects colliding determines the magnitude of the impact.
The second is more challenging to get right. This iscrush damage. It takes some processing to determine when something is crushed and how badly it is crushed.
In some games, you have a crushing ceiling that descends slowly and squeezes players into the ground. Let’s take this simple example as a starting point and work from there: the crushing ceiling descends on the player. As the crushing ceiling pushes the player further into the floor, the player starts losing health and dying.
That’s great, but what happens in a more complicated simulation with rigid bodies that can roll out of the way? Perhaps a heavy block falls on an object, but the object squeezes out to the left. Sure, the big block penetrated your ball for a single frame, but this was quickly resolved by the physics solver by applying an impulse at to the proper point on the ball. You can’t simply tag the ball as crushed and respond with death in your game code.
The rest of this tutorial looks at addressing this problem with Box2D. Box2D is remarkably stable when dealing with significant mass ratio differences.
One way of solving this is to look at how long two fixtures (components of rigid bodies) stay interpenetrated and to apply damage when a time threshold has been reached. The assumption is that the solver does a great job of applying impulses to separate the two bodies, so when they fail, it’s a sign that there is not enough space for them to coexist. This is encroachment, and if it endures for a period of time, one of the encroaching objects is crushing the other one.
Let’s recap what we want out of production quality crush detection, and then we’ll get into an implementation you can build from.
So, that’s what we want. In the second part, we’ll get our hands dirty with some source code.