2011-12-03 82 views
1

我想在C#中繪製瓷磚地圖,我遇到的問題在我看來很奇怪。OutOfMemoryException當試圖繪製瓷磚地圖

我有這個int數組,用於保存x座標和y座標以在屏幕上繪製切片。 (不僅0中的箭頭爲X,另一條是Y)

這是我如何使用循環來渲染瓦到屏幕的一部分,它在這裏我發現了一個「 OutOfMemoryException異常」上線,我會註釋掉:

public void DrawTest(SpriteBatch spriteBatch) 
    { 
     for (int x = 0;; x++) 
     { 
      for (int y = 0;; y++) 
      { 
       x = level1[x, 0]; 
       y = level1[0, y]; 

       //This line bellow is where it says OutOfMemoryException 
       spriteBatch.Draw(tileSheet, new Rectangle(x, y, 32, 32), new Rectangle(0, 0, 32, 32), Color.White); 

       if (x >= 5 | y >= 5) 
       { 
        x = 0; 
        y = 0; 
       } 
      } 
     } 
    } 

當我想打電話給該渲染方法我做它的主類Render方法

levelLoader.DrawTest(this.spriteBatch); 

它的工作完美我用這個DrawTest前方法ry畫瓦片。但我完全不知道爲什麼這不能正常工作。

UPDATE:

public void DrawTest(SpriteBatch spriteBatch) 
     { 
      for (int x = 0; x < 5 ; x++) 
      { 
       for (int y = 0; y < 5 ; y++) 
       { 
        x = level1[x, 0]; 
        y = level1[0, y]; 
        spriteBatch.Draw(tileSheet, new Rectangle(x, y, 32, 32), new Rectangle(0, 0, 32, 32), Color.White); 
       } 
      } 
     } 

UPDATE2:

 public void DrawTest(SpriteBatch spriteBatch) 
    { 
     for (int x = 0; x < 5 ; x++) 
     { 
      for (int y = 0; y < 5 ; y++) 
      { 
       int tileXCord = level1[x, 0]; 
       int tileYCord = level1[0, y]; 
       spriteBatch.Draw(tileSheet, new Rectangle(tileXCord, tileYCord, 32, 32), new Rectangle(0, 0, 32, 32), Color.White); 
      } 
     } 
    } 
+0

您可能已嘗試批量處理無限數量的繪製調用。你想用這個奇怪的循環做什麼? – harold

+0

林試圖創建一個類,將繪製遊戲的地圖即時製作.. – Rakso

回答

2

我看到你的代碼的幾個問題:

  1. 你在你的代碼有一個無限循環這裏。什麼是你的嵌套循環的終止條件?
  2. (重要!)spriteBatch.Draw()方法不繪製任何東西,它只是安排你的精靈繪圖。此方法調用之前應該有spriteBatch.Begin()(以開始計劃他的繪圖),並且最終您必須致電spriteBatch.End()將排定的spite移至設備。無限循環會導致精靈繪圖的無限調度,直到內存已滿並且您面臨內存不足異常。
  3. (!注)你調理(x >= 5 | y >= 5)您使用按位或比較,你不應該這樣做(除非有目的的,我沒有看到這裏,而使用布爾OR:(x >= 5 || y >= 5)
  4. 它是一個非常不好的習慣修改環路本身內循環的計數器。它是不是唯一的錯誤容易,也很難理解和支持你的代碼,這樣寫。

我將重新編寫代碼這種方式

spriteBatch.Begin(); 
    for (int x = 0; x < 5; x++) 
    { 
     for (int y = 0; y < 5; y++) 
     { 
      x = level1[x, 0]; 
      y = level1[0, y]; 

      //This line bellow is where it says OutOfMemoryException 
      spriteBatch.Draw(tileSheet, new Rectangle(x, y, 32, 32), new Rectangle(0, 0, 32, 32), Color.White); 
     } 
    } 
    spriteBatch.End(); 

它將在主遊戲循環的每個Draw()事件中重新繪製所有圖塊(如果您仍然從您的Game類的Draw()方法中調用此方法。 XNA會根據您的PC性能以及每幀需要完成的計算量來改變FPS率。

+0

它不需要使用spriteBatch.Begin()和End()我對玩家類做了同樣的想法,它完美的工作..但在這裏它有點不同。如果我在這裏做一個更新方法,它將是許多不同的spriteBatch.Draw()和IM規劃也havinh多個層次,這也會使它spageti代碼。 – Rakso

+0

不,它是必需的(但每個Draw()事件最好只做一次),閱讀[here](http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics .spritebatch_members.aspx)。你可以在你的'Draw()'方法中使用'Begin()'和'End()',只需在繪圖的開始和結束處調用所有Draw方法。 –

+0

+1好答案。只是爲了迂迴:XNA的默認設置使用固定的幀率。如果連續繪製也使用相同的紋理([ref](http://gamedev.stackexchange.com/a/9289/288)),則將事物保留在一個開始/結束塊中僅僅是性能優勢。 –

0

我認爲你是停留在一個無限循環。您需要以某種方式退出以避免內存不足異常。

+0

我將如何使瓷磚被繪製? – Rakso