基於2D多邊形的碰撞檢測和響應 一

2021-04-15 10:02:29 字數 1923 閱讀 8407

簡介

本文是闡述如何在2d動作遊戲中進行精確而高效的碰撞檢測。這裡的碰撞是基於多邊形而不是基於精靈的。這兩者之間在設計上會有不同。

基於精靈的碰撞檢測是通過精靈之間的重疊的畫素來完成的。而多邊形使用向量數學來精確計算交點,時間和碰撞方向。雖然多邊形僅僅是精靈的乙個近似,但是它比精靈系統要高階。

特性本文使用的演算法只適用於凸多邊形,例如三角形,四邊形,六邊形,圓形。對於非凸多邊形,你可以將其分解為多個凸多邊形,例如三角形。

演算法可以用於快速移動或慢速移動的多邊形。不管物體移動多快,碰撞都不會丟失。它也可以處理重疊的問題,並促使交疊物體分離。

演示也支援分割多邊形交叉。這可以用於子彈的建模。

同時提供了簡單的物體系統,彈力,一些基本的摩擦和靜摩擦力。用於確保物體不會從斜面上滑落。

有乙個剛體系統的例子,使用了chrsi hecker的物理教程。

限制有序碰撞。就是說並不是有序的進行碰撞。這對於快速移動的物體會出現一定的問題。一旦碰撞被檢測到,它就被直接處理了。理想狀態下你可能需要找到乙個碰撞點並處理它,然後尋找更多的碰撞。但是對於2d動作遊戲,這通常是不必要的。

一、分離座標軸方法

這個方法是碰撞檢測的核心。它的規則非常簡單並且非常易於實現。這個方法也非常快並且非常可靠,因為計算中沒有使用除法操作,下面給出乙個簡單的基於兩個box的碰撞檢測的例子。

演算法試圖在兩個物體之間找到乙個合適平面,如果這個平面存在,那麼物體就沒有相交。

為了測試物體是否是分開的,簡單的方法是投影這個物體到平面的法線上,並比較兩者之間的間距看二者是否重疊。

顯然有無數的平面可以用來分割兩個物體。但是已經經過證明的是:你只需要使用一部分平面來進行測試,對於box從上圖中可以看出平面的法線為box b的長軸。

對於box來說需要測試的分割平面是那些法線等於兩個box的軸向的平面。因此對於兩個box來說,你只需要測試4個分割平面即可。在這四個平面裡,一旦發現乙個分割平面可以分割box那麼你就可以斷定這兩個box是不相交的。

如果四個平面都不能分割box,那麼這兩個box一定是相交的,也就是出現了碰撞。

可以擴充套件這個演算法到普通的多邊形,演算法是相同的,只用需要測試的平面的數量改變了。並且分割平面在每個多邊形邊的垂直方向上又有乙個法線。在下圖中,你可以看到兩個分割平面用於測試。在紅色的平面上你可以看到兩個間隔是重疊的。然而,在藍色的平面上間隔是不重疊的,因此,藍色的平面的是分割平面,因此物體是不相交的。

現在,我們有乙個演算法來檢測兩個多邊形是否是相交的。**可以分為三個部分:

a) 生成需要測試的分離軸

b) 計算每乙個多邊形在分離軸法線上的投影

c) 檢測這些投影是否相交

bool intersect(polygon a, polygon b)

for(i = 0; i < b.num_edges; i ++)

return true; }

void calculateinterval(vector axis, polygon p, float& min, float& max) }

演算法檢測2d多邊形之間的碰撞,這個演算法非常的快速和適用。邊的方向不需要單位化,因此你可以避免存貯邊的方向,並通過多邊形的頂點直接得到邊的方向。

for(j = a.num_vertices-1, i = 0; i < a.num_vertices; j = i, i ++)

基於2D多邊形的碰撞檢測和響應 四

下面要作的是用給定的量將兩個物體分離,並新增一點摩擦和一些靜態摩擦,以便使物體靜止在斜面上。該部分使用簡單的速度影響演算法。同樣,為了使碰撞響應更加真實,物體被賦予了質量 更好的是質量的倒數 質量的倒數是比較常用的,該值為零意味著該物體具有無窮大的質量,並因此不能移動。同時速度響應中使用質量的倒數具...

基於2D多邊形的碰撞檢測和響應 五

五 處理旋轉 在許多遊戲中都可以發現一些旋轉的物體。與它們的碰撞會有一點複雜。旋轉精靈的標準做法是通過乙個簡單的角度,通常的區間是 0,2 pi 可以使用矩陣來存貯三角操作,因此乙個角度可以被轉化為2 2的矩陣 乙個簡單的處理旋轉物體碰撞的方法是儲存乙個原始多邊形的副本,並將其轉化到當前位置和角度。...

基於2D多邊形的碰撞檢測和響應 六

六 計算觸點 為了動態的移動剛體,我們需要精確計算兩個碰撞多邊形之間的觸點。對於2d來說這並不複雜,但是在3d場景中會變得非常複雜。在2d情況下,可以考慮兩種情況,點和邊的相交或者是邊和邊的相交。這個處理過程幾乎不需要教程,但是它非常適合於乙個視覺化的演示 這裡,我只考慮交疊的情況,這個原理也適用於...