2010-11-08 130 views
3

好的,所以我正在製作一款遊戲,並且我發現我的敵人不喜歡我的碰撞檢測功能,這對我的玩家來說非常合適。經過一些調試,我發現這是因爲我的敵人比我的瓷磚大,而我的玩家比我的瓷磚小。如何測試一個矩形是否在另一個矩形中?

現在我需要能夠做出大敵和老闆,所以這是不行的。所以我需要找出更好的方法來測試碰撞檢測。這是我當前如何做它:

上下:

if((enemy.left > tile.left && enemy.left < tile.right || enemy.right > tile.left && enemy.right < tile.right) && enemy.top < tile.bottom && enemy.bottom > tile.top){ 
    //collision 
} 

左右:

if((enemy.top > tile.top && enemy.top < tile.bottom || enemy.bottom > tile.top && enemy.bottom < tile.bottom) && enemy.left < tile.right && enemy.right > tile.left){ 
    //colision 
} 
+0

你的精靈是純粹的矩形嗎? – xandy 2010-11-08 01:27:26

+0

它是52x32,拼圖是50x50 – William 2010-11-08 01:28:56

+2

我的意思是,對於大多數遊戲來說,精靈的碰撞檢測不是簡單地檢測重疊的矩形,例如,如果你的敵人和你的化身都是圓形的,即使矩形重疊也不會基本崩潰。 – xandy 2010-11-08 01:39:18

回答

5

在Java中,使用intersects(Rectangle r)

+2

+1,因爲這是我選擇的選項。如果我必須編寫自己的自定義代碼,無論如何,我都會讓我的公共界面看起來像這樣。 – 2010-11-08 02:11:14

2

在.NET語言中,你可以使用Rectangle.IntersectsWith(Rectangle other)方法執行非常基本的碰撞檢測。

+0

哦,謝謝,但我有點想到答案會更多......便攜。儘管如此,當我在C#和C++和Java中編寫代碼時,我發現你的答案足夠有用,但它不是我想要的。 編輯:在Java中的非便攜式答案是好的,但是,因爲這就是我的遊戲編碼。 – William 2010-11-08 01:36:56

1

我認爲問題出在

enemy.top < tile.bottom && enemy.bottom > tile.top 

(在第一個代碼),如果敵人是瓷磚完全(高度方向)

enemy.top > tile.top && enemy.top < tile.bottom || enemy.bottom > tile.top && enemy.bottom < tile.bottom 

就像你有內,這隻會是真實的用左+右檢查完成。

只是爲了澄清這將意味着首先檢查你給是:

if((enemy.left > tile.left && enemy.left < tile.right || enemy.right > tile.left && enemy.right < tile.right) && (enemy.top > tile.top && enemy.top < tile.bottom || enemy.bottom > tile.top && enemy.bottom < tile.bottom)){ 
//collision 

}

而與此我不認爲你需要單獨的上/下,左/右檢查,這應該如果敵人的任何部分在瓦片內,則返回true

+0

你真的只需要大約一半的測試你在做最後的答案。檢查我的答案以獲得更有效的一組測試。 – 2010-11-08 02:05:13

+0

哦,是的,這是一個更好的方法。 – akd5446 2010-11-08 02:08:09

0

精靈比平鋪寬,但「左 - 右」代碼不檢查這種情況。 如果我繪製你的代碼,它只是簡單地檢查了敵人是否離開還是敵人權在於瓦片內:

(enemy.left > tile.left && enemy.left < tile.right 
|| enemy.right > tile.left && enemy.right < tile.right) 

// graphed as<br> 
// TL EL TR ----- or ----- TL ER TR<br> 

,但如果整個瓷磚在於敵方區域內,沒有檢測到命中:

// EL TL ----- and ----- TR ER 

類似地,瓦片比敵人更小,所以有必要檢查整個瓦片是否位於敵人內部。 總圖/僞代碼是:

is_hit : 
// T{L,R,T,B} => tile, E{L,R,T,B} => enemy 
// left-right: 
[ 
    TL EL TR ----- or ----- TL ER TR 
      . or . 
    EL TL ----- and ----- TR ER 
] 
.and. 
// top-bottom: 
[ 
    TT ET TB ----- or ----- TT EB TB 
      . or . 
    ET TT ----- and ----- TB EB 
] 
3

下面是如何正確地做分離軸測試(面向邊界框,就像你正在做的)。

if (firstObject.Left < secondObject.Right && firstObject.Right > secondObject.Left 
    && firstObject.Top < secondObject.Bottom && firstObject.Bottom > secondObject.Top) 
{ 
    // Intersecting 
} 

去到這個網站,並與圖3一起玩,一次做出所有這些。然後一次一個地打破每個測試。你會看到經驗,它的工作原理,是因爲你可以得到一樣簡單:

http://www.metanetsoftware.com/technique/tutorialA.html#section1

如果你喜歡它的感覺,通讀整個系列教程。

bool CGRectIntersectsRect(CGRect rect1, CGRect rect2) 
2

對於任何人在Objective-C的工作尋找相同的答案,你可以使用這將是值得的在Rect類中名爲Intersect(Rect rect)的方法。

0

.Net已經有一個:一旦你開始打包更多的功能集成到您的遊戲:)

相關問題