2015-05-06 86 views
1

我有一個簡單的小遊戲,我正在努力讓我的腳在設計過程中變得溼潤。嘗試對列表中的項目執行碰撞檢測時遇到問題。我有一個敵人級別,一次會產生三個敵人,然後這些船隻每個都有能力一次發射三顆子彈。我得到的問題是,我的碰撞檢測正在跟蹤船隻,而不是每個單獨的子彈,即使碰撞rect正在獲得子彈的位置。在射擊子彈法中,我分配了一個Vector2來複制子彈的位置(很確定我必須做些什麼來傳遞索引,但我不知道從哪裏開始)。任何幫助/指導將非常感謝!XNA 4.0碰撞檢測列表

SpriteManager.cs

for (int j = 0; j < enemies.Count; j++) 
      { 
       Enemies e = enemies[j]; 

       //Update Sprite 
       e.Update(Game.GraphicsDevice, gameTime); 

       //Check for Collision 
       if (e.collisionRect.Intersects(player.collisionRect)) 
       { 
        lives -= 1; 
       } 
      } 

Enemies.cs

public void ShootBullets() 
    { 
     Bullets newBullet = new Bullets(bulletTexture); 
     newBullet.velocity.X = velocity.X - 3f; 
     newBullet.position = new Vector2(position.X + newBullet.velocity.X, 
      position.Y + (texture.Height/2) - (bulletTexture.Height/2)); 

     //Test 
     bulletPos = newBullet.position; 

     newBullet.isVisible = true; 
     if (bullets.Count() < 3) 
      bullets.Add(newBullet); 
    } 

    public Rectangle collisionRect 
    { 
     get 
     { 
      return new Rectangle(
       (int)bulletPos.X + collisionOffset, 
       (int)bulletPos.Y + collisionOffset, 
       bulletTexture.Width - (collisionOffset * 2), 
       bulletTexture.Height - (collisionOffset * 2)); 
     } 
    } 

編輯補充子彈類:

public class Bullets 
    { 
     // Variables 
     public Texture2D texture; 

     public Vector2 position; 
     public Vector2 velocity; 

     public bool isVisible; 

     //public Rectangle boundingBox; 
     //public Vector2 origin; 
     //public float speed; 

     // Methods 

     // Constructor 
     public Bullets(Texture2D newTexture) 
     { 
      // speed = 10; 
      texture = newTexture; 
      isVisible = false; 
     } 

     // Draw 
     public void draw(SpriteBatch spritebatch) 
     { 
      spritebatch.Draw(texture, position, Color.White); 
     } 

    } 
} 

回答

2

而不是僅僅通過敵人循環,您還需要循環通過每個敵人的子彈。

最簡單的修改你的代碼看起來像

for (int j = 0; j < enemies.Count; j++) 
      { 
       Enemies e = enemies[j]; 

       //Update Sprite 
       e.Update(Game.GraphicsDevice, gameTime); 

       for (int u = 0; u < e.bullets.count; u++) { 
        Bullet b = e.bullets[u]; 
        //Check for Collision 
        if (b.collisionRect.Intersects(player.collisionRect)) 
        { 
         lives -= 1; 
        } 
       } 
      } 

但是,請注意有幾件事情,一般不建議你在這裏幹嘛。首先,不是每個敵人都有自己的子彈列表,每個敵人在「發射」子彈時都會添加一個全局列表。

那麼你只能通過搜索那一個列表,而不是查找每個敵人,然後再從每一個敵人查找每顆子彈。

其次,而不是寫出來的自定義for循環像你

for (int j = 0; j < enemies.Count; j++) { 
Enemies e = enemies[j]; 

考慮簡單地做

//same thing 
foreach (var e in enemies) { 

另外,請這些子彈進行更新邏輯何時刪除任何子彈確保走出界限或擊中其他物體。 有很多方法可以優化何時可以銷燬對象以及需要檢查碰撞的對象。 碰撞檢查通常應該儘可能少的對象進行,因爲它們是你在遊戲中需要做的較慢的事情之一。 Althoguh簡單的矩形十字路口相當快,所以也許不需要擔心優化該部分。

+1

有關您對循環的評論的說明:從我所看到的情況來看,在性能方面使用for循環比foreach循環好,在這種情況下,性能是關鍵。來源:http://stackoverflow.com/questions/365615/in-net-which-loop-runs-faster-for-or-foreach – Taegost

+0

優化到一個循環而不是數組的foreach是最後一件事情之一編碼遊戲時會有所不同。如果你需要這些速度來讓你的遊戲不會受到性能的影響,那麼你在其他地方做的事情會更糟糕。一個foreach更清晰,更容易維護。如前所述,諸如碰撞檢查和物理學等計算機繪圖和計算等功能都是您需要小心的地方。使用計數器變量膨脹代碼只是爲了從第二行的數組中加載實例真的不是必需的。 – irreal

+0

@irreal由於您所做的修改,我看到了兩個問題。其中之一是列表項目符號不公開,所以不能在課堂外訪問。我解決了這個問題,並將其公諸於世,而不是一件大事。第二件事是子彈不具有碰撞直角功能,射擊子彈不接受通過每個子彈的參數。所以這只是有點混亂。我明白你的意思 – Paul2357