Day22. 当苹果掉到牛顿头上,牛顿被敲醒了 - Gravity

一开始到现在,虽然我们没有特别提到,物体就那麽自然的向下掉,就像苹果掉到牛顿头上的自然,这背後的理所当然,就是重力在作用。今天我们要来介绍 engine 上的 gravity 参数,我们来看看,怎麽操纵 matter.js 世界中的重力。

今日的Demo
今日的Demo原始码
https://ithelp.ithome.com.tw/upload/images/20211007/20142057Qx67mFiTTL.png

如上段开头引言说的,gravity 是挂在 matter.js 里面的一个参数,所以我们可以很容易地来调整它。

它是一个物件,形式如下:

engine.gravity = {
                x: 0,
                y: 1,
                scale: 0.001
            };

基本上这三个数值就能够操控重力的表现了。

如我们的Canvas的座标轴一样,Y上到下是小到大,X左到右是小到大。
https://ithelp.ithome.com.tw/upload/images/20211007/20142057mhNHM4lKVR.png
预设的值是如上面展示物件结构的一样,没有横向重力,y 轴重力为 1 表示向下(Canvas Y往下为正向),只有如地球一样向下的重力,scale 是一个常数,用来同时对 x y 施加倍数增量。

我们可以稍微看一下套用重力的原始码

/**
 * Applys a mass dependant force to all given bodies.
 * @method _bodiesApplyGravity
 * @private
 * @param {body[]} bodies
 * @param {vector} gravity
 */
Engine._bodiesApplyGravity = function(bodies, gravity) {
    var gravityScale = typeof gravity.scale !== 'undefined' ? gravity.scale : 0.001;

    if ((gravity.x === 0 && gravity.y === 0) || gravityScale === 0) {
        return;
    }
    
    for (var i = 0; i < bodies.length; i++) {
        var body = bodies[i];

        if (body.isStatic || body.isSleeping)
            continue;

        // apply gravity
        body.force.y += body.mass * gravity.y * gravityScale;
        body.force.x += body.mass * gravity.x * gravityScale;
    }
};

这边可以看到有 matter.js 中有预写一个函式,会是针对传入的所有物体作重力施加判断,但忽略 isStatic和 isSleeping 的物体。其他一般物体会被视作分别对 x y 轴施力,x y 轴施力的公式为物体本身的重量乘上 scale 增量与对应方向 x y 的重力。

使用情境也不难想像,我们可以在 engine.update 中找到呼叫的痕迹

Engine._bodiesApplyGravity(allBodies, engine.gravity);

也就是定期透过每次呼叫来对物体施加稳定、定向的力。

matter.js 实作的 engine.gravity 有一个限制,就是整个 engine 就是所有物体遵照同一个 gravity 数值,虽然一般来说重力在区块内是单一量级很正常,但是有时候还是会有特殊需求,比如依距离或一些其他变因持续施不同方向的力。

理解後其实如果有需要,我们大可直接仿造上面的方式,自己撰写,对物体类重力的处理方式(说到底重力其实就是力的一种、对物体施力即可表现力的存在),就如同上面的倚赖质量与轴向力。

如果要做到无重力,就是把两个轴向的力调成 0 就可以了。

但依据上面的实作可以了解,两轴向为0表示不对物体施力,物体本身也是不会浮起来的,只会维持在原位。

读者可以用今天的 Demo 页面尝试对三个参数做调整,看一下在两个轴向的施力上做变化物体会如何移动。
https://ithelp.ithome.com.tw/upload/images/20211007/201420574HDOKJACDQ.png
今天关於重力的介绍就到这里,也带读者走过了实作原始码,增加了一些情境下的客制想像。

可以预告一下重力会在我们最後一个专案里扮演一个重要的角色,大家敬请期待。


<<:  网路是怎样连接的(七)TCP的交互(下)

>>:  [Day22] 发送验证信API – views

Day44 ( 电子元件 ) 触碰开灯 ( 类比讯号 )

触碰开灯 ( 类比讯号 ) 教学原文参考:触碰开灯 ( 类比讯号 ) 这篇文章会介绍如何使用「序列写...

Day03:浅谈 Git 和 GitHub

Git Git 是一个开源的分布式版本控制系统, 允许我们跟踪档案异动, 最初目的是为更好地管理 L...

Day1 # Let's Go!

Go(又称 Golang)是 Google 开发的程序语言,详细简介在 wiki 上都可以找得到。 ...

马可夫模型

马可夫模型 (Markov Model) 会用来表达状态以及转移机率及它们的随机过程使用的模型,或许...

Day 1 Hello Playground!

今天是开赛第一天,我会透过接下来的30天,从基本的东西慢慢讲起,然後再慢慢地加深难度,可以说一边透过...