How to Iterate Through planck.js Bodies?
This article provides a straightforward guide on how to loop through
all the active rigid bodies in a planck.js physics world.
You will learn the standard method using the built-in linked list
pointers (getBodyList() and getNext()), along
with a practical code example to implement in your JavaScript physics
projects.
Understanding the World Body List
In planck.js (a JavaScript port of the Box2D physics
engine), the simulation world maintains its rigid bodies as a
doubly linked list rather than a standard JavaScript
array. This design optimizes performance for the physics engine’s
internal updates, but it means you cannot use typical array methods like
forEach() or map() directly on the world
object.
To traverse this list, you start at the head of the list and move sequentially to each subsequent body until you reach the end.
Step-by-Step Iteration Code
To iterate through the bodies, use the
world.getBodyList() method to retrieve the first body.
Then, use a while loop to perform your logic and advance to
the next body using body.getNext().
Here is the standard implementation:
// Assuming 'world' is your planck.World instance
let body = world.getBodyList();
while (body) {
// Access body properties or apply forces
const position = body.getPosition();
const type = body.getType(); // 'static', 'kinematic', or 'dynamic'
console.log(`Body Position: X: ${position.x}, Y: ${position.y}`);
// Move to the next body in the linked list
body = body.getNext();
}Important Considerations
- The Loop Termination: When
body.getNext()reaches the end of the list, it returnsnull, which naturally terminates thewhileloop. - Modifying the List: If you plan to
destroy bodies during the iteration, caching the next
body before destroying the current one is highly recommended.
Destroying a body clears its pointers, which will break your loop if you
try to call
body.getNext()afterward.
Here is how to safely delete bodies during iteration:
let body = world.getBodyList();
while (body) {
// Cache the next body immediately
const nextBody = body.getNext();
// Example condition for removal
if (body.getUserData() && body.getUserData().shouldDelete) {
world.destroyBody(body);
}
// Move to the cached next body
body = nextBody;
}