How to Set Density of a Body in Matter.js
In Matter.js, a 2D physics engine for the web, the density of a rigid body determines its mass relative to its surface area. This article covers how to configure the density of a body both during initialization and at runtime. You will learn the default density values, how changing density affects mass, and the correct methods provided by the Matter.js API to ensure accurate physics calculations.
Setting Density During Creation
When creating a new body with the Matter.Bodies factory
module, you can specify the density property directly in
the options object.
const { Bodies } = Matter;
// Create a body with a custom density
const heavyBox = Bodies.rectangle(400, 200, 80, 80, {
density: 0.005
});By default, Matter.js assigns a density of 0.001 to
newly created dynamic bodies. A higher value results in a heavier body,
causing it to exert more force during collisions and resist being moved
by lighter objects of equal size.
Updating Density at Runtime
To change the density of an existing body, use the
Matter.Body.setDensity function. You should not modify the
body.density property directly, as the physics engine must
also recalculate related properties such as mass and inertia.
const { Body } = Matter;
// Dynamically update the density
Body.setDensity(heavyBox, 0.02);Relationship Between Density, Mass, and Area
In Matter.js, mass is derived from density and surface area using the formula:
\[\text{Mass} = \text{Density} \times \text{Area}\]
- Calling
Body.setDensity(body, newDensity)automatically updates bothbody.massandbody.inverseMass. - Conversely, calling
Body.setMass(body, newMass)automatically recalculates the body'sdensitybased on its area. - If you resize a body using
Body.scale(), the area changes, and Matter.js will recalculate the mass while preserving the current density. - For static bodies (
isStatic: true), the mass and density are treated as infinite. Setting a density on a static body will only influence simulation behavior if the body is later made dynamic usingBody.setStatic(body, false).