2013-02-21 102 views
0

我有一小部分遊戲基本上顯示了一本書的一頁。 Update方法不會做任何事情,Draw方法如下:XNA遊戲中的內存泄漏

public override void Draw(GameTime gameTime) 
{ 
    SpriteBatch spriteBatch = ScreenManager.SpriteBatch; 

    spriteBatch.Begin(); 
    spriteBatch.Draw(background.Image, background.Bounds, Color.White); 
    spriteBatch.DrawString(font, name, new Vector2(ScreenManager.GraphicsDevice.Viewport.Width/2 - font.MeasureString(name).X/2, 100), Color.Black); 
    spriteBatch.DrawString(font, currentPage.PageText, new Vector2(currentPage.TextArea.X, currentPage.TextArea.Y), Color.Black); 
    if (currentPageNumber != 1) 
    { 
     spriteBatch.Draw(next.Image, previous.Bounds, null, Color.White, 0.0F, Vector2.Zero, SpriteEffects.FlipHorizontally, 0.0F); 
    } 
    if (currentPageNumber != noOfPages) 
    { 
     spriteBatch.Draw(next.Image, next.Bounds, Color.White); 
    } 
    DrawEmptyRectangle(spriteBatch, 3F, Color.Black, new Rectangle(back.Bounds.X - 1, back.Bounds.Y - 1, back.Bounds.Width + 1, back.Bounds.Height + 1)); 
    DrawEmptyRectangle(spriteBatch, 3F, Color.Black, new Rectangle(play.Bounds.X - 1, play.Bounds.Y - 1, play.Bounds.Width + 1, play.Bounds.Height + 1)); 
    DrawCenteredText(spriteBatch, font, BACK_TEXT, back.Bounds, Color.Black); 
    DrawCenteredText(spriteBatch, font, PLAY_TEXT, play.Bounds, Color.Black); 
    spriteBatch.End(); 
} 

public void DrawCenteredText(SpriteBatch spriteBatch, SpriteFont font, string text, Rectangle toCenterIn, Color textColor) 
{ 
    spriteBatch.DrawString(font, text, new Vector2(toCenterIn.X + toCenterIn.Width/2 - font.MeasureString(text).X/2, toCenterIn.Y + toCenterIn.Height/2 - font.MeasureString(text).Y/2), textColor); 
} 

public void DrawEmptyRectangle(SpriteBatch spriteBatch, float width, Color color, Rectangle rectangle) 
{ 
    Vector2 topLeft = new Vector2(rectangle.Left, rectangle.Top); 
    Vector2 bottomLeft = new Vector2(rectangle.Left, rectangle.Bottom); 
    Vector2 topRight = new Vector2(rectangle.Right, rectangle.Top); 
    Vector2 bottomRight = new Vector2(rectangle.Right, rectangle.Bottom); 

    _2DLine.Draw(ScreenManager.GraphicsDevice, spriteBatch, width, color, topLeft, topRight); 
    _2DLine.Draw(ScreenManager.GraphicsDevice, spriteBatch, width, color, bottomLeft, bottomRight); 
    _2DLine.Draw(ScreenManager.GraphicsDevice, spriteBatch, width, color, topLeft, new Vector2(bottomLeft.X, bottomLeft.Y + width)); 
    _2DLine.Draw(ScreenManager.GraphicsDevice, spriteBatch, width, color, topRight, bottomRight); 
} 

這是_2DLine.Draw方法:

public static void Draw(GraphicsDevice GraphicsDevice, SpriteBatch batch, float width, Color color, Vector2 point1, Vector2 point2) 
{ 
    Texture2D blank = new Texture2D(GraphicsDevice, 1, 1, false, SurfaceFormat.Color); 
    blank.SetData(new[] { Color.White }); 

    float angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X); 
    float length = Vector2.Distance(point1, point2); 

    batch.Draw(blank, point1, null, color, angle, Vector2.Zero, new Vector2(length, width), SpriteEffects.None, 0); 
    } 

的問題是,時間越長,我離開運行多個程序它分配的內存。

+1

您使用的是代碼分析嗎? CA2000規則將幫助指出它看不到的一次性物品的實例。 – DaveShaw 2013-02-21 22:52:02

回答

6

你的泄漏是在這裏:

Texture2D blank = new Texture2D(GraphicsDevice, 1, 1, false, SurfaceFormat.Color); 

你不應該分配的紋理像這樣的每一幀。創建一個並重新使用它。當你完成它的時候,調用它的Dispose()方法,以便它釋放它的底層Direct3D資源。

+0

所以我應該在每次抽獎後立即調用它的Dispose()。我不清楚電話應該在哪裏。另外,我一般在開發時從來沒有稱過Dispose()。我假設ContentManager.Unload()自動執行此操作,對嗎? – 2013-02-21 22:57:45

+3

你*可以在每一幀上新建一個Texture2D並處理它,但是這對性能來說會很糟糕。相反,創建一個Texture2D(在初始化時),並在每個幀上重新使用它。當你知道的時候調用Dispose()將不再使用它。 ContentManager自動處理它管理的對象,即通過ContentManager.Load <>獲得的對象。當你像在這裏做新事物時,你需要負責管理他們的一生。 – Asik 2013-02-21 23:06:32