2015-04-22 23 views
1

我在XNA 4.0中使用C#製作Space Invaders克隆,並遇到了一些問題。首先,當我拍攝陣列右側列上的所有入侵者,但最頂端的一列時,入侵者將移出屏幕直到下一列達到預定限制;然後整個陣列向下移動。顯然我希望它能夠檢測到剩餘的入侵者。我很確定問題出現在以下代碼部分,但我不確定問題在哪。C#XNA Space Invaders問題

for (int rows = 4; rows > 0; rows--) // Detects right-most invader 
     for (int cols = 10; cols > 0; cols--) 
     { 
      if (InvaderArray[rows, cols] != null) 
      { 
       RightInvader = InvaderArray[rows, cols]; 
       break; 
      } 
     } 

的第二個問題是,如果我摧毀一切,但侵略者的一排,我收到了「的NullReferenceException是未處理」在這片碼通知:

if (RightInvader.GetXPos() > 800) // Right edge limit 
    { 
     InvaderDir = -1; 

     for (int rows = 0; rows < 5; rows++) 
      for (int cols = 0; cols < 11; cols++) 
      { 
       if (InvaderArray[rows, cols] != null) 
       { 
        InvaderArray[rows, cols].MoveVertical(8); 
       } 
      } 
    } 

同樣,不知道是什麼問題是。以下是用於檢測剩餘侵入者的代碼:

// Detecting remaining invader 
    bool InvaderFound = false; 

    for (int rows = 0; rows < 5; rows++) 
     for (int cols = 0; cols < 11; cols++) 
     { 
      if (InvaderArray[rows, cols] != null) 
      { 
       InvaderFound = true; 
       break; 
      } 
     } 

任何有關這兩個問題的幫助都將不勝感激。

+2

你的第一個循環是不是在0指數迭代,是預期的行爲?不應該是行> = 0和cols> = 0? –

+1

另外,你的'break'語句只會打破內部循環。外循環繼續,這可能不是你想要的。引入一個變量來決定是否繼續外部循環。如果沒有找到合適的元素,則'RightInvader'可能爲'null'。你應該在訪問它的'GetXPos()'之前檢查它。 –

+1

當你「殺死」一個入侵者時,你可能需要發佈你用來修改InvaderArray的代碼。你是否將它設置爲null或其他值? –

回答

2

所以你可能會因爲某個錯誤而遭受一些折磨。看看你的代碼,看起來你在各處都使用了很多'魔術'數字。第一步是取消所有的4S,10S,5S和11S,並創建一些公共常量:

static readonly int NumRows = 5; 
static readonly int NumColumns = 11; 

現在,你的代碼的第一部分當前從來沒有測試的第0行或列,這可能會導致一些你看到的不愉快。 你的循環,現在可以寫爲:

for (int rows = NumRows - 1; rows >= 0; rows--) 
    for (int cols = NumCols - 1; cols >= 0; cols--) 

目前,你的循環從未測試山坳或行0

編輯: 我錯過了「休息」的問題。一個簡單的方法來解決這個問題是:

bool found = false; 
for (int rows = NumRows - 1; rows >= 0 && !found; rows--) 
    for (int cols = NumCols - 1; cols >= 0 && !found; cols--) 

然後設置爲true而不是中斷。 另一種方法是將你的嵌套循環放入函數中,當你找到你想要的東西時返回。

例如,您發現功能可以寫成:

for (int rows = 0; rows < NumRows ; rows++) 
    for (int cols = 0; cols < NumCols; cols++) 
    { 
     if (InvaderArray[rows, cols] != null) 
     { 
      return true; 
     } 
    } 
} 
return false; 
+0

因此,對於第一位,應在「RightInvader = InvaderArray [rows,cols];'之後將其設置爲true的位置。 – Yellowman94

+0

之前或之後。下一次它循環,!找到將是假的,並且它將從兩個for循環中逃脫出來。當然,如果你將所有的東西嵌套在一個名爲GetRightInvader的函數中,你可以在這一點上返回InvaderArray [row,col]。 – Psymunn

+0

好的,我把這個添加到我的左手和右手入侵者探測器中,但是現在我在代碼中設置了'NullReferenceExeption',這個代碼設置了左右邊界限制,我是否也需要對這些探測器做些什麼? – Yellowman94