The article is based on MatterJs ^0.17.1

One, foreword

Collision is an old concept, many students should be familiar with it. Today we are going to take a closer look at collisions in MatterJs.

What is a collision

In nature, the act of two objects having contact areas is called collision. Representational to code, we can say that if the “shape” properties (width, height, position) of two objects intersect, a collision occurs.

Common collisions are:

  • Point to point
  • Point and graphics
  • Point and line
  • Line and graphics

Let’s take a look at how MatterJs handles collisions.

Second, find collision pairs

In MatterJs, a Grid instance is created when the engine is created. The Grid module is used to find all the body areas in the entire physical world. Pairs of region objects are then stored. When each physical rigidbody is updated, the corresponding region is updated and each pair is updated. And then we can get a list of all the regions where the rigid bodies are.

Grid.update(grid, allBodies, engine, world.isModified);
gridPairs = grid.pairsList;
Copy the code

Once we have the corresponding rigid-body blocks, we need to determine whether or not they collide. Each pair of rigidbody blocks taken above contains a pair of rigidbody including its properties. Then, we can determine whether the rigid bodies can collide by collisionFilter, the property of the rigid bodies we set earlier. We have talked about the collision property in “Rigid bodies in the Physical world”.

When the following conditions are met, the collision prerequisites are met:

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

Next, we can see that MatterJs uses the separation axis theory SAT to deal with the collision condition: “Two convex hull polygons, if and only if there is a line, the projection of the two polygons on this line does not intersect, then the two polygons do not intersect either”. A pair of collisionable pairs is calculated.

Two rigid body collision atmospheres in three stages:

  • CollisionStart The collision starts
  • CollisionActive collisions
  • CollisionEnd The collision ends

MatterJs starts events in three stages to give feedback to the user.

Events.trigger(engine, 'collisionStart', { pairs: pairs.collisionStart });
Events.trigger(engine, 'collisionActive', { pairs: pairs.collisionActive });
Events.trigger(engine, 'collisionEnd', { pairs: pairs.collisionEnd });
Copy the code

So much for the source code stuff, let’s take a look at how to use it.

How to use collision detection in Matter

When two rigid bodies collide, collisionStart will be sent only once, and collisionActive will be triggered as long as the collision state is still in place. Ending a collision will send the collisionEnd event.

We listen for these three events in the project to get the information we want.

Here’s an example 🌰: we use a rectangular board to catch a free-falling ball.

 /** Create a ball **/
var _cricle = Bodies.circle(200.200.50, {
    mass: 0.1.isStatic: false
}, 800);
var _cricle1 = Bodies.circle(200.100.50, {
    mass: 0.1.isStatic: false
}, 800);
var _rect = Bodies.rectangle(250.500.400.50, {
    isStatic: true}); Composite.add(world, [_cricle,_rect,_cricle1]);/ * * * * / collision
Matter.Events.on(engine, 'collisionStart'.(e) = >{
    console.log("888",e)
});
Copy the code

Let’s start with the physical world:

Let’s print the start of the collision:

You can see that the information about the beginning of the collision between rigid bodies is recordede.sourceIn the.

We can do some operations at the beginning of a rigid body collision, such as removing operations that require only one collision.

Next, let’s look at the collisionActive trigger:

Matter.Events.on(engine, 'collisionActive'.(e) = >{
    console.log("888",e.pairs)
});
Copy the code

If you look at it and you see two rigid bodies colliding all the time, then every frame will be emittedcollisionActiveEvents.

The collisionEnd event is not emitted while in collision state.

And then let’s see, if we move the x position of the board some distance so that the ball only hits it once,

/** Create a ball **/
var _cricle = Bodies.circle(200.200.50, {
    mass: 0.1.isStatic: false
});
var _rect = Bodies.rectangle(420.500.400.50, {
    isStatic: true}); Composite.add(world, [_cricle,_rect]);/ * * * * / collision
Matter.Events.on(engine, 'collisionStart'.(e) = >{
    console.log("start",e)
});
Matter.Events.on(engine, 'collisionActive'.(e) = >{
    console.log("active",e)
});
Matter.Events.on(engine, 'collisionEnd'.(e) = >{
    console.log("end",e)
});
Copy the code

Here we can see:

Let’s print the information carried by the trigger event:

It was a bit embarrassing, all three events did trigger, but there was one problem with all of them. Our collision pair didn’t know where it was going, so it was a bit buggy.

Collision experiment is only for everyone to experiment, this bug does not affect his use, hahaha ~~

Collision detection has many principles and a lot of calculation, but the method provided by Matter can be well applied and practiced in development.

Set collision rules

Two ways to set collision rules are provided in Matter.

  • A single setgroup
  • categoryandmaskTogether with

Set up the group

Using the body.nextGroup (isNonColliding) method, set the group value. When isNonColliding is true, it generates a decrement index, which rigid bodies cannot collide, or false, it generates an increment index, which rigid bodies can collide. For example 🌰:

// It can collide
var group = Body.nextGroup(false);
// No collision
//var group = Body.nextGroup(false);
/** Create a ball **/
var _cricle = Bodies.circle(200.200.50, {
    mass: 0.1.isStatic: false.collisionFilter: {
        group: group
    }
});
var _rect = Bodies.rectangle(250.500.400.50, {
    isStatic: true.collisionFilter: {
        group: group
    }
});
Composite.add(world, [_cricle, _rect]);
Copy the code

Determine whether a collision is possible by setting the group.

// It can collide
var group = Body.nextGroup(false);
// No collision
//var group = Body.nextGroup(false);
Copy the code

Set the category and mask

When A’s category is the same as B’s mask, the two can collide.

For example 🌰: we specify _cricle’s category as categoryB,_rect’s category as categoryB, and mask as categoryA, so there will be no collisions.

var categoryA = Body.nextCategory(),
    categoryB = Body.nextCategory();
/** Create a ball **/
var _cricle = Bodies.circle(200.200.50, {
    mass: 0.1.isStatic: false.collisionFilter: {
        category: categoryB,
    }
});
var _rect = Bodies.rectangle(250.500.400.50, {
    isStatic: true.collisionFilter: {
        category: categoryB,
        mask: categoryA 
    }
});
Composite.add(world, [_cricle, _rect]);
Copy the code

Two rigid bodies collide only if _rect’s mask is categoryA. This method has more matchability than group, so we can handle collisions better.

Four,

This chapter summarizes

This chapter focuses on the three stages of collision and their triggering events:

  • collisionStart
  • collisionActive
  • collisionEnd

It also shows how to set collision rules using the rigidbody collisionFilter property.

In the process of writing the document demo, I also encountered a bug, it seems that Matter also has unsatisfactory place.

The full text summary

That’s it for MatterJs. I wrote this series on a whim, and I’ve used the library many times myself, and I’ve been blown away by its lightness and ease of use.

In the process of writing articles also found a lot of problems, there are a lot of parts of the source code reading is not careful enough in-depth, write may be a bit different, look at you do not blame.

Subsequent version modification, or have a new idea, will continue to update this series of articles, free will also write combat games to meet you.

Previous articles present:

  • “A Preliminary Study on Physics Engine”
  • “Core Modules of MatterJs”
  • “Rigid bodies in the Physical world”
  • “Complexes in the physical world”
  • “Constraints in the Physical World”

This article is shallow, hope you don’t hesitate to your comments and praise ~ note: this article is the author’s painstaking work, reprint must be declared