我在 cocos2d-x 中是全新的。
从开发一个简单的游戏开始,就像" The Plane War"
当我实施碰撞检测时,一个问题让我感到困惑。
这意味着我必须每帧检测 50 * 50 次, 2500 次! 游戏的表现应该会下降......
那么如何优化碰撞检测呢?
答案 0 :(得分:0)
我无法谈论Cocos2d,因为我没有使用它。但一般的解决方案包括:
将游戏世界分解为区域
E.g。将您的世界划分为100x100像素块。在每个对象的每个帧的开始处计算出哪些块(注意复数)重叠。如果你经常划分你的世界,这应该是便宜的。将对象添加到每个块中的对象列表中。
然后,再次浏览对象,这次从块中读取。测试与您的对象重叠的任何其他块重叠的所有其他对象。
更复杂的划分策略可能包括四叉树或kd树。如果你的世界已经固有地划分(例如,对于某些类型的快速碰撞或能见度计算,则进入凸扇区),那么你可以经常捎带它。
按排序列表重复
选择您的世界最长的任何尺寸。我们可以说,为了争论,它不仅仅是高大的,你也不想去考虑对角线。
然后通过开始x位置对所有对象进行排序。
现在沿着列表迭代。对于列表中i
位置的每个对象,请检查i+1
,i+2
等处的对象,直到找到最左边的x超出最右边的第一个对象为止。然后停止考虑i
处的对象并允许循环滚动到下一个对象。您正在考虑的对象绝对不能与您停止检查的对象之外的任何事物发生碰撞,因为它们都有最左边的边缘甚至更靠右边。
这是极少数情况下,插入排序可以是最快的排序,因为它是最佳的 - O(n) - 如果应用于已经排序的列表并且通常接近最佳列表的位置越近分类。在游戏中,您的对象排序可能在帧之间仅稍微改变,因此如果它们在最后一帧被排序,则它们很可能接近对该帧进行排序。
然后不要直接跳到昂贵的测试
这些都是广泛的检测策略,可以防止在绝对不重叠的对象之间进行比较。即使你对象与对象有关,你也应该考虑在进行精确的像素检查之前做一些广泛的事情。最简单的解决方案是限制球体 - 为每个物体计算出一个中心和一个半径,然后作为第一个检查计算出两个中心之间距离的平方(使用毕达哥拉斯但不要移动到距离的正方形以避开昂贵的正方形) root)并将其与两个半径之和的平方进行比较。如果这两个对象至少没有那么近,那么它们就不会重叠,所以你可以跳过更精确的东西。
根据您的成本和几何体的一般形状,您可能还会考虑凸包和分离轴(特别是如果您有足够快的机制来缓存哪个轴上次分隔任何两个给定对象)。