2012-04-29 123 views
1

我是一個相當缺乏經驗的程序員,目前正在學習C#並試圖學習一般的遊戲設計。使碰撞檢測更有效(C#XNA)

我正在使用微軟的XNA框架來構建一個Galaga式的滾動射擊遊戲。在經歷了幾次粗糙的試驗之後,我用劣質的面向對象結構進行了努力,做出了一些糟糕的設計選擇,終於找到了引擎的一個可敬的開始。

目前我在製作碰撞檢測方面遇到了問題,不會延遲遊戲。我當前的引擎將所有活動的遊戲對象保存在List對象中,並循環遍歷每個對象,檢查它是否與其他對象碰撞。不用說,它可能會好很多。

這是我的碰撞檢查,在ObjectHandler類中完成。

public override void Update(GameTime gameTime) 
    { 
    ... 
     //Handle collisions 
     foreach (GameObject obj in Objects) 
     { 
      ICollideable e = obj as ICollideable; 
      //Check if the object implements ICollideable 
      if (e != null) 
      { 
       //Check collision with each other object 
       foreach (GameObject obj2 in Objects) 
       { 
        //Check if the second object implements ICollideable 
        ICollideable e2 = obj2 as ICollideable; 
        //check if they are in the same sector 
        if (e2 != null && SameSector(e.Sector,e2.Sector)) 
        { 
         //Check if the collision masks interesect 
         //if so call each object's collision event 
         if (e.Mask.Intersects(e2.Mask)) 
         { 
          e.CollisionEvent(e2); 
          e2.CollisionEvent(e); 
         } 
        } 
       } 
      } 
     } 
     ... 
    } 

這裏是SameSector函數。

private bool SameSector(Point p1, Point p2) 
    { 
     if (Math.Abs(p1.X-p2.X)<=1 && Math.Abs(p1.Y-p2.Y)<=1) 
      return true; 
     else 
      return false; 
    } 

這裏的「Mask」是一個Rectangle對象,它是XNA框架的一部分。正如你所看到的,我已經實現了一種空間分區系統,其中每個對象都設置了它的60x60平方。然而,我不確定我做了什麼有用的事情,因爲它需要花費同樣多的時間來檢查兩個對象位於相同的扇區(或相鄰的扇區),因爲它可以檢查它們是否正在碰撞。

我已經看到類似這個問題已發佈的問題,但它不完全滿足我的問題。從它我確實認識到時間管理系統是有用的。我會盡力實現這一點,但由於我對編程還很陌生,在深入研究更高級的設計之前,我想優化自己的碰撞檢查。

那麼,有沒有我的方式,我可以有效地優化我目前的碰撞檢查,或者我有什麼方法開始?

回答

3

空間分區只會幫助你,如果你已經以一種不需要你以某種方式比較每個對象與每個對象的方式來實現它。

在您的空間分區網格中,您希望每個網格單元都具有某種對象的成員資格列表,以及每個對象要注意它所在的單元格。然後,您只需要進行比較一個對象以及該單元內和緊鄰單元內的所有其他對象(因爲對象可能會重疊邊界)。缺點是你現在需要保持所有狀態的更新。

我強烈推薦書Real-Time Collision Detection,其中除了其他CD主題外,還包括深入討論幾種不同的廣義分區方案及其相對優勢和弱點。除了統一的網格外,還有分層網格,四叉樹,掃掠和修剪,以及其他可能更適合您的技術(sweep and prune可能特別有用)。