2011-12-02 80 views
3

我和我的團隊正在用C++/SDL/OpenGL開發一個2D平臺遊戲,我們已經定義了一個碰撞系統,但我們在檢查與地圖的碰撞時遇到問題。檢查2D平臺遊戲中帶有瓷磚的碰撞

瓷磚地圖的瓷磚是32x32,所以我們試圖定義X和Y的最大速度小於32,因爲在這種情況下,我們發現如果速度大於瓷磚尺寸當檢查碰撞時,它的位置已經超過了32的速度更新,所以在這種情況下,位置跳過一個導致驗證的巨大問題的瓦片,所以當我們將X和Y速度限制爲30時,但我們不知道如何使速度大於瓦片大小,而不會丟失可能滑動的某些可能瓦片的完整碰撞檢測。

回答

3

Sweep tests

基本上不是簡單的盒子/盒子碰撞,你需要檢查靜止水平幾何盒子與移動盒子通過(位置)移動到(位置+速度)所形成的形狀之間的碰撞。

+0

因此,您認爲在檢查之前不是移動框,而是在碰撞檢查期間更新位置時,只有在檢查碰撞結果爲假時才更新位置? –

+1

如果您的包裝箱/掃描箱檢查爲假,那麼您可以將其移動到所需的位置。如果這是真的,你需要弄清楚在dt期間它是否成真。我建議您在二進制搜索中改變掃描箱第二個點(位置+速度* alpha),其中alpha在0.0和1.0之間變化。當你發現你的碰撞發生時,你只需將你的盒子的最終位置設置爲(position + velocity * alpha)。 – genpfault

+0

非常感謝您的回答。我已經應用這種方法並且工作得非常好。 –

1

你如何定義速度?我們假設它是每秒像素數,然後爲了允許更高的速度,您應該在一秒鐘內多次檢查碰撞。因此,在僞代碼:

double time = GetElapsedTime(); 
player.updatePosition(speed * time); 

現在,它可能更復雜那麼,但你的想法;要麼做這樣的事情,要麼使用精確的碰撞檢測(我曾經發現過一篇很棒的文章,但似乎無法找到它),它使用方程來「預測」物體何時碰撞和碰撞的位置。我用

+0

是的,它是每秒像素,謝謝我會考慮這一點。 –

1

一種方法:

當移動一個(播放器,其他精靈...),確定所有其所穿過的矩形瓦片。

舉例來說:

on tick: 
    player-box = (player.x, player.y) - (player.x + player.width, player.y + player.height) 
    player-delta.x = (player-speed.x × (now - last-updated)) 
    player-delta.y = (player-speed.y × (now - last-updated)) 
    player-end-box = player-box + player-delta 
    { i.e. player-end-box = (player-box.top-left.x + player-delta.x, 
           player-box.top-left.y + player-delta.y) - 
          (player-box.bottom-right.x + player-delta.x, 
           player-box.bottom-right.y + player-delta.y) } 
    player-collided = (min (player-box.top-left.x, player-end-box.top-left.x), 
         min (player-box.top-left.y, player-end-box.top-left.y)) - 
        (max (player-box.bottom-right.x, player-end-box.bottom-right.x), 
         max (player-box.bottom-right.y, player-end-box.bottom-right.y)) 

然後,您可以採取的player-collided每個角落的modulo 32確定磚的播放器(或任何Sprite)的(試圖)封閉。

通常情況下,您可能希望在播放器的實際尺寸中放置一個小的「邊距」以避免1px或2px重疊...(即,將起始框設置爲小於實際精靈幾個像素),具體取決於玩家的控制有多精確,以及精靈和一個圖塊之間的大小差異。

請注意,非常快速(每更新多個瓷磚)的對角線移動使其無效,但對於非常快速的線性(水平或垂直)移動,它可以很好地工作。如果您在對角線上移動速度太快,對於此方法,請考慮將起始矩形和結束矩形連接成多邊形(不規則六邊形),然後測試每個小塊是否包含該六邊形的任何部分。

for each tile in (big rectangular area): 
     if tile is inside polygon (hexagon of movement): 
      add tile to list of collisions 

這實質上是對常見2D情況的全邊界幾何檢查的優化。