Box2D, toxiclibs, rigid bodies, joints, and springs — letting a library handle the hard physics so you can focus on creativity.
In Chapters 1-4, we built physics from scratch: vectors, forces, particles. That was essential for understanding. But there are things we didn't handle: collisions between objects, rigid body rotation, constraints, joints, friction between surfaces.
These problems are hard. Collision detection alone is a deep field of computer science. Rather than implement it all ourselves, we can use a physics library — a tested, optimized engine that handles the math for us.
| Our hand-rolled physics | Physics library |
|---|---|
| Simple forces (gravity, wind) | Full rigid-body dynamics |
| No collision detection | Automatic collision detection and response |
| No constraints | Joints, springs, motors, pulleys |
| Full creative control | Must work within the library's rules |
| Easy to understand | More complex API |
Box2D is a 2D rigid-body physics engine originally written in C++ by Erin Catto. It's been used in thousands of games (Angry Birds, Limbo, etc.) and ported to virtually every language.
Box2D's key concepts:
| Concept | What it is |
|---|---|
| World | The container for all physics simulation. Handles gravity and time-stepping. |
| Body | An object in the world. Has position, angle, velocity. Three types: static, dynamic, kinematic. |
| Shape | The geometry attached to a body: circle, polygon, edge. |
| Fixture | Connects a shape to a body with physical properties: density, friction, restitution (bounciness). |
| Joint | A constraint connecting two bodies: revolute, distance, prismatic, pulley, gear. |
Everything in Box2D lives inside a World object. You create the world, set gravity, and then step it forward in time each frame.
pseudocode world = new World(gravity: (0, 10)) each frame: world.step(timeStep, velocityIterations, positionIterations) # world updates all bodies automatically # we just query their positions and draw
Box2D uses its own coordinate system (meters, not pixels) and its own unit scale. You'll need conversion functions to translate between Box2D's world and your screen pixels. A typical scale factor is 10 pixels per meter.
Bodies come in three types:
| Type | Behavior | Example |
|---|---|---|
| Dynamic | Responds to forces and collisions. Moves freely. | A falling ball, a thrown box |
| Static | Never moves. Infinite mass. Other bodies collide with it. | Ground, walls, platforms |
| Kinematic | Moves at a set velocity but isn't affected by forces. | A moving platform, a conveyor belt |
Creating a dynamic body with a box shape:
pseudocode # Define the body bodyDef = new BodyDef() bodyDef.type = DYNAMIC bodyDef.position = (5, 2) # in meters body = world.createBody(bodyDef) # Define the shape shape = new PolygonShape() shape.setAsBox(1, 1) # half-width, half-height # Attach via fixture fixtureDef = new FixtureDef() fixtureDef.shape = shape fixtureDef.density = 1.0 fixtureDef.friction = 0.3 fixtureDef.restitution = 0.5 # bounciness body.createFixture(fixtureDef)
Joints connect two bodies together with constraints. They're what make things interesting beyond simple collisions.
| Joint Type | What it does | Real-world analogy |
|---|---|---|
| Revolute | Rotation around a shared point | A door hinge, a pendulum pivot |
| Distance | Keeps two bodies at a fixed distance | A rigid rod connecting two balls |
| Prismatic | Allows sliding along one axis only | A piston, an elevator |
| Pulley | Connects two bodies via a pulley | An elevator counterweight |
| Mouse | Attaches a body to the mouse cursor | Dragging an object |
One of the biggest reasons to use a physics library is collision detection and response. In our hand-rolled physics, we checked for edge collisions (walls and floor). But what about objects hitting each other?
Collision detection has two phases:
Box2D handles both phases automatically. You can also register contact listeners to get callbacks when collisions happen, so you can trigger sounds, particles, damage, or score changes.
Box2D is built for rigid bodies. But what about soft, stretchy things? toxiclibs (by Karsten Schmidt) takes a different approach: particle-spring systems.
Instead of rigid shapes, toxiclibs gives you:
| Concept | What it is |
|---|---|
| VerletParticle | A point with position (uses Verlet integration — no explicit velocity) |
| VerletSpring | A spring connecting two particles with a rest length and stiffness |
| VerletPhysics | The world that steps the simulation |
toxiclibs is ideal for cloth, soft bodies, hair, rope, and anything that stretches. You define a mesh of particles connected by springs, and the physics engine keeps them at their rest lengths (approximately).
A soft body is built from particles connected by springs in a mesh pattern. Imagine a grid of particles where each one is connected to its neighbors. The springs try to maintain their rest lengths, but they can stretch and compress, creating a jelly-like object.
pseudocode # Create a grid of particles for row in 0..10: for col in 0..10: particle = new Particle(col * spacing, row * spacing) world.add(particle) # Connect neighbors with springs for each pair of adjacent particles: spring = new Spring(p1, p2, restLength, stiffness) world.add(spring)
The beauty of particle-spring systems is their simplicity. Each spring just pulls its two particles toward the rest length. But hundreds of springs working together create complex, organic behavior — another example of emergence from simple rules.
Below is a simplified rigid-body stacking simulation. Boxes fall from above and stack on a platform, colliding with each other. This demonstrates the core idea: the library handles all collisions and responses; we just draw.
Click/tap to spawn a new box. Boxes fall under gravity, collide with each other, and stack on the ground. Simple AABB collision detection is used.
| Topic | Key Takeaway |
|---|---|
| Why libraries | They handle collisions, constraints, and rigid body dynamics |
| Box2D | World → Bodies → Shapes → Fixtures. Step world, read positions. |
| Body types | Dynamic (moves), static (fixed), kinematic (scripted) |
| Joints | Revolute, distance, prismatic, pulley, mouse |
| Collision | Broad phase + narrow phase, handled automatically |
| toxiclibs | Particle-spring systems for soft bodies, cloth, rope |
| Verlet integration | Position-based (no explicit velocity), great for constraints |
What we covered:
• Box2D architecture (world, bodies, fixtures, joints)
• Dynamic, static, kinematic bodies
• Collision detection (broad + narrow phase)
• toxiclibs and Verlet integration
• Particle-spring systems
• Soft bodies and cloth
What comes next:
Chapter 6: Autonomous Agents. We move from inanimate objects to objects with desires. Steering behaviors let our shapes seek, flee, wander, and flock — the first step toward artificial life.