Removing bodies in Box2D

Hello, today I bring you another lesson learnt.

When you choose Haxe for a project there are a few 2D physics engines available, mostly ports of other popular engines like Box2D. There are actually a few distinct ports to Haxe of various versions of B2D, but the most up-to-date and the one I’ve been using is Joshua Granick’s port of 2.1a. You can get it from Haxelib by opening a command prompt / terminal and running “haxelib install box2d”

In brief, it’s fantastic. Once you get a handle on how it works and where all the bits you want to use are it’s pretty simple, a far cry from the engine I initially experimented with – Physaxe – which was basically 20 pages of pure maths disguised as classes and functions! But there are some small issues I’ve run across while using it, and here comes the latest.


As we’ve discussed previously my project runs in two threads, and Box2D is updated from the second worker thread. I’m not sure if that’s contributed something to this problem, or if it’s just odd coincidence. Since I’m building a “Tower Defence” game I’m basically using B2D as a collision system, I’ve disabled all the collision response code that would usually make objects bounce/push out of each other and instead just report the start and end of collisions to the objects concerned. In particular, of course, I have enemies and bullets, and the two must meet fairly regularly and be destroyed fairly regularly.

The physics debug display of my game project, Tower Defence.

Herein lies the problem, no matter what I did I couldn’t get B2D to remove the physics body of an enemy after they’d been destroyed.

The enemy sprite vanished, but the collision system still sees it, and the gun keeps firing at nothing. Initially I thought I must always be hitting the B2World.destroyBody method while the B2World was being updated (and thus, is locked), so I added some code to the destroyBody method to store any objects arriving during a lock in an array, and then remove them at the very start of B2World.step.

public function destroyBody(b:B2Body):Void { 
  if (isLocked() == true) { 
    this.bodiesToRemove.push(b);
    return;
  }
  etc...
}

public function step(dt:Float, velocityIterations:Int, positionIterations:Int):Void {
  foreach (b in this.bodiesToRemove) this.destroyBody(b); 
  etc...
}

This didn’t do anything, which surprised me. Other bodies are removed fine — I can already create a weapon and destroy it, and the body goes too.

I turned to Google, as we all do in times of need, knowing I’d already looked through a few pages of results on the subject and found nothing that useful. This time however, I got something to work.

The chosen answer to this question is what worked — set a property in the body object and iterate over them seperate to the main step loop. In my implementation, I set the m_userData variable of B2Body (since I don’t use it for anything else) and just run a short function immediatly after B2World.step which I called B2World.destroyBodyQueue. If m_userData is true, we kill the object.

public function destroyBodyQueue() {
  var b:B2Body = m_bodyList;
  while (b != null) {
    if (b.getUserData()==true) {
      b = b.m_next;
      this.destroyBody(b.m_prev);
      continue;
    }
    b = b.m_next;
  }
}

Easy!