Oh fiddlesticks
Something's gone wrong here. Try again and see if it works, if it doesn't you're allowed to shout at me.

Using Box2D as a collision system

Posted: September 2nd, 2012

In my new tower defence project I need to know when certain things are touching, or when object A is within range of object B, and other nonsenses like that. It seems perverse now, but the first time I had to implement collision code a few years ago I didn’t know why the computer couldn’t TELL there was a collision: The blue circle is halfway-inside the red square, surely that’s obvious? But implement I did, and it was horrible and rough, but for that project it didn’t matter at all.

In the early days of this project I implemented a collision system again with just two shape types: Rectangle and circle. It worked well enough, but the performance was awful — I had time to knock together a few arrays and an update loop, but more advanced stuff like knowing which objects could be safely ignored to speed the whole process up takes time to write and test. Having experience with it previously, I ran back to Box2D, dropping the source in to my project so I could begin prodding.


As it turns out, disabling the actual physics simulation bit of Box2D and just notifying objects of collisions is pretty easy… In fact, if you stumble upon the right comment in the right class, it’s written right there for you…

 

 

All the work you need to do is in box2d.dynamics.B2ContactListener. The first two functions, beginContact and endContact, are where you’ll want to notify your game objects of the start and end of collisions. Box2D only executes these functions once (not every frame the collision is occuring), so develop accordingly. The third function, preSolve, is where that comment comes from, and is where we’ll disable all further processing. To make this work I also had to add a reference to the parent sprite to each B2Body so we know what to contact. My code is as follows:

 

 

As you can see, my recieving functions in the sprites take the B2Contact object as their parameter since it already contains all the data they need, so to make everything a bit easier on the other end I added a few methods to box2d.contacts.B2Contact to retrieve the “other” sprite, body and shape.

 

 

Presto, I hope that helps someone someday 🙂
– B