2015-11-16 49 views
0

我目前正在爲RPG風格的遊戲開發一個平鋪碰撞系統,它主要工作,除了與矩形交叉點有些不一致之外。Java矩形碰撞交集(並不總是有效)

protected void tileCollision() 
{ 
    AnimatedSprite player = findPlayer(); 
    for(int i = 0; i < _sprites.size(); i++) 
    { 
     AnimatedSprite spr = _sprites.get(i); 
     for(int j = 0; j < tileWithinRange.length; j++) 
     { 
      Tile tile = tileWithinRange[j]; 
      if(tile != null) 
      {  
       if(tile.getBounds().intersects(player.getBounds())) 
       { 
        player.setCollided(true); 
        tileCollision(player, tile, -1, -1); 
       } else 
       { 
        player.setCollided(false); 
       } 
      } 
     } 
    } 
} 

當我第一次用瓦片在啓動遊戲的碰撞,它總是返回true,但如果我沿着地磚的一列動,我開始越來越虛假的回報,然後過了一段時間我只得到虛假的回報。

Here is an image of the player intersecting with a tile

有一個明顯的交匯於此,但在這種情況下,可變相撞返回false。 ?

到底哪裏出問題了交集並不總是登記`

回答

0

太少的信息在這裏真正知道發生了什麼事,但看起來可疑的位置:

 if(tile.getBounds().intersects(player.getBounds())) 
    { 
     player.setCollided(true); 
     tileCollision(player, tile, -1, -1); 
    } else 
    { 
     player.setCollided(false); 
    } 

既然你在一個循環中對着玩家檢查多個拼圖,如果玩家與第一個拼圖發生碰撞,但是不會與第二個拼圖相撞,該怎麼辦?即使他與前面的圖塊相撞,您最終仍會打電話player.setCollided(false);,並將truefalse之間的碰撞狀態覆蓋。這可能解釋你在一段時間後只能得到錯誤回報的行爲(也許是因爲你檢查瓷磚的順序使得它使用假狀態覆蓋真實狀態)。

我不確定這是否合乎要求或者不會產生這些副作用,但至少讓這種碰撞狀態首先打開然後用off同樣的循環。如果這是不受歡迎的行爲,那麼在碰撞發生時,您可能會需要您擺脫循環。或者,也許你想要的是更多的東西是這樣的:

player.setCollided(false); 
    for(int j = 0; j < tileWithinRange.length; j++) 
    { 
     Tile tile = tileWithinRange[j]; 
     if(tile != null && tile.getBounds().intersects(player.getBounds())) 
     { 
      player.setCollided(true); 
      tileCollision(player, tile, -1, -1); 
     } 
    } 
} 

或者,也許你的邊界/交集的功能是真正的故障 - 它太很難說有這麼少的代碼/信息(我們不知道如何將這些都實現)。

能夠隔離您的代碼並學習如何構建測試用例來獨立測試小部件中的各個功能是很好的。你想通過一個測試程序消除嫌疑犯,讓你能夠弄清楚,「好的,這個部分在任何情況下都能很好地工作,讓我們繼續下一件事。」否則,它會變成一個猜測遊戲,試圖找出哪裏出了問題。在開發過程中失去時間/生產力的最簡單方法之一是首先編寫一些代碼,然後嘗試縮小事後的錯誤,而不是測試每個小小的babystep。在你發現他們越晚,錯誤會變得越來越昂貴,並且你在調查中必須經歷的嫌疑人越多。

0

我最終將方法重寫爲布爾值,使其在碰撞時返回true,否則返回false。這是新的代碼。

public boolean tileCollision() { 
    AnimatedSprite player = findPlayer(); 
    for(int j = 0; j < tileWithinRange.length; j++) { 
     Tile tile = tileWithinRange[j]; 
     if(tile != null) { 
      if(tile.getTileBounds().intersects(player.getBounds())) { 
       return true; 
      } 
     } 
    } 
    return false; 
}