2D物理游戏性能问题(libgdx box2d in android)

2D physics game performance problems (libgdx box2d in android)

我正在制作一款类似于 earn to die 2 的 2D 汽车游戏。我已经快完成了。唯一的问题是物理引擎的性能。我正在使用 box2d 并且有 10 米长的边缘形状完全构建了 100 公里的地形。 1辆车,通常30-40个箱子。活动动态物体的数量约为 60-100,最多 120。游戏在桌面上流畅运行,但在 android fps 下,当活动物体超过 60 时,fps 下降到 30 以下。汽车和箱子之间以及箱子彼此之间存在碰撞并且盒子和汽车都接地。

我正在使用 libgdx 框架 1.9.4 作为版本,java 是 1.7,使用 eclipse neon 编码,windows 7.

这就是我计算世界活跃度的方式

    int num=0;
    Array<Body> bodies=new Array<>();
    world.getBodies(bodies);
    for(Body b:bodies){
        if(b.isActive())num++;
    }

活跃动态体通常在100个左右

这不是所有地形和地下网格的绘图问题,汽车和箱子花费 6-7 毫秒我在 box2d 调试渲染关闭时测量它们并且世界步骤方法调用花费大约 30 毫秒当有大约30 个箱子,而汽车正在碾压它们

我没有加载所有游戏对象(现在是盒子)我将整个地图分成块地图大小为 100 公里,当汽车在接下来的 50 米(在块范围内)时,块大小为 50 米我从准备好的池中加载框(这些对象的 box2d 世界表示也被池化,当框在池中时,我使用 setActive(false) 停用它们的 box2d 主体,并在加载块时返回 true)

我也将这个区块系统应用于地形。我在游戏加载时加载所有地形,然后通过使用此方法 setActive(false) 设置来停用它们,当汽车在地图上行驶时,如果块范围包括汽车的 x 轴坐标,我激活下一个包含静态地形的块bodies有大约20个大小为10米的固定装置,使得chunk的大小总共为200米。

绿线是激活的地形形状,如您在禁用一段距离后左右看到的那样,直到地图的尽头这部分是在 100 公里地形图中间的地图的大约 60 公里处。

当车辆稍微移动时,更多新箱子会在前面装载,旧箱子如果距离汽车后方 20 米,则会被集中在一起。

我的问题是

1) 这个 fps (20 fps) 是正常的和预期的吗?(android 7 这是 phone 规格 http://www.androidpolice.com/2016/02/23/the-general-mobile-gm-5-plus-is-the-most-powerful-android-one-device-yet/)

2) 100 公里的地形会不会有问题,如果是,我应该如何管理它?

->我尝试了 activating/deactivating 地形实体,当它们超出屏幕矩形时。

->我在一个物体上尝试了数百个固定装置,或者每个地形块都是独立的物体,但最好的性能是我将 100 公里的地形分成 200 米的块,每个块都是一个物体,由大约 20 个固定装置组成。

3) 模拟 100 个具有巨大边缘形状地形的动态物体是完全不可能的吗? (但为了死而复生他们做到了)

4) 我应该只为这种游戏(一个简单的特定游戏)编写自己的简单物理吗?

5) 我应该使用 bullet physics 而不是 box2d 来实现 2D 目的吗?可能吗?我会遇到性能问题吗?

如果需要任何代码请评论,我会添加。

是否有任何我在网上找不到的非常快的物理引擎,如果有,您建议更改 box2D 吗?

注意事项:

我正在用常数时间步长模拟 box2d 我试过 1/60 1/45 1/30 和 8-3 , 6- 2 作为迭代步骤。

我对线性使用高阻尼值,如 .9,对所有物体使用 angular。

我也想将这些盒子分成几块,实际上我正在这样做,但是当汽车被压碎时没有分裂下摆我遇到了这个 fps 下降所以我现在禁用它。

只有关节是车轮关节,用于汽车的车轮,地图上任何地方都没有关节。

这些盒子有 1.2 米高,尺寸很逼真。

用于箱子和汽车的多边形形状,用于地形边缘形状(链形)

速度阈值在世界设置中默认为 1。

如果有什么笔记我忘记了请评论,我会分享。

谢谢。

免责声明:我无法回答你所有的问题,以下只是我的猜测。

几年前,我用Java + box2d + plain Opengl (LWJGL) 开发了一个游戏原型和游戏库。

我认为您遇到了我遇到的一些问题。

然而,以我的经验不足,我可能是错的。
如果专家(读者)认为我的post有什么错误,请在下方评论,我会改正。

我的猜测

Java速度慢/不太适合游戏。

免责声明:对此有很多争论。
我不是专家,无法在这里发表可靠的声明,但我看到很多 game-prototype 运行 在 C++ 中比 Java 快 3 到 10 倍。 (使用 not-so-different 算法)

内存碎片

你可能已经知道,即使你使用池,与 C++ 相比仍然很差。
你把盒子放在一起,但你不能把所有东西都放在一起,例如游戏逻辑 data-structure、vector2D、普通数组(经常是新 [])、您使用的某些库中的一些恐怖算法。

停用的身体仍然消耗内存(间接加剧内存碎片)。

你有很多静态物体/静态的高复杂度body。

你没有提到你有多少静态body,它们是什么。
您使用的地形是 high-amount-of-vertices 形状吗?
像 Box2D 和 Bullet 这样的流行物理引擎在凸形方面很酷,在原始形状方面很专家,但在凹形方面往往表现不佳(例如你的 terrian)

你们的形状不断地相互碰撞。

例如,一堆 100 个盒子比散布在场景周围的 100 个盒子需要更多的计算。

世界太大

据我所知,box2d把一个场景(世界)划分成一个网格。如果你的世界很大,但是很多 body 聚集到网格的同一个单元格中,Box2D 会工作得相对更差。

不限于Box2D
Bullet 和 Ogre3D - 在某些配置中 - 也会遇到这个问题。

回答(再猜)

1) is this fps (20 fps) normal and expected?

我不知道moblie,但你的代码仍然可以在某些方面进行优化。 (见下文)

2) can the 100 km terrain be problem if so how should I manage it?

未聚焦的块 -> 删除 body(不仅仅是停用它)。

是的,说起来容易做起来难,您可以只停用附近的区块,但移除(删除)远处区块中的所有尸体(> 3 chunk-distance,可能)。

如果被删除的chunk还能回到现场,你可能得想办法把它保存在某个地方。 (例如只保存 body 的位置、尺寸、重量)

3) simulating 100 dynamic bodies with huge edge shape terrain is tottaly impossible ? ( but in the earn to die they did it)

他们做到了,或者你只是认为他们做到了?
在某些方面,编程是一门艺术。
你看到的东西可能与它们实际实现的方式有很大不同。
您的瓶颈可能只是地形 - 减少其 level-of-detail 也可能有所帮助。

4) should I write my own simple physics for only this kind of game (a simple specific one) ?

不,除非你想学习 && 有很多时间 && 真的很喜欢数学。

5) should I use bullet physics instead of box2d for 2D purposes ? is it possible? and will I face with performance problems ?

我想你还是会在一定程度上面对。
对于 Box2D 和 Bullet 来说约束是昂贵的
你确定你真的需要约束吗?
在某些情况下,可以通过稍微修改游戏的复合形状/修改设计来避免。

我认为如果您改用 C++ 和 Bullet,您将获得至少 3 倍的性能,但是 我完全不确定