How to Disable Planck.js Collisions Dynamically?
Planck.js, a 2D JavaScript physics engine based on Box2D, allows
developers to alter contact behavior in real time during a physics step.
By tapping into the PreSolve event listener, you can
intercept a collision right before it is calculated by the physics
solver and disable it by calling contact.setEnabled(false).
This technique is ideal for creating one-way platforms, passing through
specific obstacles based on game state, or ignoring collisions between
specific objects dynamically without permanently changing their
collision filters.
Understanding the PreSolve Event
The PreSolve event is fired after the engine detects
that two fixtures are overlapping, but before it applies any
forces or impulses to resolve the collision. This provides a precise
window of opportunity to evaluate the contact and decide whether the
physics engine should treat it as a solid barrier.
Unlike the BeginContact event—which merely reports that
a collision has started—PreSolve runs continuously every
time step as long as the shapes overlap, giving you continuous control
over the interaction.
Implementing the Collision Hook
To disable a collision dynamically, you must register a
PreSolve listener on your Planck.js world object. Inside
the callback function, you can inspect the two fixtures involved in the
contact, determine if they meet your criteria for bypassing, and disable
the contact if necessary.
Here is a typical implementation pattern:
// Register the PreSolve event listener on your world
world.on('pre-solve', function(contact, oldManifold) {
const fixtureA = contact.getFixtureA();
const fixtureB = contact.getFixtureB();
const bodyA = fixtureA.getBody();
const bodyB = fixtureB.getBody();
// Insert your custom logic here (e.g., check entity types or positions)
if (shouldPassThrough(bodyA, bodyB)) {
// Dynamically disable the collision for this physics step
contact.setEnabled(false);
}
});Creating One-Way Platforms
A classic use case for the PreSolve hook is the “one-way
platform” found in many 2D platformer games, where a character can jump
up through a platform from below but lands solidly on top of it.
To achieve this, you compare the vertical position of the character’s
feet with the top surface of the platform inside the
PreSolve event. If the character is moving upward or their
position is lower than the platform’s threshold, you call
contact.setEnabled(false), allowing them to pass through
seamlessly.
Important Performance Considerations
Because the PreSolve event fires frequently for every
overlapping pair of fixtures during every single physics step, it is a
performance-critical area of your application.
- Keep Logic Lightweight: Avoid heavy calculations, object allocations, or complex array lookups inside the listener.
- Use Fast Filtering First: Use standard Planck.js
collision filtering (
categoryBitsandmaskBits) for static collision rules. Only rely onPreSolvefor rules that genuinely change dynamically depending on real-time game conditions.