最近了解了一種用 掃描線算法檢測碰撞 的流程算法
原來不是叫掃描線算法。。。數組
拿 2D 遊戲,遊戲中的物體都是 AABB 盒來講(3D 遊戲也是能夠用這種方式的。2D 遊戲分紅 x、y 兩個維度,3D 分紅 x、y、z 三個維度)
1 首先以 x 軸 方向列一條直線 line,將全部的物體都投影到該直線上,因而每一個物體在 line 上都映射成一條線段,有 起點 start、終點 end。
2 將這些數據存成一個結構體 struct,包含下面字段:
startPos、endPos、objectId
3 將全部數據存放到一個數組 xLineList 中,而後根據 startPos 從小到大進行快排
4 用以下方式遍歷數組:
totalCount = xLineList.length
for i=0; i<totalCount; ++i
for j=i; j<totalCount; ++j
if objectI.endPos <= objectJ.startPos
//i 和 j 在 x 軸方向上有碰撞
else
break;
用上述方法拿到了 x 軸上全部相交的物體,在記錄碰撞對的時候,靜態物體之間的碰撞是能夠忽略的,只有 dynamic 和 dynamic 或者 dynamic 和 static 之間的碰撞纔有記錄的必要,能省就省。用相似的方式拿到 y 軸上全部相交的物體。兩個方向上同時相交的則表示在 遊戲中發生了碰撞。spa
算法時間複雜度理論上是 n*n,可是實際上不會有這麼高,通常遊戲中,物體相對稀疏,因此很容易就會跳出內層循環。排序
當物體移動時,爲了不從新作一遍投影操做,能夠直接用二分查找在 xLineList 中查找,而後修改 start、end。也能夠用額外的一個 map 來維護每一個 struct 在數組中的下標。由於列表基本上是有序的,因此再次排序時,時間複雜度很低。遊戲
其餘諸如四叉樹、八叉樹,最大包圍盒樹,二維空間劃分 BSP,格子劃分法等,均可以用來作碰撞檢測,可是複雜度上並無特殊的優點,實現起來複雜度卻是高了很多。若是有特殊的需求卻是可使用。object