Menu

Box2D Game Objects Part 2

In Part 2 of this series, we look at the Body component for AGE.

The primary purpose for this GO is to handle the box2d bookkeeping for Body instances, map that information to its drawable resources, and provide an abstract base class for more complicated objects.

In here we set up some more infrastructure by way of an abstract class:

  • Implement the filter flags for the World filter methods. This is a public field because it gets accessed a lot.
  • Add a passive flag so subclasses can control how force acts upon them.
  • Add a marker interface UnderForce for subclasses to signal the World they want forces applied. This is then further controlled by passive flag.
  • Put in the bare minimum box2d resource acquisition. The simplest object in box2d needs a BodyDef and a Body.

Notice how none of this has to do with the visual rendering, that's for DrawableGameObject!

Let's get started!

public abstract class Box2DBody extends DrawableGameObject {
protected Body body;
protected BodyDef bd;
protected boolean passive;
public int filterFlags;
public Box2DBody(String name, Geometry model, int depth) {
    super(name, true, model, depth);
    set(Constants.Property.TRANSFORM, new Transform());
}

These are the box2d configuration methods.

protected abstract void configureBodyDef(BodyDef bd);
protected abstract void configureBody(Body bd);

These are some convenience methods.

public boolean isPassive() { return passive; }
public void setPassive(boolean passive) { this.passive = passive; }
public boolean isBody(Body bd) { return bd == body; }
public float getInertia() { return body == null ? 0f : body.getInertia(); }

The sync method handles setting up the Transform property from the current values computed by the World update (see Part 1).

The Transform.scale is not adjusted. Subclasses are expected to set the scale appropriately based on other properties, e.g. Radius or HalfDimension or you can use "actual size" Geometry.

public void sync() {
    if (body != null) {
        final Vec2 wc = body.getWorldCenter();
        final Transform tx = getAs(Constants.Property.TRANSFORM);
        tx.tx = wc.x;
        tx.ty = wc.y;
        tx.rz = (float) Math.toDegrees(body.getAngle());
        set(Constants.Property.TRANSFORM, tx);
    }
}

The unload method handles the bookkeeping associated with removing an object from box2d. The bodymap is a parameter, because it is possible that a GO can have composite geometry in box2d.

The World calls this method during its BoundaryListener.violated method. The World does not call this during UnloadCallback because it is possible to recycle these GOs.

public void unload(Box2DWorld world, HashMap<Body, Box2DBody> bodymap) {
    final Body prev = this.body;
    if (prev != null) {
        prev.setUserData(null);
        world.destroyBody(prev);
        body = null;
        bodymap.remove(prev);
    }
}

The reload method handles re-initializing box2d resources for the GO. This requires less work than initial loading, since BodyDef was already set up.

public void reload(Box2DWorld world, HashMap<Body, Box2DBody> bodymap) {
    final Body prev = this.body;
    if(prev != null) {
        prev.setUserData(null);
        world.destroyBody(prev);
        this.body = null;
        bodymap.remove(prev);
    }
    final Body bx = world.createBody(bd);
    if (bx != null) {
        // createBody() can fail!
        configureBody(bx);
        bx.setUserData(this);
        bodymap.put(bx, this);
    }
    this.body = bx;
}

The load method handles the initial loading of box2d resources.

The World calls this method during its LoadedCallback.

public void load(Box2DWorld world, HashMap<Body, Box2DBody> bodymap) {
    bd = new BodyDef();
    configureBodyDef(bd);
    final Body bx = world.createBody(bd);
    if(bx != null) {
        // createBody() can fail!
        configureBody(bx);
        bx.setUserData(this);
        bodymap.put(bx, this);
    }
    this.body = bx;
}
}
Posted by g-dollar 2013-06-05

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.