box2d中物体移动的功能实现细节

最近把box2d研究了一遍,总体上差不多是了解了,但是在运行那个小球下落的demo时候发现移动速度与物理情况不一样,服务器空间,仔细研究了半天才发现原来有这么多细节概念要注意。这必须记录下来,对以后有同样问题的人肯定会有所启发。

物理模型:

一个边长为1m的正方形盒子悬停在20m高的位置,然后自由落体。根据公式h=gt^2/2可知下落到0m高时应该是2s。

对应box2d的模型:

一个形状为边长为1m的正四角型,不存在任何阻尼,放在20m高的空中,然后设置向下引力为9.8m/s^2。

注意一:单位换算

这个地方是新手最容易出错的。由于libgdx中的距离单位都是px,但box2d的距离单位都是m,所以你程序中所有要计算的值都要确保单位正确。

具体来说,比如我的显示器分辨率是1440px*900px,那我创建一个游戏界面为200px*200px的,如new JoglApplication(new DemoGame(), "Demo Demo", 200, 200, false);。这个很好理解,你的整个游戏界面就是这个大小,与显示器的分辨率是正比关系。

然后,游戏中会有一个camera来看具体的界面内容,这里只考虑正投影摄像机(不会因为距离对界面放大或者缩小),那么定义其能看到的也是200px*200px的画面new OrthographicCamera(200, 200),这 样就真的是画面上的1px代表你显示器的1px了。camera大小的变化是你游戏中的1px与实际显示器1px是成反比的。我觉得这个与游戏界面设置一样最好理解了。

那如果我希望10个像素代表1m(scale=10px/m),那计算出来的每个物体位移1m,你对应的actor都要移动10个像素。就是这么个换算关系。

注1:box2d中的单位都是标准单位,比如长度就是m,香港虚拟主机,重量就是kg。

注2:box2d的物理计算与画面上的actor是分开的,需要把物理数据再通过同步来反应到actor上。但是在Box2DDebugRenderer可以直观的看这个物理世界。

注意二:最大速度限制

这个时候物体移动起来有点意思了,当把世界引力加到很大,网站空间,诡异的事情发生了,开始还是加速运动,突然到后面明显变成匀速运动了。查了一遍资料才发现,原来box2d把每帧位移限制在2m/frame,所以在60Hz的刷新率情况下物体最大移动速度就是120m/s了。悲剧的是这个限制是hard coding,这可能是让物体看起来移动比较连续吧。所以要把速度加上去,那就只能提高帧数了,比如world.step(1/100f, 3, 3);能提高最大速度就是200m/s,但这么修改会有一个严重的问题,就是让物体位移的时间刻度和实际时间不一致了,画面看上去会和人感知不一样。

注:timestep是时间步长,这是动画里面一个重要概念,物理世界每次计算出来新的位置就必须要知道过了多久时间,这就让离散的时间点计算变成一个连续的动画。

注意三:初始化的影响

以上工作都做好了,发现下落时间怎么统计都不对。弄了半天才发反应过来原来第一次render的时候就已经开始计算物体移动了,并且把这个deltaTime带入进去计算了。由于初始化速度会比较慢,程序远达不到60Hz的刷新度,所以我把那个时间作为第一次下落时间其实是已经晚了的。所以干脆把第一次render再让每个物体唤醒,这就得到期望的结果了。

附上测试代码:

你有没有这样的感觉,坐在一列火车上,

box2d中物体移动的功能实现细节

相关文章:

你感兴趣的文章:

标签云: