拥抱物理世界-MatterJs(一)

自由落体运动

物体只在重力的作用下从静止开始下落的运动.

一、物理公式

/** 不计摩擦阻力 */
h = ½ * g * t²
v =  g * t
∆h = g * ∆t²
复制代码

二、使用js实现一个自由落体

创建一个小球div.
思路:
1、使用计时器模拟loop循环.
2、小球每隔时间t运动一段距离g * t.
3、碰触地面模拟动能衰减.即初速度衰减为_s * speed.

代码实现:

/** 
 * 自由落体
 *  h = ½ * g * t²
 */
var block = document.getElementById('block');
var _timer = null;
/** 速度 */
var speed = 0;
/** 高度 */
var _h = 400;
/** 重力 */
var _g = 0.02;
/** 间隔时间 */
var _t = 10;
/** 衰减系数 */
var _s = -0.9;
/** 小球高度 */
var _offsetH = block.offsetHeight;

function startMove() {
    clearInterval(_timer);
    block.style.top = '0px';
    _timer = setInterval(function () {
        speed += _g * _t * _t;
        var _topY = block.offsetTop + speed;
        if (_topY > _h - _offsetH) {
            _topY = _h - _offsetH;
            speed *= _s;
        }
        block.style.top = _topY + 'px';
    }, _t);
}
复制代码

三、使用matterjs实现自由落体

在MatterJs中,world默认是一个复合体Composite;
并给物理世界一个1的重力.

var engine = Engine.create(),
        world = engine.world;
/** 重力 */
world.gravity.y = 1;
复制代码

使用MatterJs自带的渲染器Render渲染出物理世界.

var render = Render.create({
    element: document.body,
    engine: engine,
    options: {
        width: 800,
        height: 600,
        showVelocity: true
    }
});
Render.run(render);
复制代码

使用Runner进行物理世界循环.

/** 创建运行时 */
var runner = Runner.create();
Runner.run(runner, engine);
复制代码

在物理世界中创建一个地面和一个小球

/** 创建物体 */
var _circle = Bodies.circle(200, 10, 20, {
    isStatic: false
});
Composite.add(world, [
    Bodies.rectangle(400, 400, 800, 10, {
        isStatic: true
    }),
    _circle
]);
复制代码

这个时候小球已经可以自由落体了,但是没有反弹效果.
现在我们给小球添加以下属性:

  • 质量
  • 弹性
  • 硬度
/** 硬度 */
_circle.stiffness = 0.1;
/** 弹性-衰减  */
_circle.restitution = 0.8;
/** 物体质量 */
_circle.mass = 0.1;
复制代码

这就完成了一个小球的自由落体.

相比较手写的自由落体.用matterJs模拟更真实.
代码看起来手写的好像更简洁一些,但是:

  • 我们需要多个物体呢?
  • 多个物体之间需要碰撞呢?
  • 需要实现复杂的物体交互呢?
  • 需要模拟各种不同的环境呢?

这个时候我们再去一点代码一点代码的去写,那这个工程量就很巨大了.
而物理引擎能更好的帮助我们创建并完成需求.
后续我们再讲具体的方法.

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享