物理引擎box2d的学习心得

1 前言

     最近学习libgdx的时候暂时先没看box2d那部分,昨天想做个物理效果看了一下那部分的封装,发现没点概念太难看懂了,还是乖乖的把box2d先系统的学习一遍。这个资料网上很多,最好的自然是官方的用户手册,还有热心网友把翻译成中文的了。还是老习惯,学完以后留点东西以备忘。

2 基础知识

    以下内容对理解物理引擎非常重要,摘自用户手册,这部分主要是给自己做备忘,强烈建议读者把《box2d中文手册》研读一遍。

2.1 必要知识

质量(mass),力(force),扭矩(torque)和冲量(impulses),这个不懂看看物理知识。

2.2 核心概念

形状(shape)

2D几何对象, 比如圆形(circle)或多边形(polygon)。

刚体(rigid body)

十分坚硬的物质, 坚硬得像钻石,它上面任意两点之间的距离都保持不变。在后面的讨论中,我们用物体(body)来代替刚体。(这就使得物体本身不会产生形变,那软软弹弹的效果应该都是动画)

夹具(fixture)

fixture将形状绑定到物体之上, 并有一定的材质属性, 比如密度(density), 摩擦(friction)和恢复(restitution)。

(译注:一个物体和另一物体碰撞, 碰撞后速度和碰撞前速度的比值会保持不变,这比值就叫恢复系数。)

约束(constraint)

约束是个物理连接, 用于消除物体的自由度。在2D中, 物体有3个自由度(水平,垂直,旋转)。如果我们把一个物体钉在墙上(像钟摆那样), 那就把它约束到了墙上。这个时候,此物体就只能绕着钉子旋转, 所以这个约束消除了它2个自由度。

(译注:简单的说, 需要用几个参数来确定物体的空间状态, 这个物体就有几个自由度。在二维中,完全没有约束的条件下, 我们要确定物体的状态, 要有x坐标, y坐标, 旋转角这三个参数, 所以自由度为3。如果物体被钉在墙上, 只要有旋转角,就可以完全确定物体的状态,有了钉子这个约束,物体自由度就变成了1。)

接触约束(contact constraint)

一种特殊的约束, 设计的目的是为了防止刚体被穿透, 也用于模拟摩擦和恢复。接触约束不用你来创建, 它们会自动被Box2D生成。

关节(joint)

关节就是种约束, 用于将两个或多个body固定到一起。Box2D支持不同的关节类型:转动(revolute),棱柱(prismatic),距离(distance)等。一些关节可以有限制(limits)和马达(motors)。

关节限制(joint limit)

关节限制限定了一个关节的运动范围。例如人类的胳膊肘只能在某一角度范围内运动。

关节马达(joint motor)

根据关节的自由度, 关节马达可以驱动关节所连接的物体。例如, 你可以使用一个马达来驱动一个肘的旋转。

世界(world)

一个物理世界就是各种, 刚体(bodies), 夹具(fixtures), 约束(constraints)相互作用的集合。 Box2D支持创建多个世界, 但这通常没有必要。

box2d的内存是自己管理的,他建立了一个内存池,以减少对内存的频繁的申请和释放。所以所有对象都要box2d帮你创建,也就是libgdx中的world。

2.3 模拟物理世界的相关算法

积分器(integrator)的数值算法:在离散的时间点上模拟连续的物理方程它与传统的游戏动画循环一同运行。我们需要为Box2D选取一个时间步。通常来说用于游戏的物理引擎需要至少 60Hz 的速度,也就是 1/60 的时间步。你可以使用更大的时间步,但是你必须更加小心地为你的世界调整定义。我们也不喜欢时间步变化得太大,所以不要把时间步关联到帧频(除非你真的必须这样做)。直截了当地,这个就是时间步:

约束求解器(constraint solver):用于解决模拟中的所有约束,一次一个。单个的约束会被完美的求解,然而当我们求解一个约束的时候,我们就会稍微耽误另一个。要得到良好的解,我们需要多次迭代所有约束。所以就有必要控制迭代计算的次数以防止无限循环,推荐迭代次数为10能较好的模拟效果。

2.4 fixture中一些有意思的概念

密度(Density)

fixture的密度用来计算父物体的质量属性。密度值可以为零或者是整数。你所有的fixture都应该使用相似的密度,这样做可以改善物体的稳定性。

当你添加一个fixture时,物体的质量会自动调整。

摩擦(Friction)

摩擦可以使对象逼真地沿其它对象滑动。Box2D支持静摩擦和动摩擦,两者都使用相同的参数。摩擦在Box2D中会被精确地模拟,摩擦力的强度与正交力(称之为库仑摩擦)成正比。摩擦参数经常会设置在0到1之间, 也能够是其它的非负数,0意味着没有摩擦, 1会产生强摩擦。当计算两个形状之间的摩擦时,Box2D必须联合两个形状的摩擦参数。

恢复(Restitution)

恢复可以使对象弹起。恢复的值通常设置在0到1之间。想象一个小球掉落到桌子上,值为0表示着小球不会弹起, 这称为非弹性碰撞。值为1表示小球的速度跟原来一样,只是方向相反, 这称为完全弹性碰撞

传感器(Sensors)

有时候游戏逻辑需要判断两个fixture是否相交,但却不应该有碰撞反应。这可以通过传感器(sensor)来完成。传感器也是个fixture,但只会侦测碰撞而不产生其它反应。

2.5 body中一些有意思的概念 

阻尼(Damping)

阻尼用于减小物体在世界中的速度。阻尼跟摩擦有所不同,摩擦仅在物体有接触的时候才会发生。阻尼并不能取代摩擦,往往这两个效果需要同时使用。 

休眠参数(Sleep Parameters)

休眠是什么意思? 模拟物体的成本是高昂的,所以如果物体更少,那模拟的效果就能更好。当物体停止了运动时, 我们会希望停止模拟它 

固定旋转(Fixed Rotation)

你可能想一个刚体,比如某个角色,具有固定的旋转角。这样物体即使在负载下,也不会旋转。

子弹(Bullets)

游戏模拟通常以一定帧率(frame rate)产生一系列的图片。这就是所谓的离散模拟。在离散模拟中,在一个时间步内刚体可能移动较大距离。默认情况下,Box2D会通过连续碰撞检测(CCD)来防止动态物体穿越静态物体。一般情况下,dynamic物体之间不会应用CCD,这是为了保持性能。

3 libgdx中的box2d

3.1 libgdx的优势

    有个不得不说的优点,box2d用户手册里面有相当篇幅在说如何管理内存和引用,这个对于java程序而言真的是再不用多考虑了。

    另外,jbox2d版本在性能方面有些问题,但牛逼的是libgdx是通过jni调用的box2d的c++版本。

3.2 如何将actor和body联系起来

    这个问题真的有点让我困扰,我们期望的效果自然是actor能带上物理特性,但遗憾的是不能直接这么指定。这就造成了一个是在物理世界移动的物理,一个是动画世界的图片,两者却没有了直接关系。所以这就需要将这两个东西联系在一起,然后同步两者的为止。

    目前觉得比较好的方式就是在上层再做一次封装,将actor和相应的body绑定在一起,每帧都先让body去计算位移,然后再调整actor的位置。

4 总结

    物理引擎真的很强大,能通过对物理定义就变成一个可以按物理逻辑运行的效果,但在这之前对于box2d的概念必须有所了解。在libgdx中调用box2d还是比较方便的,就是可惜还要自己去绑定。



本文转自passover 51CTO博客,原文链接:http://blog.51cto.com/passover/804566,如需转载请自行联系原作者

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值