游戲中的碰撞檢測(轉)


http://wenku.baidu.com/view/45544cfcfab069dc50220145.html

http://blog.csdn.net/ruanjianxiong/article/details/6715769

游戲中的碰撞檢測方式有很多,不同的算法之間主要是在精度和速度之間權衡。以下幾種方式按照速度排序說明。以2D為例,3D不過是增加了一維罷了,算法理解上沒太大區別。

一、地圖格子划分檢測

       最簡單的一種檢測,就是把地圖(或者稱為場景,總之是指碰撞發生的范圍)划成一個個格子,類似仙劍奇俠傳這樣。假設地圖有800*600px,20*20個像素為一格。那么可以划為40*30個格子。地圖中參與檢測的對象都存儲着自身所在的格子坐標,判斷碰撞就顯而易見了,例如可以認為兩個物體在相鄰格判為碰撞,或者兩個物體在同一格。采用這種方式有個要求,就是地圖中所有可能參與碰撞的物體都要是20*20像素左右大小或者是其整數倍,例如房子占了3*3個格子,諸如此類。如果不遵守這個規則,有的物體只占了格子的一半,那么在玩家眼里這種檢測就顯得非常的粗糙。這種檢測就像是把地圖的像素點放大幾十倍一樣,與逐像素檢測相比,效率提高了幾十倍甚至上百倍。這種方式可運用於對檢測要求不嚴格的游戲,例如踩地雷的RPG、推箱子之類的智力游戲。

二、矩形檢測

     當地圖中的物體不能嚴格按照某個塊大小的整數倍來繪制時,那么就需要另想其他的方法。這種方法適用於地圖中的物體近似為矩形或者雖然不是矩形,但是碰撞精度要求不高的情況下。每個物體記錄一個能夠將自己框住的最小矩形的左上角坐標和矩形長寬。碰撞退化為判斷矩形與矩形之間是否重疊,而這僅需要4次比較即可得出,速度很快。但為了判斷整個場景中的物體,必須取第一個物體,迭代其他所有物體進行判斷,再取第二個物體,迭代除第一第二個物體外的所有物體進行判斷,以此類推。總計要進行(n-1)!次矩形判斷才能准確得出場景中所有的碰撞可能。

三、圓形檢測

    與上一種方法類似,區別在於用一個能夠包含物體的最小圓代替了矩形。主要是考慮到游戲中的物體外形以平滑為主,例如人物角色。而判斷兩個圓是否碰撞的計算也很簡單,就是判斷兩個圓心之間的距離是否小於兩個圓的半徑之和。雖然球形檢測在某些情況下提高了精度,但卻損失了速度,因為點距離的計算需要用到平方和開方。具體相比慢多少我就不太清楚了。另外,為了計算整個地圖的所有碰撞可能,也要進行(n-1)!次比較。

四、像素檢測

    精確到像素級,已經不能比這更精確了,相對的,效率也是最低的。怎樣判斷兩個物體是否碰撞呢?在過去png格式圖片還不盛行的時候,游戲中用到的圖片中的透明部分是指定用某種顏色來表示的,例如洋紅色。就像電影中的綠幕藍幕,通過處理把這些顏色的像素點當做透明點處理,而為了判斷檢測,需要准備一張原圖像的黑白圖,黑色區域表示透明,這張圖片中的每個像素值為0或者1,判斷檢測的時候取兩張圖片的黑白圖,進行與運算,結果為1(有白點重疊),則判為碰撞。但是現在有了PNG和XNA,逐像素檢測就相對簡單一些。首先仍然需要有一個矩形框包圍物體,通過矩形檢測得到重疊的矩形區域可以大大減少檢測的像素點數量。然后在這個區域內,取兩個圖片的點逐行逐列迭代,如果遇到某個點兩張圖片均有顏色存在,即判為碰撞。同理,進行(n-1)!次比較后得到全地圖的碰撞可能。

五、四叉樹檢測

       准確的說這事在第三四五種方法的基礎上的優化策略,或者說是第一種方法同后三種方法的組合應用。主要是針對那最后的(n-1)!次比較。方法是,像第一種方法一樣將地圖分為格子,格子的大小應該能夠容納10個左右的地圖中最大物體,例如一個800*600的地圖可能就划為9個區。同樣的,每個物體要記錄自己所在的區坐標以及矩形包圍盒。如果該物體完全位於該區內,則只要將其與該區內的其他物體判斷碰撞。如果該物體雖然位於某個區,但是小部分位於隔壁區,則額外的需要迭代隔壁區的物體,這點效率損失是可以容忍的,相比於迭代全地圖的物體。

     有個問題,我怎么知道哪些物體是跟該物體位於同一個區呢?那不是還是要迭代一遍所有物體?這時候就是題目發揮的地方的,之所以稱為四叉樹檢測(當然,這名字是我自己取的),就是因為那些區塊是以四叉樹的方式鏈接的,即得到一個區塊的對象,就可以直接得到其上下左右相鄰的區塊的對象,而物體可以是存儲在所在區的一個列表中。這樣就不用遍歷所有物體也可以直接取出隔壁區的物體了。當地圖很大的時候,四叉樹的優勢體現得很好。

六、3D中的碰撞檢測

     以上是我所掌握碰撞方法,可能還有更多吧。那么3D中的檢測其實是2D的延伸,例如矩形檢測變為立方體檢測,圓形檢測引申為球形檢測,四叉樹檢測進化為八叉樹檢測。

    當然了,凡是有例外。逐像素檢測方法在3D中沒有相對應的方法,因為3D中的物體的表示最小單元是三角型而非點。其實也可以說逐三角片檢測是逐像素檢測的3D版,但畢竟是平面碰撞的檢測,需要一定的計算公式,而不是與或一下就OK的。這里就不贅述了。

總結

我的表達能力不是很OK,另外手打得也有些酸。

選擇哪種方法,要根據你的游戲需要,例如推箱子游戲,顯然只要格子碰撞檢測就足夠了。而一些以球作為主要物體的游戲例如射擊游戲則可以考慮圓形碰撞。

同樣的,在有些碰撞精度要求很高的游戲中,還要對這些方法進行一定的變化,例如格斗游戲,作為判斷的單元不是整個人而是四肢、身體等部位,需要更多的包圍盒來表示一個物體。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM