2010-02-10 18 views
1

我有一個遊戲組成的船隻在二維網格上飛來飛去。我正在寫一個函數來獲取一個位置,並且計算出(預定義的)目標是否可以從那裏被命中。這隻需要檢查潛在攻擊者的火線中的所有網格方格。C#XNA:如何從這個簡單的函數中刪除重複?

在大多數情況下,這是一橫,形成像這樣:

(currX +/- SHOT_RANGE, currY) and (currX, currY +/- SHOT_RANGE) 

SHOT_RANGE是一個鏡頭可行駛的最大距離,目前發射艦位於(currX, currY)

檢查這兩行代碼是相當簡單:

 for (int i = x - SHOT_RANGE; i < x + SHOT_RANGE; i++) { 
      if (target.TileX == i && target.TileY == y) { 
       return true; 
      } 
     } 

     for (int j = y - SHOT_RANGE; j < y + SHOT_RANGE; j++) { 
      if (target.TileX == x && target.TileY == j) { 
       return true; 
      } 
     } 

然而,在某些「權力瓦」艦也火角。所有這些方格也必須檢查。這是重複發生的地方。你能看到一種用較少的代碼來做到這一點的方法嗎?

/// <param name="x">Current x-coord of the potential ship</param> 
    /// <param name="y">Current y-coord of the potential ship</param> 
      private bool CanShootTargetFrom(int x, int y) { 

     if ((target.TileX == x && Math.Abs(target.TileY - y) <= SHOT_RANGE) || (target.TileY == y && Math.Abs(target.TileX - x) <= SHOT_RANGE)) { 
      return true; 
     } 

     if (board.IsPowerTileAt(x, y)) { 
      int i = x - SHOT_RANGE; 
      int j = y - SHOT_RANGE; 
      while (i != x + SHOT_RANGE && j != y + SHOT_RANGE) { 
       if (target.TileX == i && target.TileY == j) { 
        return true; 
       } 
       i++; 
       j++; 
      } 
      i = x - SHOT_RANGE; 
      j = y + SHOT_RANGE; 
      while (i != x + SHOT_RANGE && j != y - SHOT_RANGE) { 
       if (target.TileX == i && target.TileY == j) { 
        return true; 
       } 
       i++; 
       j--; 
      } 
     } 

     return false; 
    } 

修訂使用卡拉格的建議,我意識到我可以消除其中的兩個環通過提高上限檢查對角線。

回答

1

我認爲它可以在不循環,至少在水平方向和垂直掃描來完成更容易:

class Ship{int x;int y} 

Ship s;//your ship 
Ship t;//target 

if(
    (s.y == t.y && abs(s.x-t.x) <= SHOT_RANGE) 
    || 
    (s.x == t.x && abs(s.y-t.y) <= SHOT_RANGE) 
) 
    return true; 

至於對角線,它們有90度角的三角形: (A²+稱b² <c²)

int a = abs(s.x - t.x) 
int b = abs(s.y - t.y) 
if(a == b && a * a + b * b <= shot_range * shot_range) 
    return true; 

我希望這是你想要的東西嗎?

+0

但對於對角線,如果firer在'(3,3)'而目標在'(1,2)'時,這不會返回true嗎?這不會是正確的;該船隻沿着對角線發射。 (所以從'(3,3)',一艘船可能擊中'(2,2)',((1,1)'等) – 2010-02-11 01:35:10

+0

好點。但它是一個90度的角度,所以a == b。 – Carra 2010-02-11 09:17:02

0

我認爲一個更好的設計是改變你的函數有類似簽名:
public bool CanShoot(IShootable potentialTarget)

這種方法可能是船舶類的成員。每個Ship對象都會知道它自己的射擊能力。任何你想能夠被槍殺的東西都可以實現IShootable。

關於你的問題,似乎有一個更簡單的方法。與卡拉所說的類似,您可以檢查每個座標的差異的絕對值是否小於您的射擊範圍。如果不是,則返回false。否則,如果它們位於電源圖塊上,則返回true。如果它們不在電源圖塊上,請檢查以確保x座標或y座標匹配,如果不是則返回false,否則返回true。

這是假設在(0,0)處有射程2的船隻可以在(2,2)處在船上射擊。我假設這是因爲你發佈的代碼會允許這樣做。

相關問題