When I first tried box2dWeb in conjunction with the CAX framework, I found that box2dWeb’s code would cause the caX package modules compiled by WebPack to be executed out of order. Box2dweb also seems to have no official documentation or maintenance address, so ditch the pit and switch to Matter-js.

Matter-js is the most popular Web 2D physics engine on Github. It has the following features:

  • Support rigid body, hybrid, complex
  • Support convex polygon rigidbody
  • Interrigid body constraints are supported
  • Built-in sleep and rest body
  • Physics simulation time speeds up and slows down
  • Mobile compatibility (touch event and PC mouse event response)
  • Physical properties (mass, area, density, conservation of momentum, frictional resistance, gravity, elastic or non-collision detection, recovery, etc.)

Start combining Cax with Matter-js

The introduction of js

Let’s start with mate-js and CAx in HTML. You can get js via NPM or CDN:

  • unpkg.com/matter-js
  • unpkg.com/cax

The preparatory work

Add Canvas to page

<canvas id="myCanvas" width="800" height="600"></canvas>
Copy the code

Declare variables in advance:

var Engine = Matter.Engine,
            Render = Matter.Render,
            World = Matter.World,
            Bodies = Matter.Bodies,
            Composites = Matter.Composites,
            Body = Matter.Body,
            Constraint = Matter.Constraint,
            MouseConstraint = Matter.MouseConstraint,
            Common = Matter.Common,
            Events = Matter.Events,
            Composite = Matter.Composite
Copy the code

Create a rigid body

Bodies.rectangle(100.49.800.44, { isStatic: true })
Copy the code
  • The first four parameters represent x, y width and height respectively. Notice that x and y are the coordinates of the center of the rectangle
  • isStaticTrue indicates a stationary rigid body, no transmission or false indicates a movable rigid body.

Create four walls and add to the world

// Create engine
var engine = Engine.create();

// Create four walls and add walls to the world
var offset = 10;
World.add(engine.world, [
    Bodies.rectangle(400.600 - offset, 800, offset * 2, { isStatic: true }),
    Bodies.rectangle(400, offset, 800, offset * 2, { isStatic: true }),
    Bodies.rectangle(offset, 300, offset * 2.600, { isStatic: true }),
    Bodies.rectangle(800 - offset, 300, offset * 2.600, { isStatic: true}));Copy the code

Create objects and add them to the world

var stack = Composites.stack(20.20.6.4.0.0.function (x, y) {
    if (Common.random() > 0.5) {
        return Bodies.rectangle(x, y, 64.64, {
            bitmap: new cax.Bitmap("img/box.jpg")}); }else {
        return Bodies.circle(x, y, 46, {
            desity: 0.0005.frictionAir: 0.06.friction: 0.01.bitmap: new cax.Bitmap("img/basketball.png")}); }}); World.add(engine.world, stack);Copy the code

Stack (xx, YY, columns, Rows, columnGap, rowGap, callback) can be used to create object stacks. Xx and yy are the x and y coordinates of the first object in the object heap, columns and rows are the number of columns and rows of the object heap to be created, columnGap and rowGap are the columnGap and rowGap between objects, and finally, Callback (x, y, column, row, lastBody, I); You can see that callback is a method that generates a concrete object.

Look to see the subsequent rendering of the user that hangs on the bitmap when it is created.

Start the engine

Engine.run(engine)
Copy the code

Initialize render walls and objects

var bodies = Composite.allBodies(engine.world);

for (var i = 0; i < bodies.length; i += 1) {
    var obj = bodies[i]
    if (obj.bitmap) {
        obj.bitmap.x = obj.position.x
        obj.bitmap.y = obj.position.y
        if (obj.label === 'Circle Body') {
            obj.bitmap.scaleX = obj.bitmap.scaleY = 92 / 128
            obj.bitmap.originX = 64
            obj.bitmap.originY = 64
            obj.bitmap.rotation = obj.angle * 180 / Math.PI
        } else {
            obj.bitmap.scaleX = obj.bitmap.scaleY = 64 / 200
            obj.bitmap.originX = 100
            obj.bitmap.originY = 100
            obj.bitmap.rotation = obj.angle * 180 / Math.PI
        }
        stage.add(obj.bitmap)
    }
}

/ / wall
var topRect = new cax.Rect(800.20, { fillStyle: '#2CB044' })
stage.add(topRect)
var bottomRect = new cax.Rect(800.20, { fillStyle: '#2CB044' })
bottomRect.y = 600 - 20
stage.add(bottomRect)
var leftTop = new cax.Rect(20.600, { fillStyle: '#2CB044' })
stage.add(leftTop)
var rightRect = new cax.Rect(20.600, { fillStyle: '#2CB044' })
rightRect.x = 800 - 20
stage.add(rightRect)
Copy the code
  • throughComposite.allBodiesYou can get all rigid bodies
  • The rigidbody size corresponds to the texture size by setting the Bitmap’s scaleX and scaleY

Update render stage

cax.setInterval(function () {
    var bodies = Composite.allBodies(engine.world);
    for (var i = 0; i < bodies.length; i += 1) {
        var obj = bodies[i]
        if (obj.bitmap) {
            obj.bitmap.x = obj.position.x
            obj.bitmap.y = obj.position.y
            obj.bitmap.rotation = obj.angle * 180 / Math.PI
        }
    }

    stage.update()
}, 16)
Copy the code

Add Matter-js built-in Debug Canvas

var render = Render.create({
    element: document.body,
    engine: engine,
    options: {
        wireframes: false}});var renderOptions = render.options;

renderOptions.wireframes = true;
Render.run(render);
Copy the code

End result:

【→ Online demo 】