Create a Grid of Boxes with Matter.Composites.stack
This article provides a practical guide on using the
Matter.Composites.stack method to generate a structured
grid of rigid box bodies within the Matter.js 2D physics engine. You
will learn the purpose of each parameter in the function, how to
configure spacing and dimensions, and how to implement a complete
working script to render the grid in your physics simulation.
Understanding
the Matter.Composites.stack Method
In Matter.js, the Composites module offers factory
methods for creating complex or repetitive arrangements of bodies. The
stack method specifically generates a two-dimensional grid
of bodies organized into rows and columns.
The syntax for Composites.stack is:
Matter.Composites.stack(xx, yy, columns, rows, columnGap, rowGap, callback)Parameter Breakdown:
xx(number): The starting X-coordinate (left offset) for the grid.yy(number): The starting Y-coordinate (top offset) for the grid.columns(number): The total number of columns to generate.rows(number): The total number of rows to generate.columnGap(number): The horizontal space between adjacent bodies.rowGap(number): The vertical space between adjacent bodies.callback(function): A function called for every cell in the grid. It passes the calculated(x, y)position of each cell and must return aMatter.Bodyinstance.
Step-by-Step Implementation
To build a 5x5 grid of rectangular boxes, initialize your Matter.js
modules, define the grid via Composites.stack, and add the
resulting composite to the simulation world.
// 1. Alias Matter.js modules
const { Engine, Render, Runner, Bodies, Composite, Composites } = Matter;
// 2. Create the engine and renderer
const engine = Engine.create();
const render = Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false
}
});
Render.run(render);
Runner.run(Runner.create(), engine);
// 3. Define grid parameters
const startX = 200;
const startY = 100;
const columns = 5;
const rows = 5;
const columnGap = 10;
const rowGap = 10;
const boxWidth = 40;
const boxHeight = 40;
// 4. Create the grid using Composites.stack
const boxGrid = Composites.stack(
startX,
startY,
columns,
rows,
columnGap,
rowGap,
function(x, y) {
return Bodies.rectangle(x, y, boxWidth, boxHeight, {
render: {
fillStyle: '#3498db'
}
});
}
);
// 5. Create boundaries to support the stack
const ground = Bodies.rectangle(400, 580, 810, 40, { isStatic: true });
// 6. Add all elements to the world
Composite.add(engine.world, [boxGrid, ground]);Customizing the Grid Bodies
Because the callback function runs for every cell, you
can introduce conditions or randomize properties per body.
- Checkerboard Colors: Alter the body appearance
based on its position or a loop counter by changing
render.fillStyle. - Static vs. Dynamic: Add
{ isStatic: true }inside the body options if you want the grid to remain fixed in place rather than fall under gravity. - Non-Uniform Shapes: While
Composites.stackis designed for a consistent grid, the callback allows returning different geometry (such as alternating circles and rectangles) as long as their placement fits within the defined row and column gaps.