2013-03-25 55 views
0

我有一個程序,檢查距離以及玩家是否與屏障相撞。我現在正在計算屏障陣列中哪個屏障距離移動的玩家最近,然後返回該屏障的指數。尋找最近的物體(屏障)給玩家

這是我到目前爲止有:

public static int closestBarrier(GameObject object, GameObject[] barriers) 
// TODO stub 
{ 
    int closest = 0; 

    for (int i = 0; i < barriers.length - 1; i++) { 

     if (Math.sqrt((object.getX() - barriers[i].getX()) 
       * (object.getX() - barriers[i].getX())) 
       + ((object.getY() - barriers[i].getY()) * (object.getY() - barriers[i] 
         .getY())) <= Math 
       .sqrt((object.getX() - barriers[i + 1].getX()) 
         * (object.getX() - barriers[i + 1].getX())) 
       + ((object.getY() - barriers[i + 1].getY()) * (object 
         .getY() - barriers[i + 1].getY()))) { 

      closest = i; 
     } else 
      closest = i + 1; 

    } 

    return closest; 
} 

我仍然對Java,所以我明白我已經有可能不是很有效,或者做它的最佳方法(甚至就在所有!?)。

+0

Yucky ...使用變量來存儲嵌套計算的結果,它非常* undebuggable *。 – sp00m 2013-03-25 13:20:09

回答

1

我會重構它一丁點簡單,像這樣:

public static int closestBarrier(GameObject object, GameObject[] barriers) 
    { 
     int closest = -1; 
     float minDistSq = Float.MAX_VALUE;//ridiculously large value to start 
     for (int i = 0; i < barriers.length - 1; i++) { 
      GameObject curr = barriers[i];//current 
      float dx = (object.getX()-curr.getX()); 
      float dy = (object.getY()-curr.getY()); 
      float distSq = dx*dx+dy*dy;//use the squared distance 
      if(distSq < minDistSq) {//find the smallest and remember the id 
       minDistSq = distSq; 
       closest = i; 
      } 
     } 

     return closest; 
    } 

這種方式,你正在做的少距離檢查(你的版本則每次迭代的兩個距離檢查),你也只需要ID,而不是實際的距離,所以你可以通過不使用Math.sqrt()並簡單地使用平方距離來獲得一點速度。

我能想到的另一個想法取決於佈局。假設你有一個自上而下的垂直卷軸,你首先檢查障礙的y屬性。如果你有他們的散列或者排序列表,對於屏幕底部的一個對象,你可以從最大的屏障開始循環到最小的屏障。一旦找到Y軸上最接近的障礙,如果超過1,可以檢查x軸上最近的障礙。您不需要使用平方根或平方根,因爲您基本上將支票從2D隔離到1D,在2D檢查中進行2次檢查,縮小屏障並丟棄較遠的屏障,而不是檢查每個對象的全部時間。

一個更高級的版本將使用space partitioning,但希望你不會需要它在一個簡單的遊戲,而學習。

+0

感謝您的回覆!我完全理解你如何改寫它,使其更有意義,更高效。它幾乎在工作,但是我仍然沒有通過一項測試,我無法弄清楚爲什麼。這是測試:(我的結果是障礙2是最接近的,但實際上它是障礙1) 'player.setX(12); player.setY(20); 的assertEquals(「玩家最接近第二屏障」,2,\t \t \t \t Submission.closestBarrier(玩家,障礙));' – 2013-03-25 13:52:21

+0

@danboy我不熟悉你的代碼和安裝程序的其餘部分,因此它是一種很難精確解決問題。使用距離公式最適合圓/方形。我假設你可能正在處理不規則形狀的物體,並且屏障的質心不是測試對象方向上的最靠近的點。如果你想象這一點會更好。 – 2013-03-25 14:06:05

+0

我使用圓圈和我的距離公式是這樣 '雙b1Dist = Math.sqrt((obOneX - obTwoX)*(obOneX - obTwoX) \t \t \t \t +((obOneY - obTwoY)*(obOneY - obTwoY ))); \t \t double b1DistTwo = b1Dist - objectOneRadius; \t \t b1DistFinal = b1DistTwo - objectTwoRadius; \t \t return b1DistFinal;' 對不起繼續問你,但是謝謝你的時間! – 2013-03-25 14:16:51