添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天, 点击查看活动详情

matter.js 是一个JS的2D的物理引擎,我们可以单独使用它或者用它配合Canvas,来实现一些物理效果,或者一些高级的Canvas动画。

一、安装和使用

  • 使用 script 标签引入使用
  • 使用 npm install matter-js 安装使用
  • 2.初始化

    // 起别名方便后面使用
    const Engine = Matter.Engine,
        Render = Matter.Render,
        Runner = Matter.Runner,
        Bodies = Matter.Bodies,
        Composite = Matter.Composite;
    // 创建一个物理引擎
    const engine = Engine.create();
    engine.gravity.y = 9.8 // 设置重力
    // 创建一个渲染器
    const render = Render.create({
      element: document.body,
      engine: engine,
        options: {
        pixelRatio: 1, // 设置像素比
          background: '#fafafa', // 全局渲染模式时背景色
          wireframeBackground: '#222', // 线框模式时背景色
          hasBounds: false,
          wireframes: true, // 线框模式
          showSleeping: true, // 刚体睡眠状态
          showDebug: false, // Debug 信息
          showBroadphase: false, // 粗测阶段
          showBounds: false, // 刚体的界限
          showVelocity: false, // 移动刚体时速度
          showCollisions: false, // 刚体碰撞点
          showSeparations: false, // 刚体分离
          showAxes: false, // 刚体轴线
          showPositions: false, // 刚体位置
          showAngleIndicator: false, // 刚体转角指示
          showIds: false, // 显示每个刚体的 ID
          showVertexNumbers: false, // 刚体顶点数
          showConvexHulls: false, // 刚体凸包点
          showInternalEdges: false, // 刚体内部边界
          showMousePosition: false // 鼠标约束线
    // 创建一个方块和一个地面
    var box = Bodies.rectangle(400, 200, 80, 80);
    var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });
    // 将他们加入到这个物理引擎中
    Composite.add(engine.world, [box, ground]);
    // 运行这个渲染器
    Render.run(render);
    // 创建一个运行环境,类似于U3D的Update函数
    var runner = Runner.create();
    // 开始渲染运行
    Runner.run(runner, engine);
    这里注意在创建ground时候,新增了个属性isStatic: true,这句话的意思是当前这个物体是静态的,即:只是一个刚体,拥有碰撞器,但是不会受重力影响,不会收到物理碰撞效果。

    engine.timing.timeScale = 0.1 可以设置冻结时间来控制慢放或者快放

    二、创建简单的物理几何刚体

    1. 创建圆和矩形

    const box = Bodies.rectangle(400, 200, 80, 80);
    const cir = Bodies.circle(200, 200, 40);
    

    2. 创建一个正多边形

  • Bodies.rectangle(x, y, n, r, option):n为正多边形的边数,r为正多边形半径
  • const pl = Bodies.polygon(200, 100, 8, 80, { 
      chamfer: { radius: 30 }
    

    3. 创建一个梯形

  • Bodies.trapezoid(x, y, w, h, slope): slope为斜率,当斜率为1时候,是三角形
  • const pl = Bodies.trapezoid(200, 100, 80, 100, 0.5)
    
    const pl = Bodies.trapezoid(200, 100, 80, 100, 1)
    

    三、创建组合物理几何刚体

  • Body.create({ parts: [shape1, shape2, ...] })
  • 创建一个三角形和矩形的组合体

    const t1 = Bodies.trapezoid(200, 100, 80, 100, 1)
    const r = Bodies.rectangle(200, 185, 80, 100)
    const cp = Body.create({ 
      parts: [t1, r]
    const ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });
    // 将他们加入到这个物理引擎中
    Composite.add(engine.world, [cp, ground]);
    

    四、碰撞检测

    Events.on(engine, 'collisionStart', function(e) {
      const pairs = e.pairs;
      pairs.forEach(pair => {
        console.log(pair);
    

    pairs 是一个数组,其中包含所有的碰撞对,遍历这个数组,可以拿到每一对碰撞对象的相关信息。

    五、力的施加

  • Body.applyForce(shape, shape.position, { x: number, y: number

    shape为被施加力的物体,x、y分别代表受力物体在x、y的受力大小。

    const r = Bodies.rectangle(200, 200, 100, 50)
    const ground = Bodies.rectangle(0, 300, 80000, 50, { isStatic: true })
    // 将他们加入到这个物理引擎中
    Composite.add(engine.world, [r, ground]);
    setTimeout(() => {
      Body.applyForce(r, r.position, {
        x: 0.2,
        y: 0
    }, 4000)
    

    六、鼠标操作约束

    如果你想使用鼠标进行交互,那么可以使用Matter.MouseConstraint 进行操作。

    const mouseConstraint = MouseConstraint.create(engine)
    // 将他们加入到这个物理引擎中
    Composite.add(engine.world, [r, ground, mouseConstraint]);
    

    七、其它配置和方法

    1. 可以为创建的物体设置弹性和密度

    const ground = Bodies.rectangle(0, 300, 80000, 50, { 
      density: 1, // 密度
      restitution: 0.8, // 弹性
      isStatic: true
    

    2. Composites.chain() 创建锁链

    const group = Body.nextGroup(true);
    const ropeA = Composites.stack(
      100,
      function (x: number, y: number) {
        return Bodies.rectangle(x, y, 50, 20, {
          collisionFilter: { group: group },
    Composites.chain(ropeA, 0.5, 0, -0.5, 0, {
      stiffness: 0.8,
      length: 2,
      render: { type: "line" },
    Composite.add(
      ropeA,
      Constraint.create({
        bodyB: ropeA.bodies[0],
        pointB: { x: -25, y: 0 },
        pointA: { x: ropeA.bodies[0].position.x, y: ropeA.bodies[0].position.y },
        stiffness: 0.5,
    const mouseConstraint = MouseConstraint.create(engine)
    // 将他们加入到这个物理引擎中
    Composite.add(engine.world, [ropeA, mouseConstraint]);
    

    3. 摩擦力

    matterjs摩擦力有三种:

  • 普通摩擦力 friction
  • 空气摩擦力 frictionAir
  • 静止摩擦力 frictionStatic
  • const ground = Bodies.rectangle(0, 300, 80000, 50, { 
      friction: 1
    

    matterJs还可以创建很多其它物理材质的物体,比如说,软球,小汽车,牛顿摆等等,大家可以去官方Demo查看更多的例子,如果你觉得本文帮助了你,请您给我个攒👍🏻。

  •