Setting Body Mass Instead of Density in Matter.js
In Matter.js, physics bodies automatically calculate their mass based on their area and a default density value. However, you can manually set the mass of a body instead of relying on density calculations. This article explains how to explicitly define mass during body creation or update it dynamically at runtime, as well as how Matter.js reconciles the relationship between mass, density, and inertia.
Setting Mass During Body Creation
You can override the default automatic calculation by passing a
mass property inside the options object when creating a
body.
const { Bodies } = Matter;
// Create a body with an explicit mass of 50
const box = Bodies.rectangle(400, 200, 80, 80, {
mass: 50
});When you pass an explicit mass value at instantiation,
Matter.js accepts the value and automatically recalculates the body's
density behind the scenes using the formula:
\[\text{density} = \frac{\text{mass}}{\text{area}}\]
Updating Mass Dynamically
If the body has already been instantiated, you should not set
body.mass = newMass directly. Directly modifying properties
can cause physics calculation errors because internal properties such as
inverseMass, inertia, and
inverseInertia will not update.
Instead, use the built-in Body.setMass method:
const { Body } = Matter;
// Correct way to update mass dynamically
Body.setMass(box, 100);Using Body.setMass() ensures that:
body.massis updated.body.inverseMassis updated to1 / mass.body.densityis recalculated relative to the body's existing area.- Rotational properties linked to mass distribution remain stable.
How Matter.js Balances Mass and Density
Matter.js always keeps mass, density, and area synchronized. They are not independent variables:
- Changing Density: If you call
Body.setDensity(body, newDensity), Matter.js updates the mass (mass = newDensity * area). - Changing Mass: If you call
Body.setMass(body, newMass), Matter.js updates the density (density = newMass / area). - Scaling Dimensions: If you scale a body using
Body.scale(body, scaleX, scaleY), its area changes. By default, Matter.js preserves the body's density and recalculates the mass to reflect the new size. If you want the body to retain its exact mass after scaling, you must callBody.setMass()again after the scale operation.
Considerations for Static Bodies
Static bodies (bodies created with isStatic: true) are
treated as having infinite mass and zero inverse mass:
mass = InfinityinverseMass = 0
Attempting to set a finite mass on a static body will not make it
dynamic. To apply a manual mass to a previously static body, you must
first convert it to a dynamic body using
Body.setStatic(body, false) before defining its mass.