2014-04-19 159 views
0

我一直在試圖解決這個問題幾個小時,而且互聯網在這個問題上很不起眼。矩形之間的碰撞

我需要幫助檢測和解決矩形之間的碰撞,而不是只是檢測,但注意我也提到了解決方案。

這是兩個箱,其中x/y的寬度/高度。我只需要檢測它們何時重疊,並將其中一個盒子順利推出另一個盒子。

另外,還要注意一個箱子是固定的 - 與其他移動。

有沒有人有這樣的東西(或可以給我一個例子嗎?)我會很感激。

我需要的框能夠停留在彼此的頂部爲好。

謝謝!

+1

什麼* *具體是什麼問題?你有什麼*嘗試*檢測重疊?這並不複雜。 – chrylis

+0

檢測不是問題。問題在於解決碰撞問題。我嘗試了很多方法(例如在最後一個工作位置和新位置之間進行插值以找到一個新的位置,同時停止速度並強制將它們放在盒子外面),但沒有一個能夠很好地工作。 – Brayden

+0

Brayden,看看SAT(分離軸定理) – Gere

回答

1

我不知道什麼情況下這裏是(這些是盒子移動或靜止的?你是否在尋找一個準確的物理分辨率,或只是一個幾何正確的?),但似乎你可以在做到這一點方式如下:

1)確定是否存在一個框碰撞 2)確定兩個盒子,這將產生一個第三個框的交叉點。盒子的寬度和高度就是穿透深度。 3)按照穿透深度(x - 寬度,y - 高度)移動其中一個盒子的中心。

這應該會導致框不相交。

供參考:兩個箱交點可以通過採取分鐘的最大值和從兩個框中馬克塞斯的分鐘來計算。

這裏是我的引擎部分的代碼框中路口:

bool Bounds::IntersectsBounds(const Bounds &other) const 
{ 
    return !(min.x > other.max.x || max.x < other.min.x 
      || min.y > other.max.y || max.y < other.min.y); 
} 

bool Bounds::Intersection(const Bounds &other, Bounds &outBounds) const 
{ 
    if (!this->IntersectsBounds(other)) { 
     return false; 
    } 

    outBounds.min.x = std::max(min.x, other.min.x); 
    outBounds.min.y = std::max(min.y, other.min.y); 
    outBounds.max.x = std::min(max.x, other.max.x); 
    outBounds.max.y = std::min(max.y, other.max.y); 


    return true; 
} 

在這種情況下,「outBounds」變量是兩個箱(在這種情況下是你的穿透深度)的交叉點。您可以使用此框的寬度/高度來執行碰撞解析。

+0

一個盒子是固定的,另一個不是。對不起,不澄清。我會修改這個問題,並嘗試你的解決方案。謝謝! – Brayden

+0

你能詳細說一下交點計算嗎? – Brayden

+0

當然,我會編輯原始文章 – aeskreis

0

是啊!這是一個很常見的問題!您可能想查看堆棧交換網絡的gamedev部分!

檢測

bool collide(float x1,float y1,float sx1,float sy1, float x2, float y2, float sx2, float sy2){ 
if (x1+sx1 <= x2) 
     return false; 
if (x2+sx2 <= x1) 
     return false; 
if (y1+sy1 <= y2) 
     return false; 
if (y2+sy2 <= y1) 
     return false; 
return true; 
} 

分辨率 至於答案,這取決於你要爲應用程序的類型。它是一款雙面滾輪,自上而下,基於圖塊?答案取決於對這個問題的回答。我會假設像sidescroller或自上而下的動作遊戲動態。

代碼不難,但執行可以。如果你在屏幕上移動幾個對象,你可以使用類似的系統,礦山,肚裏類似如下:

  1. 獲得您目前正與碰撞對象的列表,在距離的順序從當前對象。
  2. 遍歷對象並使用以下方法解決衝突
  3. 通過向對象發送消息來檢查對象是否具有某種特殊的碰撞類型(傳送器等),並檢查返回值(傳送器將採用處理碰撞分辨率)
  4. 檢查我們當前對象的前一個底部位置(A)是否高於相關對象的頂部(B),如果是,則表示您已發生底部碰撞。通過A y位置設置爲的B y位置減去A
  5. 高度(如果先前FAILED)檢查如果A先前右側是的B左側的左側,如果解決這意味着你有右側碰撞。通過A的x位置設置爲B的位置減去A的寬度
  6. (如果先前FAILED)檢查如果A先前左側是的B右側的右若然解決這意味着你有左側碰撞。通過A的x位置設置爲B解決'SX位置加上B的寬度
  7. (如果先前FAILED)檢查如果A先前頂側是的B的底側的下方,如果是這樣你有頂部碰撞。通過A y位置設置爲的B y位置加上B的高度

呼解決。根據距離排序物體是非常重要的,如果您檢查與較遠物體的碰撞,它會抓住邊緣!

我希望有道理!

+0

問題主要在於如何解決它,如果可以的話,請更具體地比「檢測碰撞,然後解決」。謝謝! – Brayden

+0

哈哈,你可以搞清楚人,你是程序員!不要讓我們爲你做這一切:D但我會對你更具體一些 - 我知道有時我們需要一點外部視角。 – ultifinitus

0

編輯:顯然不適用於Android。

https://stackoverflow.com/a/15515114/3492994

使用從2D圖形API可用類。

Rectangle r1 = new Rectangle(100, 100, 100, 100); 
Line2D l1 = new Line2D.Float(0, 200, 200, 0); 
System.out.println("l1.intsects(r1) = " + l1.intersects(r1)); 

什麼這不告訴你,在這裏...

+0

不幸的是,你不能在Android中使用它們。 – Brayden