Tuesday, July 25, 2017

Getting Started With Matter.js: The Engine and World Modules

In the introductory tutorial of this series, you were briefly introduced to different modules in Matter.js. The library contains a lot of modules, so it was impractical to write in detail about each of them in a single tutorial. After reading the first part of the series, you should now have a general idea of the library and its features.

In this tutorial, we will just focus on the World module and the Engine module in Matter.js. The World module provides us with the necessary methods and properties to create and manipulate the world composite. You can use it to add or remove different bodies from the world. The Engine module contains methods for creating and manipulating the engines that are responsible for creating the simulation of your world.

The World Module

In this section, you will learn about different methods, properties and events of the World module. World is actually a Composite with additional properties like gravity and bounds added to it. Here is a list of important methods available in this module:

  • add(composite, object): This method is inherited from the Composite module and allows you to add one or more body(s), composite(s) or constraint(s) to the given composite or world. 
  • addBody(world, body): This method allows you to add individual body elements to the given world. There are also addComposite() and addConstraint() methods that allow you to add a composite or constraint to the world.

The code below uses both these methods to add different bodies to the world. The add() method adds three static rectangles that act as walls. The addBody() method adds a circle, square or rectangle based on the button clicked by the user.

You can see that the isStatic key has been set to true for the three walls in our world. Setting this key to true for any object makes that object completely static. The object will never change its position or angle now. There are a lot of other properties that can be specified to control the behavior of different objects. You will learn about all of them in the Body module tutorial of this series.

  • remove( composite, object, [deep=false]): This is a generic method to remove one or more body(s), composite(s) or constraint(s) from the given composite or world. For example, you could use the following line to remove the top and left walls from the world.
  • clear( world, keepStatic): This method is an alias for its Composite counterpart. You can use it to remove all the elements from the world at once. The second parameter is a Boolean which can be used to prevent static elements from being cleared. Its value is false by default. This means that calling World.clear( world) will remove all the elements from that particular world.
  • rotate( composite, rotation, point, [recursive=true]): This method can be used to rotate all the children in a given world or composite by a specific angle around the provided point. The angle given here is in radians. The point parameter determines the point for rotation.
  • scale( composite, scaleX, scaleY, point, [recursive=true]): You can use this method to scale all the children of your composite or world by the given values. This method scales everything from width, height and area to mass and inertia.
  • translate(composite, translation, [recursive=true]): The translate method is useful when you want to translate or move all the children of a world or composite by a given vector relative to their current positions. 

One thing you should keep in mind is that neither translate() nor rotate() imparts any kind of velocity to the bodies in the world. Any motion that occurs is just the result of changes in the shape or position of different bodies. Here is some code to scale, rotate and translate a world based on button clicks:

You should note that the above code applies a different scale on the x and y axis. This turns the circle in our Matter.js world into an oval. The oval then topples to go to a more stable state with lower potential energy.

Try pressing the Scale button in the above demo. After that, press the Rotate button to see how closely Matter.js simulates the real-life motion of an oval.

Besides all these methods, the World module has a lot of useful properties as well. For example, you can get an array of all the bodies that are direct children of the world composite using world.bodies. Similarly, you can get an array of all the composites and constraints using world.composites and world.constraints

You can also specify the bounds of the world within which Matter.js should detect collisions using world.bounds. One interesting thing that you can change with the world properties is gravity. The gravity along the x and y axis is set to 0 and 1 by default. You can change these values using world.gravity.x and world.gravity.y respectively.

You should visit the Matter.World documentation page to read more about this module.

The Engine Module

The Engine module is necessary for properly updating the simulation of the world. Here is a list of some important methods of the Engine module.

  • create([options]): This method is useful when you want to create a new engine. The options parameter in this method is actually an object with key-value pairs. You can use options to override the default values for different properties of the engine. For example, you can use the timeScale property to slow down or speed up the simulation. 
  • update(engine, [delta=16.666], [correction=1]): This method will move the simulation forward in time by delta ms. The value of the correction parameter specifies the time correction factor to apply after the update. This correction is usually only necessary when the delta is changing between each update.
  • merge(engineA, engineB): This method will merge two engines specified by the given parameters. While merging, the configuration is applied from engineA and the world is taken from engineB.

The Engine module also has a lot of other properties to help you control the quality of the simulation. You can set a value for constraintIterations, positionIterations or velocityIterations to specify the number of constraint, position and velocity iterations to perform during each update. A higher value in each case will provide a better simulation. However, a higher value will also adversely affect the performance of the library.

You can set a value for the timing.timeScale property to control the speed at which the simulation occurs. Any value below 1 will result in a slow-motion simulation. Setting this property to zero will completely freeze the world. The following example should make it clear.

You might have noticed that the balls are bouncing off the ground this time. Every rigid body has a coefficient of restitution set to 0 by default. This gives them clay-like properties, and they don't bounce back on collision. I have changed the restitution value to 1 so that the balls can easily bounce back. 

You will learn about all these properties of rigid bodies in the next tutorial of the series. For now, add some circles or balls to the world and try pressing the slow motion and fast motion buttons to notice the difference.

You should visit the Matter.Engine documentation page to read more about this module.

Conclusion

This tutorial discussed two very important modules in Matter.js that you need to know about in order to run any simulations. After reading this tutorial, you should be able to scale, rotate, slow down or speed up your world. Now, you also know how to remove or add bodies to a world. This can be helpful when you are developing 2D games.

In the next tutorial of the series, you will learn about the different methods, properties and events available in the Bodies module.


by Monty Shokeen via Envato Tuts+ Code

No comments:

Post a Comment