blog

Getting Started With Matter.js: The Composites and Composite Modules

In the third tutorial of the series, you learned about different methods and properties of the Body module in Matter.js. The Body module enables you to manipulate simple bodies like circles, rectangles, and trapeziums. Matter.js also has other modules to help you create and manipulate some complex but common composite bodies like cars, chains, pyramids, stacks, and soft bodies.

All these composites and the methods to manipulate them are available in the Composite and Composites modules in Matter.js. In this tutorial, you will begin by learning about different composites like pyramids and cars etc. that can be created using the Composites module. After that, we will go over some important methods and properties available in the Composite module.

Creating a Stack and a Pyramid

A stack and a pyramid are both very similar to each other. A stack can be created by using the stack(xx, yy, columns, rows, columnGap, rowGap, callback) function. Similarly, you can create a pyramid with the help of the pyramid(xx, yy, columns, rows, columnGap, rowGap, callback) function. As you can see, all the parameters are the same in both cases. In fact, the pyramid formation is derived from the stack formation.

The names of all the parameters are self-explanatory. The xx and yy parameters used in this function are used to specify the starting point of the composite. The columns and rows parameters determine the number of columns and rows in the composite. The gap between different rows and columns can be controlled using the columnGap and rowGap parameters.

Under the influence of gravity, the rowGap generally vanishes in most cases without changing the composite. However, sometimes the resulting momentum of individual bodies can move the bodies under them. This can change the shape of the composite.

The callback function is used to create bodies that can be arranged in either a grid arrangement or a pyramid arrangement based on the function used. This means that you can use it to create a stack or pyramid of rectangular boxes or trapezoids. You should keep in mind that using a circle will make the arrangements unstable. Here is the code to create a stack of rectangles:

You can make the callback function as complex as you wish. In this case, I have used the render options that we learned about in the Body module tutorial to create only orange rectangles with black outlines.

When you start creating a lot of pyramids with different parameters, you will notice that the number of rows created is sometimes less than the number of rows you specified. This is because the library uses the following formula to calculate the number of rows:

Math.min(rows, Math.ceil(columns / 2))

You can carefully place a stack or another pyramid over a pyramid to create interesting patterns. For example, you could place a smaller pyramid over the red one to create a complete pyramid with two colors.

Creating a Car and a Chain

A car in Matter.js is a structure consisting of two wheels and a body. The wheels are created with a friction of 0.8 and density equal to 0.01. You can create a car using the function car(xx, yy, width, height, wheelSize). The xx and yy parameters are used to specify the position of the car.

The width and height determine the dimensions of the main body of the car. The wheelSize parameter is used to specify the radius of the wheels. There is no need for a callback function as the type of bodies needed to create a car is predetermined.

You can use the chain(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) function in Matter.js to chain all the bodies in a given composite together using constraints. The offset parameters in the function are used to determine the relative position of the constraints connecting different boxes.

You will also need additional constraints to hang the chain from a point in the world. Here is the code to create a chain and hang it to the ceiling of our world.

The boxes in our chain have been created using the stack() function that you learned about earlier. The constraints created by the chain() function have a stiffness of 1.

This prevents the length of rope between different boxes from changing at all. The additional constraint that we have created here keeps our boxes hanging from the ceiling.

Here is a demo with a car and the chain created from the above code. You can move the car forward and backward using the orange buttons. Each click applies a force at the center of the first wheel, moving the whole car.

Creating a Soft Body and Newton's Cradle

A soft body is similar to a stack, with two major differences. The individual elements of the soft body are held together by constraints, and a soft body can only have circles as its constituent elements. You can consider a soft body to be a cross between a mesh and a stack. Creating a soft body is as simple as calling softBody(xx, yy, columns, rows, colGap, rowGap, crossBrace, pRadius, pOptions, cOptions) with the appropriate parameter values.

You are already familiar with the first six parameters of the function. The crossBrace parameter is a Boolean value that determines if the cross braces should be rendered or not. The pRadius parameter determines the radius of circles, and the pOptions parameter can be used to control other properties of the particles, like mass and inertia.

The cOptions parameter specifies various options for the constraints that bind the particles together. The following code will create a soft body for our Matter.js world.

Creating a Newton's cradle is also very straightforward using the built-in newtonsCradle(xx, yy, number, size, length) function. The number parameter determines the number of balls in the cradle. The size parameter determines their radius, and the length parameter determines the length of the rope to which the balls are attached. The library sets the restitution and friction values to zero so that they can continue their motion for a long time.

The following code creates the cradle and moves the first ball to a higher position so that it has some velocity when it falls down and strikes other balls. The position specified by the translate() function is relative to the current position of the body. All these functions and properties of the Body module have been discussed in more detail in the previous tutorial of the series.

Important Methods and Properties in Composite Module

Now that you have learned how to create different kinds of composite bodies, it is time for you to learn about different methods and properties available in the Composite module to manipulate these composites. You can use rotate(composite, rotation, point, [recursive=true]), scale(composite, scaleX, scaleY, point, [recursive=true]) and translate(composite, translation, [recursive=true]) to rotate, scale and translate any composite. These functions are very similar to their Body module counterparts.

You can also add or remove one or more body(s), constraint(s) and composite(s) from a given composite using the add(composite, object) and remove(composite, object, [deep=false]) functions respectively. If you want to move some bodies from one composite to another, you can do so with the help of the move(compositeA, objects, compositeB) function. This function will move the given objects from composite A to composite B.

If you ever want to access all the bodies, composites and constraints that are direct children of the given composite, you can use the composite.bodies, composite.composites and composite.constraints properties to get access to all of them in the form of an array.

We have already seen how to use the bodies property to translate a ball from the Newton's cradle to the left and apply a force on the wheel of our car composite. Once you have a reference to individual bodies from the composite, you can use all the methods and properties of the Body module to manipulate them.

Final Thoughts

In this tutorial, you learned how to create some complex composites using the Composite and Composites modules in Matter.js. You also learned about different methods and properties that you can use to manipulate these composites.

This series was aimed at getting people started with the Matter.js library in a beginner-friendly way. Keeping that in mind, we have covered important functions and properties of the most common modules in the library.

Matter.js also has a lot of other modules, which we briefly discussed in the first tutorial of the series. If you want to use this library to its full potential, you should read the documentation of all these modules on the official website.

If you have used Matter.js in any of your projects, please tell us about your experience in the comments.