Perfectly Elastic Collisions in Matter.js
This guide explains how to configure physics bodies and simulation settings in Matter.js to achieve perfectly elastic collisions. In a perfectly elastic system, colliding bodies conserve total kinetic energy, rebounding without any loss of speed or momentum. Achieving this behavior requires setting maximum restitution, eliminating all forms of friction and drag, and tuning the simulation engine to prevent subtle numerical energy losses.
Configure Body Restitution
The core property governing bounce in Matter.js is
restitution. A value of 0 represents a
completely inelastic collision where bodies stick together, while a
value of 1 represents a fully elastic collision.
When two bodies collide, Matter.js calculates the resulting bounce
using Math.max(bodyA.restitution, bodyB.restitution). While
setting one body to 1 is technically sufficient for
collisions involving that body, you should explicitly set
restitution: 1 on all interacting bodies—including walls
and boundaries—to ensure consistent elastic behavior throughout the
entire canvas.
const elasticBody = Matter.Bodies.circle(x, y, radius, {
restitution: 1
});Eliminate Friction and Drag
Even with maximum restitution, bodies will lose energy if friction is present. You must strip away linear surface friction, static friction, and air resistance:
friction: 0: Prevents tangential energy loss when bodies scrape or glance off one another.frictionAir: 0: Prevents the engine from applying velocity drag over time. If left at its default value (0.01), bodies will steadily lose speed even if every collision is elastic.frictionStatic: 0: Ensures that bodies do not stick or bind when in contact.
Combine these values into a standard definition for your elastic bodies:
const defaultElasticOptions = {
restitution: 1,
friction: 0,
frictionAir: 0,
frictionStatic: 0
};
const ballA = Matter.Bodies.circle(100, 200, 20, defaultElasticOptions);
const ballB = Matter.Bodies.circle(300, 200, 20, defaultElasticOptions);
const wall = Matter.Bodies.rectangle(400, 200, 50, 400, {
isStatic: true,
...defaultElasticOptions
});Adjust Engine and Solver Settings
Matter.js uses an iterative impulse solver. In high-speed scenarios or dense clusters of objects, default engine thresholds can introduce minor energy drift (either damping the motion or artificially adding energy).
To maintain energy conservation:
- Disable Gravity: If gravity is active, bodies will
accelerate downward. Set
engine.gravity.y = 0andengine.gravity.x = 0if you want closed-system kinetic conservation. - Increase Solver Iterations: Increase
engine.positionIterationsandengine.velocityIterations(e.g., from default6and4up to10or higher) to minimize calculation errors during impacts. - Disable Sleeping: Set
enableSleeping: falseon the engine to prevent bodies with low velocities from falling asleep and halting unexpectedly. - Cap Maximum Velocity (Optional): If numerical
errors cause bodies to slowly gain energy over thousands of frames,
manually clamp body velocities in a
beforeUpdateevent listener to ensure strict physical consistency.