2011-12-03 81 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