Day13. 对面的女孩看过来,我们的镜头看过来 - Bounds

只要是「看」这个行为,都会牵扯到怎麽看,就像拍照的角度,电影的运镜,第一人称的视角等等,我们今天要来聊聊,怎麽移动 Matter.js 中关注在 Canvas 上的视角。毕竟 Canvas 座标世界广大无边,如果妥善运用视角移动,可以让许多显示效果更有质感。

今天的Demo
今天的Demo原始码

https://ithelp.ithome.com.tw/upload/images/20210928/20142057uKRr0HjM3f.png

谈到视角,就要说到 render 模组, 首先要让我们後面的动作生效,必须要在创建的时候把 hasBounds 设定开起来:

var render = Render.create({
    element: document.body,
    engine: engine,
    options: {
        width: 800,
        height: 600,
        background: '#000000',
        hasBounds: true,//<-----This one
        enabled: true,
        wireframes: false,
        showSleeping: true,
        showStats: true,
        showVelocity: true,
        showCollisions: true,
        showSeparations: true,
        showPositions: true,
        showAngleIndicator: true,
        showIds: true,
    }
});

Bounds 模组其实本身是用来操控物体的创建和操作AABB盒,主要是用於碰撞检测的。那为什麽我们今天会提到这个模组呢?因为要操作 render 的视角的时候,我们会操作的其实是 render 底下的 render.bounds。

bounds 有一些方法:

  • create
  • contains
  • overlaps
  • shift
  • translate
  • update

前三个方法看名字应该可以了解会是跟碰撞那边比较相关的,今天就不带到,那些在一般的实作里面多会交给 Matter.js 自己处理,我们今天来看怎麽透过後三个方法来操控画面的视角:render.bounds 。

bounds的型别是由两个向量构成,一个是min ,一个是 max。

min 跟 max 都是一个向量,资料结构会像是:

{
	max: {x: 800, y: 600}
	min: {x: 0, y: 0}
}

操作的时候要注意,不要当成一般的向量型别来使用。

如果这样不了解的话,可以看一下下面这个图:

https://ithelp.ithome.com.tw/upload/images/20210928/20142057jpb9nDAyF7.png

主角会是上面两个,不过这次的内容在API文件上的说明比较不直观,但是这次原始码的逻辑相对单纯,我们可以看一下原始码。

Bounds.translate = function(bounds, vector) {
    bounds.min.x += vector.x;
    bounds.max.x += vector.x;
    bounds.min.y += vector.y;
    bounds.max.y += vector.y;
};

大家可以看到 translate 是直接将传入的 x,y 座标加入,同时於 min/max 的 x/y 加上这个平移。

当 render 套用这个方法,就等同像指定的方向平移,一般我们如果要做运镜或跟随镜头,应该都会使用这个方法,再来来看 shift 方法。

Bounds.shift = function(bounds, position) {
    var deltaX = bounds.max.x - bounds.min.x,
        deltaY = bounds.max.y - bounds.min.y;
        
    bounds.min.x = position.x;
    bounds.max.x = position.x + deltaX;
    bounds.min.y = position.y;
    bounds.max.y = position.y + deltaY;
};

shift方法会做的事是维持整个 bounds 的大小,同时将 min 的位置移到我们传入的位置上,所以这个方法可以用到重制视角,一般 render 预设的 bounds min 会是在 (0,0) 的位置,当你对他做了任何位移操作,你想要重置的时候就可以用 shift 让 min 回到 (0,0) 的位置。

说主要前两个会用到是笔者看了一下 update 的原始码,但是不太确定它的目的,他是传入一组顶点阵列,遍历顶点阵列後 max 会是阵列中最大的, min 会是阵列中最小的。最後传入的 velocity 是一个向量,依据向量来决定要拓张目前的 bounds 或是缩小 bounds。

目前没有想到特别的情境,感觉比较像是 Matter.js 结合其他机制使用的。

Bounds.update = function(bounds, vertices, velocity) {
    bounds.min.x = Infinity;
    bounds.max.x = -Infinity;
    bounds.min.y = Infinity;
    bounds.max.y = -Infinity;

    for (var i = 0; i < vertices.length; i++) {
        var vertex = vertices[i];
        if (vertex.x > bounds.max.x) bounds.max.x = vertex.x;
        if (vertex.x < bounds.min.x) bounds.min.x = vertex.x;
        if (vertex.y > bounds.max.y) bounds.max.y = vertex.y;
        if (vertex.y < bounds.min.y) bounds.min.y = vertex.y;
    }
    
    if (velocity) {
        if (velocity.x > 0) {
            bounds.max.x += velocity.x;
        } else {
            bounds.min.x += velocity.x;
        }
        
        if (velocity.y > 0) {
            bounds.max.y += velocity.y;
        } else {
            bounds.min.y += velocity.y;
        }
    }
};

今天的 Demo让大家可以用上下左右操作视角,也可以改动一次视角的偏移位置大小。

Reset 的按钮会让视角重置到 0 的位置,第一排的 alert 可以让你知道目前的 bounds 的位置,建议大家可以尝试操作看看,体验一下 render.bounds 的移动对视角产生的变化。

今天视角的介绍就到这里,也带大家看了几个原始码的逻辑,我们後面的实作上会套用这个方式,来让我们的视角移动更符合我们的预期。


<<:  如何衡量万事万物 (7) 误差

>>:  Day-28 轻松使用Excel生成乱数并排名

鬼故事 - 为什麽骇客一直回来

鬼故事 - 为什麽骇客一直回来 鬼故事 故事回到我们小新的身上, 小新公司最近被骇客入侵,身为网管兼...

会计,审计和问责制(Accounting, Auditing, and Accountability)& 用户和实体行为分析(UEBA)

日志是会计的工作成果。可以通过查看或检查(审核)一组相关日志(审核记录)以唯一地将活动跟踪到实体来实...

D22 Django-bootstrap 网站美化工程 - fontawesomefree icon

为了Google的icon还有未来应该会需要加入一些icon所以安装个好用的python包 cons...

在威胁建模中的发现了多个 攻击向量(attack vectors),要如何操作(优先顺序)才能解决攻击面?

优先顺序需要基於一些标准。通常基於风险敞口对风险进行优先级排序,同时考虑风险的可能性和影响。 例如,...

第四章之二

接续先前所述,Hostinger提供非常多工具可以使用,这次就介绍一些非常实用且无须懂太多如终端机指...