Collision detection 碰撞检测问题

Collision detection 碰撞检测问题,collision-detection,cocos2d-x,Collision Detection,Cocos2d X,我在cocos2d-x中是全新的 只需从开发一个简单的游戏开始,就像“飞机战争” 当我执行碰撞检测时,一些问题使我感到困惑。 假设玩家的飞机可以每隔一天发射50+颗子弹 时间 超过50个以上的敌人出现在屏幕上。 这意味着我必须每帧执行50*50次检测,2500次! 游戏的表现应该是秋天 那么,我如何优化碰撞检测呢?我不能说Cocos2d,因为我没有使用它。但一般的解决办法包括: 将游戏世界划分为多个区域 例如,将您的世界划分为100x100像素块。在每个对象的每个帧的开始处,计算出它重叠的块

我在cocos2d-x中是全新的
只需从开发一个简单的游戏开始,就像“飞机战争”

当我执行碰撞检测时,一些问题使我感到困惑。

  • 假设玩家的飞机可以每隔一天发射50+颗子弹 时间
  • 超过50个以上的敌人出现在屏幕上。
这意味着我必须每帧执行50*50次检测,2500次! 游戏的表现应该是秋天


那么,我如何优化碰撞检测呢?

我不能说Cocos2d,因为我没有使用它。但一般的解决办法包括:

将游戏世界划分为多个区域

例如,将您的世界划分为100x100像素块。在每个对象的每个帧的开始处,计算出它重叠的块(注意复数)。如果你有规律地划分你的世界,那应该是便宜的。将对象添加到每个块中的对象列表中

然后,再次运行对象,这次从块中读取。针对与对象重叠的任何其他块重叠的所有其他对象进行测试

更复杂的划分策略可能包括四叉树或kd树。如果你的世界已经固有地被分割(例如,为了某些类型的快速碰撞或可见性计算而被分割成凸面部分),那么你通常可以利用这一点

沿已排序的列表迭代

选择你的世界最长的维度。让我们假设它比高宽,为了便于讨论,你不想费心考虑对角线

然后从x位置开始对所有对象进行排序

现在沿着列表迭代。对于列表中位于
i
位置的每个对象,将其与位于
i+1
i+2
等位置的对象进行检查,直到到达其最左侧x超出最右侧的第一个对象。然后在
i
处停止考虑对象,并允许循环滚动到下一个对象。你正在考虑的对象肯定不会与你停止检查的对象以外的任何对象发生碰撞,因为它们都有最左边的边,甚至更右边

这是一种罕见的情况,插入排序可以是最快的排序,因为它是最优的-O(n)-如果应用于已排序的列表,并且通常越接近最优,列表就越接近排序。在游戏中,对象顺序在帧之间可能只会有一点变化,所以如果它们是在最后一帧排序的,它们很可能接近于在这一帧排序的

然后不要直接跳到昂贵的测试中

这两种都是广泛的相位检测策略,可以防止绝对不重叠的对象之间的比较。即使在对象与对象之间,你也应该在做精确的像素检查之前考虑做一些宽泛的事情。最简单的解决方案是包围球体-为每个对象计算出一个中心和一个半径,然后作为第一个检查,计算出两个中心之间距离的平方(使用毕达哥拉斯,但不要移动超过距离的平方,以避免昂贵的平方根),并将其与两个半径之和的平方进行比较。如果这两个对象没有那么近,那么它们就不能重叠,这样你就可以跳过更精确的内容


根据您的成本和几何形状的一般形状,您也可以考虑凸壳和分离轴(特别是如果您有足够快的机制来缓存哪个轴最后分离了两个给定的对象)。

谢谢“汤米”~这是一个好主意,通过像素块来解决我的问题。其实我还有一个想法,就是使用多线程,我不知道这是否能提高性能,看来我还要做2500次检测。。。。。。你认为呢?2500次是最好的情况(假设你把任何测试都算作碰撞检测;很多测试都比完全测试便宜得多)——应该在2500次到最坏的情况(2500*2500)/2=3125000次之间,通常更接近2500次。但是,当你在迭代最后一个列表时,你可能会考虑把它分成一些组,比如说100或500,或者任何在分析过程中建议的东西,并使用<代码> DeXCHOXIpAp/<代码>来让GCD在内核之间调度它。调度是有成本的,因此需要分析和选择合适的批量大小。