The article is based on MatterJs ^0.17.1

In the previous chapter, we introduced the physical environment of matterJs. With the environment, we need to place objects in the environment to enrich the world. Today, we’re going to look at how objects exist and move in the physical environment.

1. Introduction to objects in matterJs

Objects in matterJs fall into two categories:

  • Body – rigid Body
  • Composite — Composite

Only these two forms of objects are supported in the physical environment of matterJs. A rigid body is a single object body, and a composite is a combination of a rigid body, constraint, or composite. Rigid bodies provide the most basic physical objects with a fixed shape. Complex makes it possible for us to compose the irregular objects we need at will, and provides the possibility of realizing the diversity of the physical world.

In matterJs, the World is also a complex, with all the methods of the complex.

World.create = Composite.create;
World.add = Composite.add;
World.remove = Composite.remove;
World.clear = Composite.clear;
World.addComposite = Composite.addComposite;
World.addBody = Composite.addBody;
World.addConstraint = Composite.addConstraint;
Copy the code

Rigid body factories provide several basic shapes:

  • A rectangle rectangle
  • Trapezoid trapezoidal
  • Circle the round
  • Polygon polygon
  • FromVertices Extensible graphics

The composite factory Composites provides several kinds of complexes:

  • Stack stack
  • Chain chain
  • Mesh grid
  • Pyramid cone
  • NewtonsCradle Newton swing ball
  • The car the car
  • The softBody software

Two, the independent Body of rigid Body -Body

In Chapter 1, we wrote about a ball in free fall, and the ball in it is a circular physical rigid body. First, let’s look at what properties the next rigid body has:

The property name The default value introduce
id 0 Each rigid body has a unique ID that increments during creation
type ‘body’ type
label ‘Body’ Logo, you can name it yourself
parts [] Components of the rigidbody, usually array elements are the rigidbody itself
plugin {} The plug-in
angle 0 The Angle, this is in radians
vertices Vertices.fromPath(‘L 0 0 L 40 0 L 40 40 L 0 40’) Compute vertices and specify a rigid body shape
position { x: 0, y: 0 } Position, with the center of gravity as the calculation point
force { x: 0, y: 0 } The force component on the x, y vector
torque 0 Torque, M = F times L
speed 0 speed
angularSpeed 0 The angular velocity
velocity { x: 0, y: 0 } Physical velocity, displacement in the x and y components
angularVelocity 0 Physical angular velocity
isStatic false Whether static rigid body
isSleeping false Whether the rigid body sleeps
density 0.001 The density of rigid body
restitution 0 Attenuation coefficient of force (elasticity)
friction 0.1 The frictional force
frictionStatic 0.5 Static sliding friction
frictionAir 0.01 Air resistance
collisionFilter { category: 0x0001, mask: 0xFFFFFFFF, group: 0 } Collision filter
bounds null Rigid body boundary, with maximum and minimum values
circleRadius 0 The circular radius
timeScale 1 Time scaling coefficient, 0 frozen, greater than 1 accelerated less than 1 slow
positionPrev null The last rigid body position
anglePrev null The rigid body Angle from last time
axes null shaft
area 0 The area of a 2D plane shape
mass 0 The quality of rigid body
inertia 0 inertia
events null The event

Density = body. Mass/body. Area. Angle = radian * Math.pi / 180. Restitution can specify the height of elastic rigid body. The larger the value of the rigid body, the greater the force required to move. CollisionFilter The vertices filter rule, which is covered in a separate section. This provides an idea for us to customize the rigid body. The force size controls the movement direction of the rigid body.

Next, let’s look at what we can do with the methods provided by the rigid body:

1, Body. NextGroup

NextGroup = (isNonColliding) => {}

  • IsNonColliding Whether the colliding identifier is allowed

Returns a decrement or increment index. If isNonColliding is true, a decrement index is generated and the rigidbodies cannot collide. If isNonColliding is false, an increment index is generated and the rigidbodies can collide. Take 🌰 for example: when we set group = body.nextgroup (true), the circle will not collide with our ground, as it does when set to false.

var group = Body.nextGroup(true);
/** Create a circular rigid body */
var _circle = Bodies.circle(200.10.20, {
    isStatic: false.collisionFilter: {
        group: group
    }
});
Composite.add(world, [
    Bodies.rectangle(400.400.800.10, {
        isStatic: true.collisionFilter: {
            group: group
        }
    }),
    _circle
]);
Copy the code

So how does matterJs determine collisions?

if(filterA.group === filterB.group && filterA.group ! = =0)
            return filterA.group > 0;
Copy the code

So it’s a collision.

2, Body. NextCategory

NextCategory = ()=>{} Parameter: none Category value range is [1, 2^31]. Collisions between specified rigid bodies can be realized by specifying collision groups. This method is simply used to generate the category specified by the collisionFilter attribute. Use category and mask together to determine grouping collisions.

For example, 🌰: When the _circle category is the same as the Rectangle mask, the two can collide. In the following example, categoryA and categoryB have different values.

var categoryA = Body.nextCategory(),
    categoryB = Body.nextCategory();
/** Create a circular rigid body */
var _circle = Bodies.circle(200.10.20, {
    isStatic: false.collisionFilter: {
        category: categoryA
    }
});
Composite.add(world, [
    Bodies.rectangle(400.400.800.10, {
        isStatic: true.collisionFilter: {
            category: categoryB,
            mask: categoryB //categoryB
        }
    }),
    _circle
]);
Copy the code

How does matterJs determine grouping collisions?

return(filterA.mask & filterB.category) ! = =0&& (filterB.mask & filterA.category) ! = =0;
Copy the code

3, the Body. The set

Function: Body. Set = (Body, Settings, value) => {} parameter:

  • Body set to the rigidbody
  • Settings Specifies the value of the property or key-value pair to be set
  • The value insettingsIs a string value

When matterJs sets a property, it calls a series of methods to set the corresponding value. So what are the properties that can be set? Here are some values that can be set:

switch (property) {
    case 'isStatic':
        Body.setStatic(body, value);
        break;
    case 'isSleeping':
        Sleeping.set(body, value);
        break;
    case 'mass':
        Body.setMass(body, value);
        break;
    case 'density':
        Body.setDensity(body, value);
        break;
    case 'inertia':
        Body.setInertia(body, value);
        break;
    case 'vertices':
        Body.setVertices(body, value);
        break;
    case 'position':
        Body.setPosition(body, value);
        break;
    case 'angle':
        Body.setAngle(body, value);
        break;
    case 'velocity':
        Body.setVelocity(body, value);
        break;
    case 'angularVelocity':
        Body.setAngularVelocity(body, value);
        break;
    case 'parts':
        Body.setParts(body, value);
        break;
    case 'centre':
        Body.setCentre(body, value);
        break;
    default:
        body[property] = value;
}
Copy the code

As you can see, the default properties that are not rigid bodies can also be set.

4, the Body. The rotate

Rotate = (Body, rotation, point) => {}

  • Body Rotating rigid body
  • Rotation The Angle of rotation
  • Which point is rotated relative to

To rotate by a certain Angle relative to a given position, and to rotate by a given Angle. If no point is passed, only the rigid body rotates. If a point is passed, the rigid body rotates by the rotation relative to the point, and the rigid body also rotates by the rotation.

For example 🌰: The rectangle is rotated 30 * math. PI / 180 radians relative to {x: 200,y: 100}.

/** Create a rigid body */
var _rect = Bodies.rectangle(100.100.50.50, {
    isStatic: true}); Composite.add(world, _rect); Body.rotate(_rect,30 * Math.PI / 180, {
    x: 200.y: 100
});
Copy the code

If the rotation is 0, the object does not move or rotate even if the point is passed in.

Let’s see how matterJs handles this.

if(! point) { Body.setAngle(body, body.angle + rotation); }else {
    var cos = Math.cos(rotation),
        sin = Math.sin(rotation),
        dx = body.position.x - point.x,
        dy = body.position.y - point.y;
    Body.setPosition(body, {
        x: point.x + (dx * cos - dy * sin),
        y: point.y + (dx * sin + dy * cos)
    });
    Body.setAngle(body, body.angle + rotation);
}
Copy the code

As you can see, we set position first and then Angle.

5, the Body scale

Function: Body. Scale = (Body, scaleX, scaleY, point) => {}

  • The body of rigid body
  • ScaleX Scale factor in the X direction
  • ScaleY Scale factor in the Y direction
  • Point Scaling center, anchor point

If no scaling center is given, the default is the center of the rigid body (center of gravity). For example 🌰: the following rectangle is scaled by 50% with respect to {x: 200,y: 100} point x.

var _rect = Bodies.rectangle(100.100.50.50, {
    isStatic: true}); Composite.add(world, _rect); Body.scale(_rect,0.5.0.5, {x: 200.y: 100});
Copy the code

As you can see, scaling redefines the vertex rules of the rigid body and changes its mass, inertia and other properties.

// scale vertices
Vertices.scale(part.vertices, scaleX, scaleY, point);
// update properties
part.axes = Axes.fromVertices(part.vertices);
part.area = Vertices.area(part.vertices);
Body.setMass(part, body.density * part.area);
// update inertia (requires vertices to be at origin)
Vertices.translate(part.vertices, { x: -part.position.x, y: -part.position.y });
Body.setInertia(part, Body._inertiaScale * Vertices.inertia(part.vertices, part.mass));
Vertices.translate(part.vertices, { x: part.position.x, y: part.position.y });
Copy the code

6, the Body. The update

Update = (Body, deltaTime, timeScale, correction) => correction

  • The body of rigid body
  • DeltaTime Time interval frame interval of each update, 16.67ms
  • TimeScale timeScale coefficient 0 frozen, greater than 1 accelerated less than 1 slow
  • Correction The correction factor. Default is 1

We don’t call this method actively. It will be called in Engine. Update. Mainly used to update the rigid body position, Angle, velocity and other physical information and geometric transformation.

7, Body. ApplyForce

Function: Body. ApplyForce = (Body, position, force) => {}

  • The body of rigid body
  • Position Vector at which force is applied
  • Force Vector of applied force

Force is divided into components in the x and y directions.

For example 🌰: if we apply a force {x: 0.1, y: 0.1} to the rigid body _rect, the body will move along an oblique line at an Angle of 45 degrees.

var _rect = Bodies.rectangle(100.100.50.50, {
    isStatic: false.mass: 1
});
Composite.add(world, _rect);
Body.applyForce(_rect,{x: 0.y: 0}, {x: 0.1.y: 0.1});
Copy the code

Notice that the rigid body or the complex on which we apply force, its isStatic cannot be true, cannot be a static rigid body. Static rigid bodies are not subjected to force. When a rigid body is subjected to a force, a moment is created.

How does the applyForce method work?

body.force.x += force.x;
body.force.y += force.y;
var offset = { x: position.x - body.position.x, y: position.y - body.position.y };
body.torque += offset.x * force.y - offset.y * force.x;
Copy the code

At this point, we have covered the main properties and methods of the rigid body. Single rigidbodies in matterJs have a set of properties and methods that we can manipulate to create interesting scenarios. So how do we get some special shapes? Matterjs gives us a factory method for Bodies to generate various shapes.

Three, rigid body production workshop -Bodies

We have described the properties and methods that a single rigid body needs. With the core technology, we are about to start the production of formal products. Bodies provide us with several common moulds (shapes). All shapes are generated using body.create ().

1, the rectangle

Rectangle = (x, y, width, height, options) => {}

  • X — x position
  • Y — y position
  • Width the width of the
  • Height height
  • The options to configure

Shape method of rectangle:

Vertices.fromPath('L 0 0 L ' + width + ' 0 L ' + width + ' ' + height + ' L 0 ' + height)
Copy the code

Here’s an example 🌰:

/** Create rectangle **/
var _rect = Bodies.rectangle(100.100.50.50, {
    isStatic: false}); Composite.add(world, _rect);Copy the code

2, trapezoidal

Trapezoid = (x, y, width, height, slope, options) => {} parameter:

  • .
  • Slope slope

The form method of trapezoid:

if (slope < 0.5) {
    verticesPath = 'L 0 0 L ' + x1 + ' ' + (-height) + ' L ' + x2 + ' ' + (-height) + ' L ' + x3 + '0';
} else {
    verticesPath = 'L 0 0 L ' + x2 + ' ' + (-height) + ' L ' + x3 + '0';
}
var trapezoid = { 
    label: 'Trapezoid Body'.position: { x: x, y: y },
    vertices: Vertices.fromPath(verticesPath)
};
Copy the code

Here’s an example 🌰:

/** Create a trapezoid
var _trapezoid = Bodies.trapezoid(100.100.50.50.0.2, {
    isStatic: true}); Composite.add(world, _trapezoid);Copy the code

3, round

Function: Bodies. Circle = (x, y, radius, options, maxSides) => {} parameters:

  • .
  • The radius radius
  • MaxSides maximum edge

How does a circle have shape? It’s actually a formalized method of using polygons.

Bodies.polygon(x, y, sides, radius, Common.extend({}, circle, options))
Copy the code

A circle in matterJs is actually a polygon with a minimum of 10 sides and a default of 25.

Here’s an example 🌰:

/** Create a circle **/
var _cricle = Bodies.circle(50.50.50, {
    isStatic: true,},80);
Composite.add(world, _cricle);
Copy the code

Here’s the interesting part: matterJs intends to make a real circle.

// TODO: true circle bodies
Copy the code

4. Polygons

Function: Bodies. Polygon = (x, y, sides, radius, options) => {} parameters:

  • .
  • Sides number of edges
  • The radius radius

How are polygons present?

for (var i = 0; i < sides; i += 1) {
    var angle = offset + (i * theta),
        xx = Math.cos(angle) * radius,
        yy = Math.sin(angle) * radius;
    path += 'L ' + xx.toFixed(3) + ' ' + yy.toFixed(3) + ' ';
}
var polygon = { 
    label: 'Polygon Body'.position: { x: x, y: y },
    vertices: Vertices.fromPath(path)
};
Copy the code

If the number of sides is less than 3, the circle is drawn. For example 🌰: draws a triangle.

/** Create a polygon **/
var _polygon = Bodies.polygon(50.50.3.20, {
    isStatic: true}); Composite.add(world, _polygon);Copy the code

Custom shapes

Function: Bodies.fromVertices = (x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea, RemoveDuplicatePoints) => {} parameter:

  • .
  • VertexSets One or more arrays of vertices
  • FlagInternal Specifies whether an internal flag is displayed
  • RemoveCollinear 0.01 simplifies the threshold of the same side
  • MinimumArea 10 Threshold at which small portions are removed
  • RemoveDuplicatePoints 0.01 Threshold when simplifying nearby points

FlagInternal = true; no internal flag

Formal method interested can read the source code.

For example 🌰: Let’s draw a five-pointed star.

/** Custom shape **/
Common.setDecomp(decomp);
var star = Vertices.fromPath('50 0 63 38 100 38 69 59 82 100 50 75 18 100 31 59 0 38 37 38');
var _custom = Bodies.fromVertices(200.200, star,{
    isStatic: true
},true.0.1.10);
Composite.add(world, _custom);
Copy the code

Decomp is a plugin for drawing custom shapes. I’m just using script reference here. Use a series of points to form a closed shape.

Four,

This section describes the rigid body in matterJs, including its properties and methods. Note that each rigid body has its own unique ID. It has both similar and dissimilar properties. We can draw some rigid Bodies with shapes using the Bodies factory method:

  • rectangular
  • trapezoidal
  • polygon
  • circular
  • Some custom shapes

We can also do a few things to the rigidbody:

  • Setting the base properties
  • Setting collision rules
  • Apply force to move the rigid body

Meanwhile, we need to pay attention to:

  • A static rigid body is free from any physical action
  • You can set rigid body updates to achieve certain effects, such as freezing, constant speed, and to prevent stalling.

We will continue this in the next chaptermatterJsHow to create a complex complex. And how to use complexes to build complex physical worlds.

This article is shallow, please don’t hesitate your comments and likes ~ note: this article is the author’s painstaking work, reprint must declare