Matter.js 2D 物理引擎试玩报告_matter引擎下载-程序员宅基地

技术标签: 移动开发  H5 物理引擎 matter  

何为物理引擎,能做什么?

物理引擎是一个计算机程序,使用质量、速度、摩擦力和空气阻力等变量,模拟了一个近似真实的物理系统,为刚性物体赋予真实的物理效果,比如重力、旋转和碰撞等效果,让物体的行为表现的更加趋向真实,例如,守望先锋的英雄在跳起时,系统所设置的重力参数就决定了他能跳多高,下落时的速度有多快,子弹的飞行轨迹等等。

四个例子不同的效果,模拟物体落入斜坡的表现

  • 无物理效果
  • 重力,没有碰撞效果
  • 重力和碰撞,没有旋转效果
  • 重力、碰撞以及旋转效果

物理引擎通常有两种常见类型:实时物理引擎和高精度物理引擎。高精度物理引擎需要更多的处理能力来计算非常精确的物理,通常使用在科学研究(计算物理学)和动画电影制作。实时物理引擎常用于电子游戏并且简化了算法,降低精确度以减少处理时间,使得在游戏中有更好的处理速度。

物理引擎在游戏中的应用

CS1.5 应用的是真实度比较差的物理引擎,人物死亡后倒地动作是固定的,即使有障碍物也会执行这个动作,所以人物穿过了门。

CS 1.5

而 CS:GO 因为采用了 Source Engine 开发,模拟较为精细,所以人物死亡之后的姿势可以根据物理学自动计算,所以可以躺在杆上,使游戏更加真实。

CS GO

Matter.js 介绍

Matter.js 是一个用于 Web 的 JavaScript 2D 物理引擎库,该项目诞生于 2014 年 2 月 28 号(0.5.0-alpha 版本),目前已更新迭代了 11 个版本(最新为 0.12.0 版本),它相较于老牌的 Box2D 引擎库,Matter.js 更为轻量级(压缩版仅有 84 KB),并且在性能和功能方面也不逊色。

在没有 Matter.js 前,你想去制作一个物理游戏不仅需要扎实数学知识和物理知识,并且需要通过编程语言表示出来让机器读懂。而有 Matter.js 就不一样了,它为开发者提供了许多的功能模块,通过简单易用的 API 就可以实现例如弹跳、碰撞、重力、滚动等物理效果。

Matter.js 介绍

Matter.js 下载

首先,需要下载开发版本或者稳定版定,并将脚本加入到页面中,即可开启旅程。

 

1

 

<script src="matter.js" type="text/javascript"></script>

你也可以使用包管理工具 Bower 或 NPM

 

1

 

$ bower install matter-js

 

1

 

$ npm install matter-js

Matter.js 支持的特性

刚体 复合体 复合材料
凹面和凸面 物理特性(质量、面积、密度等) 弹性(弹性和非弹性碰撞)
碰撞(粗略阶段、中间阶段、精细阶段) 稳定的堆叠和静止 动量守恒
摩擦力和阻力 事件监听 约束
重力 睡眠和静态物体 圆角(倒角)
视图(平移、缩放) 碰撞查询(射线追踪、区域测试) 时间缩放(减速、加速)
Canvas 渲染器(支持向量和纹理) MatterTools 工具(创建、测试和调试) 世界状态序列化,需要 resurrect.js
跨浏览器(Chrome、Firefox、Safari、IE8+) 兼容移动端(触摸、响应) 原生 JS 实现

Matter.js 中基础的概念

大多数的物理引擎对于物理模拟的要素都有着相近的概念,不同的引擎差别在于使用的方式,功能的全面性,模拟的精细度等层面,下面就先从物理世界的基础概念讲起。

Engine(引擎)和 World(世界)

Matter.Engine 模块包含了创建和处理引擎的方法,引擎是负责管理和更新模拟世界的控制器,引擎可以控制时间的缩放,可以检测所有的碰撞事件,并且拿到所有碰撞的物体对(pairs)。

在 Matter.js 中任何的物体都需要一个容身处,而存放这些物体的地方,我们称之为世界,物体必须添加到世界里,然后由引擎运行这个世界。而创建世界需要使用到 Matter.World 模块,该模块包含了用于创建和操作世界的方法,一个 Matter.World 相当于一个复合物体,物体、约束、复合物体的聚合体,其次世界还有额外的一些属性,比如重力、边界。

MatterJS_EngineAndWorld

Render(渲染)

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

 

// Matter.Render 用法

var engine = Engine.create();

// ... 将物体加入到世界中

var render = Render.create({

element: document.body,

engine: engine,

options: options

});

Engine.run(engine);

Render.run(render);

  • element 是一个容器元素,使用时指定要渲染的节点
  • engine 指定为 Matter.Engine 实例
  • options 指定一些渲染的参数

Matter.Render 是将实例渲染到 Canvas 中的渲染器,控制视图层的样式,它的主要作用是用于开发和调试,默认情况下 Matter.Render 将只显示物体的线框(轮廓),这对于开发和调试很有帮助,但如果需要使用到全局实体渲染则需要将线框模式关闭 render.options.wireframes = false,另外它同样也适合制作一些简单的游戏,因为它包括了一些绘图选项、线框、向量、Sprite 精灵和视窗功能。

MatterJS_EngineAndWorld

DEMO 戳这里

Body(刚体)

物体或者叫刚体,在物理引擎里特指坚硬的物体,具有固定的形状,不能形变。刚体可以用于表示一个箱子、一个球或是一块木头,每个物体都有自己的物理属性,质量、速度、摩擦力、角度等,还可以设置刚体的标记。Matter.Bodies 模块中内置了几种刚体,矩形 Matter.rectangle、多边形 Matter.polygon、圆形 Matter.circle 、梯形 Matter.trapezoid 等等。

MatterJS_EngineAndWorld

 

1

2

3

4

5

6

7

8

 

// 创建刚体

var rect = Bodies.rectangle(200, 100, 50, 50), // 矩形

circle = Bodies.circle(300, 100, 25), // 圆

polygon = Bodies.polygon(450, 100, 5, 25), // 多边形

trapezoid = Bodies.trapezoid(590, 100, 50, 50, 3); // 梯形

// 将刚体添加到世界中

World.add(engine.world, [rect, circle, polygon, trapezoid]);

DEMO 戳这里

Composite(复合体)

由刚体和复合材料通过约束组合在一起的就叫做复合体。复合体对外当作一个刚体,复合体的物理属性是通过所包含的刚体的属性综合计算出来的。Matter.Composite 模块包含用于创建和处理复合体的方法,另外还有一个 Matter.Composites 模块,提供了几种特别的复合材料,例如 链 Composites.chain、牛顿摆球 Composites.newtonsCradle、软体 Composites.softBody、汽车 Composites.car 、堆叠 Composites.stack 等等。

桥梁

MatterJS_EngineAndWorld

 

1

2

3

4

5

6

7

8

9

10

11

12

13

 

// 使用堆叠创建桥梁

var group = Body.nextGroup(true);

var bridge = Composites.stack(150, 300, 9, 1, 10, 10, function(x, y) {

return Bodies.rectangle(x, y, 50, 20, {

collisionFilter: { // 过滤碰撞

group: group

}

});

});

// 创建链约束

Composites.chain(bridge, 0.5, 0, -0.5, 0, { stiffness: 0.9 });

DEMO 戳这里

MatterJS_EngineAndWorld

 

1

2

3

4

5

6

7

8

9

10

 

// 软体

var cloth = Composites.softBody(200, 200, 20, 12, 5, 5, false, 8, {

friction: 0.00001, // 摩擦力

collisionFilter: {

group: Body.nextGroup(true)

},

render: {

visible: false

}

});

DEMO 戳这里

牛顿摆球

MatterJS_EngineAndWorld

 

1

2

 

// 创建牛顿摆球

var newtonsCradle = Composites.newtonsCradle(300, 320, 5, 25, 150);

DEMO 戳这里

Constraint(约束)

约束可理解为通过一条线,将刚体 A 和刚体 B 两个刚体连接起来,被约束的两个刚体由于被连接在了一起,移动就相互受到了限制。Matter.Constraint 模块包含了用于创建和处理约束的方法,这个约束可以很宽松,也可以很紧绷,还可以定义约束的距离,约束具有弹性,可以用来当作橡皮筋。

MatterJS_EngineAndWorld

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

 

// 创建一个矩形和圆形

var rect = Bodies.rectangle(400, 100, 50, 50, {

isStatic: true

}),

ball = Bodies.circle(400, 400, 50);

World.add(engine.world, [

rect,

ball,

Constraint.create({

bodyA: rect, // 约束刚体 A

pointA : { // 约束点 A

x: 0,

y: 0

},

bodyB: ball, // 约束刚体 B

pointB: { // 约束点 B

x: 0,

y: -50

},

stiffness: 0.6

})

]);

DEMO 戳这里

MouseConstraint(鼠标约束)

如果你想让刚体与用户之间有交互,那就要在鼠标和刚体之间建立连接,也就是鼠标和刚体间的约束,Matter.MouseConstraint 模块包含用于创建鼠标约束的方法,提供通过鼠标或触摸(移动端时)移动刚体的能力,可以设置什么标记的物体才能被鼠标操纵,创建鼠标约束后,可以捕获到鼠标的各类事件。

 

1

2

3

4

5

6

 

// 全局鼠标约束

var mouseConstraint = MouseConstraint.create({

element: render.canvas

});

World.add(engine.world, mouseConstraint);

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

 

// 设置某个标记的物体才能被鼠标操纵

var categoryBall = 0x0001; // 分类

var ball = Matter.Bodies.circle(300, 350, 32, {

density: 0.68, // 密度

restitution: 1, // 弹性

collisionFilter: {

category: categoryBall

}

});

var mouseConstraint = MouseConstraint.create({

element: render.canvas,

collisionFilter: {

mask: categoryBall

}

});

World.add(engine.world, mouseConstraint);

DEMO 戳这里

Vector(向量)

Matter.Vector 模块包含用于创建和操纵向量的方法,向量是引擎有关几何操作行为的基础,修改物体的运动状态基本都是使用向量来控制,例如赋予物体一个力,或者设置物体的速度、旋转角度,并且内置了多个向量的求解函数:向量积、标量积、格式化、垂直向量等等。

Events(事件)

Matter.Events 模块包含了绑定、移除和触发对象的方法。

  • 绑定事件 Matter.Events.on(object, eventNames, callback)
  • 移除事件 Matter.Events.off(object, eventNames, callback)
  • 触发事件 Matter.Events.trigger(object, eventNames, event)

Matter.js 中的一些属性

施加力

Matter.Body.applyForce(body, position, force) 方法可以给刚体施加一个力,传入 X 和 Y 轴需要的力度值,通过这个方法你可以去模拟踢一个足球、投一个篮球的效果。

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

 

var ball = Bodies.circle(300, 100, 25, {

density: 0.68, // 密度

restitution: 0.8 // 弹性

});

World.add(engine.world, ball);

function addForce() {

var forceMagnitude = 0.02 * ball.mass;

Body.applyForce(ball, ball.position, {

x : (forceMagnitude + Common.random() * forceMagnitude) * Common.choose([1, -1]),

y : -forceMagnitude + Common.random() * -forceMagnitude

});

}

addForce();

DEMO 戳这里

重力

可以设置 X、Y 轴的重力值,默认都为 1,参数在 0、1、-1 中选择使用。

 

1

2

3

4

5

 

// 实现反重力效果

engine.world.gravity.y = -1;

// 无重力效果

engine.world.gravity.y = 0;

DEMO 戳这里

睡眠状态

通过 enableSleeping: true 开启睡眠模式后,当刚体处于不受作用状态时,会进入睡眠状态,这样可以有效的提高引擎的性能,当物体被其他物体碰撞或者对刚体施加力时,刚体会被叫醒,引擎会继续对其进行计算模拟。

 

1

2

3

4

5

6

7

8

9

 

// 开启睡眠状态

var engine = Engine.create({

enableSleeping: true

});

// 还可以针对进入睡眠状态的刚体进行监听,比如将刚体移出世界

Event.on(ball, "sleepStart", function() {

World.remove(engine.world, ball);

});

DEMO 戳这里

摩擦力

摩擦力在 Matter.js 中分别提供了三种:摩擦力 friction、空气摩擦力 frictionAir 以及静止摩擦力 frictionStaticfriction 默认值是 0.1,取值范围在 0 - 1,当值为 0 意味着刚体可以摩擦力的无限滑动,1 意味着对刚体施加力后会立刻停止,frictionAir 默认值是 0.01,取值范围 0 - 1,当值为 0 意味着刚体在空间中移动时速度永远不会减慢,值越高时刚体在空间的移动速度越慢,frictionStatic 默认值 0.5,当值为 0 时意味着刚体几乎是静止的,值越高时意味着需要移动刚体所需的力就越大。

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

 

// 摩擦力

Bodies.rectangle(300, 70, 40, 40, {

friction: 0.01

})

// 空气摩擦力

Bodies.rectangle(300, 70, 40, 40, {

frictionAir: 0.05

})

// 静止摩擦力

Bodies.rectangle(300, 70, 40, 40, {

frictionStatic: 1

})

时间缩放

可以控制全局的时间,当值为 0 时为冻结模拟,值为 0.1 给出慢动作效果,值为 1.2 时给出加速效果。

 

1

 

engine.timing.timeScale = 0.1;

这里就简单提及到几个属性,当然还有更多的属性比如:视图(View)、弹性(Restitution)等等,更详细的 API 可到官网查看。

Matter.js 调试

除了前面讲 Matter.Render 模块的时候提到的线框模式 wireframes 便于调试外,Matter.Render 模块其实还为我们提供了以下几种方法,便于我们自定义调试选项:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

 

var render = Render.create({

element: document.body,

engine: engine,

options: {

width: 800,

height: 600,

pixelRatio: 1, // 设置像素比

background: '#fafafa', // 全局渲染模式时背景色

wireframeBackground: '#222', // 线框模式时背景色

hasBounds: false,

enabled: true,

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 // 鼠标约束线

}

});

另外官方提供了三个调试工具,可单独使用或一起使用,如下:

工具:

  • MatterTools.Demo 用于运行和测试 DEMO
  • MatterTools.Gui 改变引擎的属性
  • MatterTools.Inspector 检查世界

MatterJS_EngineAndWorld

官方 DEMO 戳这里

下载

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_22780533/article/details/82182874

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法