Box2D and Joints for JavaScript

Sponsor: Register today for New Game, the conference for HTML5 game developers. Learn from Mozilla, Opera, Google, Spil, Bocoup, Mandreel, Subsonic, Gamesalad, EA, Zynga, and others at this intimate and technically rich conference. Join us for two days of content from developers building HTML5 games today. Nov 1-2, 2011 in San Francisco. Register now!




Intro

Previously we looked at complex bodies with multiple shapes for Box2D. Using those techniques, we learned how to build concave bodies by associating two or more shapes to a body.

Another way to build more complex objects is to bind bodies together with joints. Joints constrain bodies together, for example by restricting ranges of motion or affecting motion of one body from another. Box2D supports many different types of joints, including pullings, gears, and ropes.

Box2D 2.1a (the version we've been using for all of these tutorials and demos) supports the following joint definitions:

  • Distance
  • Friction
  • Gear
  • Line
  • Mouse
  • Prismatic
  • Pulley
  • Revolute
  • Weld
Box2D 2.2 (the latest at the time of this writing, yet not yet ported to JavaScript) also supports:
  • all of the above
  • Wheel
  • Rope
Example

Let's start with a "revolute joint" which sounds like a fancy way of saying a joint that allows two bodies to revolve around a shared point. The below screenshot shows a sloped ground with a simple two wheel object rolling down.


See the below live example:



Visit the stand alone example of wheel joints with Box2D and check out the source code.

Explanation

Joints bind two bodies. As with many of Box2D's APIs, it all begins with a definition. For example, let's look at the definition of a Revolute joint:

    var joint = new b2RevoluteJointDef();
    joint.Initialize(body1, body2, body1.GetWorldCenter());
    this.world.CreateJoint(joint);

You can see the joint works with Bodies (not shapes or fixtures). The joint is created by the Box2D world.

Really weird stuff starts to happen when the anchor point for the joint is outside the body. And by really weird, I mean doesn't work. I've used the body.GetWorldCenter() to find the center of the body for the joint to bind to.

Notice that I'm only referencing the the center of one body. This is because a revolute joint specifies a single hinge point, and it assumes that the two bodies are already in the right position.

Revolute joints are quite configurable. Some examples of options for a revolute joint are:
  • enableLimit - whether the joint limits will be active
  • lowerAngle - angle for the lower limit
  • upperAngle - angle for the upper limit
  • enableMotor - whether the joint motor will be active, defaults to false
  • motorSpeed - the target speed of the joint motor. Positive for counter clockwise, negative for clockwise
  • maxMotorTorque - the maximum allowable torque the motor can use. A torque too weak won't be able to move the bodies.
Self powered

Using the motorSpeed and the maxMotorTorque we can build a self powered car.

bTest.prototype.addRevoluteJoint = function(body1Id, body2Id, params) {
    var body1 = this.bodiesMap[body1Id];
    var body2 = this.bodiesMap[body2Id];
    var joint = new b2RevoluteJointDef();
    joint.Initialize(body1, body2, body1.GetWorldCenter());
    if (params && params.motorSpeed) {
      joint.motorSpeed = params.motorSpeed;
      joint.maxMotorTorque = params.maxMotorTorque;
      joint.enableMotor = true;
    }
    this.world.CreateJoint(joint);
}


To show off this awesome hotrod, we'll flatten the ground and let her rip!




You can control the direction of the motor with the motorSpeed. A positive motorSpeed will travel counter-clockwise and a negative speed will travel clockwise (as seen above). The maxMotorTorque needs to be high enough to actually move your bodies.


Summary

Box2D joints bind two bodies together. Box2D has numerous joints like revolute, distance, and pulleys. Many joints have attributes like motor speeds, upper and lower angle bounds, and torque.

For more information on Box2D joints, the manual has examples and explanations of all the joint types. For more information on revolute joints specifically, I found this Box2d Revolute Joints tutorial helpful.

Next Up

Add some excitement to your Box2D simulations with Impulse.

Popular posts from this blog

Lists and arrays in Dart

Converting Array to List in Scala

Null-aware operators in Dart