不久之前在論壇上有人發貼,使用java編寫的超級馬裡奧如何實作碰撞檢測,筆者自己以前
也做過Tank大戰。裡面同樣涉及到碰撞檢測,翻翻U盤裡的東西還在,什麼時候也給共享出來。
這篇文章就簡單遊戲中的碰撞檢測做一個簡單的總結。首先需聲明的是這裡隻是2D的碰撞檢測。
文章出處位址:http://blog.csdn.net/kiritor/article/details/8948097
對于形狀之間如何來判斷是否是碰撞的這要根據具體的形狀來定。在新手練手的小遊戲中,
物體形狀一般可以設定為矩形區域,這類規則圖形。它的碰撞檢測可以通過java API中的
Rectangle類來實作碰撞的檢測。
首先我們檢視API關于Rectangle類的介紹:它就是指定坐标空間的一個區域,這個區域是通過
指定左上角x、y坐标和去高度和寬度來确定的。
接下來看起具體的方法public Rectangleintersection(Rectangle r),這個方法就是碰撞檢測
的關鍵了,如果兩個Rectangle對象有交集,那麼他們就有碰撞了。而每個形狀我們都可以得到他
們的Rectangle對象,這樣圖形的碰撞檢測也就得以實作了。

上述這個例子就是判斷Tank發出的×××是否對地圖中的障礙物有碰撞,如果有的話
就做相關的操作(×××爆炸、障礙物消失)。上述代碼中×××對象有一個getRec()方法就是
得到×××圖形的Rectangle對象,具體實作就是根據其坐标和width、height來生成的。
采用此種方法進行碰撞檢測需要注意,對于圖檔的實作處理應該盡量的去掉圖示邊角
的空白,不然實際效果可以産生肉眼可辨的誤差。也就是說Rectangle盡量的包住圖形
且Rectangle的區域盡量小。這種碰撞檢測的方法被稱之為多矩形碰撞。
一旦有一個矩形數組中的矩形與另外一個矩形數組的矩形發生碰撞就可認為發生了
多矩形碰撞。其中多圓形碰撞也是同樣的道理,隻是包裹的圖形區域是圓形罷了。
不過仔細思考多矩形碰撞同樣會有誤差,雖然這種誤差十分小。
像素級别的碰撞檢測算得上是最精确的碰撞檢測方法了。
首先周遊算出一張位圖所有的像素點坐标,然後與另外一張位圖上的所有點坐标進行對比,
一旦有一個像素點的坐标相同,就立刻取出這兩個坐标相同的像素點,通過位運算取出這兩個
像素點的最高位(透明度)進行對比,如果兩個像素點都是非透明像素則判定這兩張位圖發生
碰撞。
介紹了像素碰撞之後可以得到兩個結論:
1、像素碰撞很精确,不論位圖之間是否帶有透明像素,都可以精确判斷;
2、正是因為像素碰撞的這種高精确判定,進而也會造成代碼效率明顯降低!
假設兩張100×100 大小的位圖利用像素級檢測碰撞,僅是周遊兩張位圖的像素
就要循環100×100×2=20000 句邏輯代碼;況且還要對篩選出來的相同坐标的
像素點進行周遊對比其透明值!這種效率可想而知!
當然,這裡的像素碰撞隻是大緻提供一種思路,肯定還可以進行代碼優化;但是不論再優的
代碼,使用像素級進行碰撞檢測終會導緻整個程式的運作效率大大降低。是以像素級别的碰
撞檢測在遊戲開發中是盡量避免使用的!
對于×××和障礙物的碰撞檢測,采用上述第一種方法就可以簡單的實作了,不過×××
是圓形的有沒有更加精确的碰撞檢測方法呢?也就是實作圓形和矩形的碰撞檢測嘛。
這裡我們需要簡單的運作下幾何數學的知識,給個簡單的圖就會明白了。
小圓有個運動軌迹,軌迹的線如果和他對着的正方形的相對某一象限的邊有焦點,那麼
就能碰撞,邊就是那一個象限的邊(還要把圓半徑算進去),具體代碼就不實作了,讀者可
自己嘗試着去實作。
對于矩形碰撞,很多人都知道。但面對多邊形圖形,大多數采用多矩形覆寫的方式。
SAT 一種可以快速檢測不規則的凸多邊形是否碰撞的算法給出兩個凸多邊形體,
如果我們能找到一個軸線,使兩物體在此軸線上的投影不重疊,則這兩個物體之間沒有
發生碰撞,這個軸線叫做Separating Axis(紅色軸線)。
對于2D來說,紅色線就是垂直與多邊形邊的軸。
是以,如果我們要檢查兩多邊形是否碰撞,就去檢查兩多邊形在每個所有可能的軸上的投影
是否重疊。