How to Enable Joint Limits in Planck.js?
Planck.js, a 2D JavaScript physics engine rewritten from Box2D, allows developers to restrict the range of motion for physics bodies using joint limits. By configuring constraints on specific joints—most commonly RevoluteJoint and PrismaticJoint—you can precisely control angles or translation distances. This article provides a straightforward guide on how to enable, configure, and dynamically update these limits to keep your physics simulations contained and realistic.
Understanding Joint Limits
In Planck.js, joints connect two bodies and dictate how they move relative to each other. By default, joints often allow a free range of motion. Enabling limits introduces a strict boundary on this motion:
- Revolute Joint Limits: Restrict the rotation angle between two bodies, measured in radians.
- Prismatic Joint Limits: Restrict the linear translation along a specified axis, measured in meters.
Step-by-Step Implementation
1. Define the Joint Definition
When creating a joint, you pass a definition object
(RevoluteJointDef or PrismaticJointDef) to the
world creator method. This is where you declare the boundaries.
2. Enable the Limit Property
You must explicitly set enableLimit to
true. Simply providing the upper and lower bounds is not
enough; the engine will ignore them unless the limit flag is active.
3. Set Lower and Upper Bounds
Specify the minimum and maximum allowed movement. For angles, remember that Planck.js uses radians, not degrees.
Code Example: Revolute Joint Limits
Here is a practical example of constraining a spinning pendulum or hinge to a 90-degree arc (\(-45^\circ\) to \(+45^\circ\)).
import { World, Vec2, RevoluteJoint } from 'planck-js';
const world = new World(new Vec2(0, -10));
// ... (Assume bodyA and bodyB are already created and positioned)
// Create the joint definition
const jointDef = {
lowerAngle: -0.25 * Math.PI, // -45 degrees in radians
upperAngle: 0.25 * Math.PI, // 45 degrees in radians
enableLimit: true, // Crucial step to activate limits
localAnchorA: Vec2(0, 0),
localAnchorB: Vec2(0, 2),
};
// Create the joint in the world
const hingeJoint = world.createJoint(new RevoluteJoint(jointDef));Modifying Limits Dynamically
If your simulation requires boundaries to change during runtime—such as a gate unlocking to open wider—you can modify the joint properties directly after creation using the following API methods:
// Change the limits on the fly
hingeJoint.setLimits(-Math.PI / 2, Math.PI / 2);
// Toggle the limit entirely
hingeJoint.enableLimit(false); By utilizing enableLimit, setLimits(), and
keeping your units in radians (for rotation) or meters (for
translation), you can reliably control asset behavior and maintain
stability within your Planck.js environment.