Object disposed exception to be thrown
I have recently integrated in a HUD method into my XNA game project and when the method is called by the main Draw method it throws out a object disposed exception this has something to do with the two Drawstring used in the program.
The exception is thrown at spriteBatch.End() and says Cannot access a disposed object. Object name: 'Texture2D'.
//initiation of the spritebatch
private SpriteBatch spriteBatch;
//game draw method
public override void Draw(GameTime gameTime)
{
ScreenManager.GraphicsDevice.Clear(Color.CornflowerBlue);
// Our player and enemy are both actually just text strings.
spriteBatch = ScreenManager.SpriteBatch;
tileMap.Draw(spriteBatch, camera);
spriteBatch.Begin(SpriteSortMode.Deferred,
BlendState.AlphaBlend,
null, null, null, null,
camera.TransformMatrix);
DrawHud();
level.Draw(gameTime, spriteBatch);
spriteBatch.End();
// If the game is transitioning on or off, fade it out to black.
if (TransitionPosition > 0 || pauseAlpha > 0)
{
float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);
ScreenManager.FadeBackBufferToBlack(alpha);
}
base.Draw(gameTime);
}
the HUD method
private void DrawHud()
{
Rectangle titleSafeArea = ScreenManager.GraphicsDevice.Viewport.TitleSafeArea;
Vector2 hudLocation = new Vector2(titleSafeArea.X + camera.Position.X, titleSafeArea.Y + camera.Position.Y);
Vector2 center = new Vector2(titleSafeArea.Width + camera.Position.X / 2.0f,
titleSafeArea.Height + camera.Position.Y / 2.0f);
// Draw time remaining. Uses modulo division to cause blinking when the
// player is running out of time.
string timeString = "TIME: " + level.TimeRemaining.Minutes.ToString("00") + ":" + level.TimeRemaining.Seconds.ToString("00");
Color timeColor;
if (level.TimeRemaining > WarningTime ||
level.ReachedExit ||
(int)level.TimeRemaining.TotalSeconds % 2 == 0)
{
timeColor = Color.Yello开发者_StackOverfloww;
}
else
{
timeColor = Color.Red;
}
DrawShadowedString(hudFont, timeString, hudLocation, timeColor);
// Draw score
float timeHeight = hudFont.MeasureString(timeString).Y;
DrawShadowedString(hudFont, "SCORE: " + level.Score.ToString(), hudLocation + new Vector2(0.0f, timeHeight * 1.2f), Color.Yellow);
}
//method which draws the score and the time (and is causing the problem)
private void DrawShadowedString(SpriteFont font, string value, Vector2 position, Color color)
{
spriteBatch.DrawString(font, value, position + new Vector2(1.0f, 1.0f), Color.Black);
spriteBatch.DrawString(font, value, position, color);
}
As the exception says, the problem exists because one of the Texture2Ds you are using is being disposed before you are using it.
There are two things in the XNA API (that come to mind) that will dispose of a Texture2D: The ContentManager.Unload()
method for any textures loaded by that content manager, and the Texture2D.Dispose()
method. So check if your own code is calling one of these two functions at any point.
The exception will only be thrown when the Texture2D instance is "used". Because SpriteBatch batches together texture draws, the texture doesn't actually get used until you end the SpriteBatch (at which point it draws everything in one go). If you change to SpriteSortMode.Immediate
SpriteBatch will stop batching sprites and will instead draw them "immediately" you ask it to. This will cause the texture to be used and the exception to be thrown at a Draw
call instead of an End
call, which should make it easier to identify which texture is being disposed of while still in use.
The code you have posted seems to be fine, I suspect the problem exists elsewhere in your code. The above information should help you identify where the problem is.
My guess is that something is happening in level.Draw that is disposing of a texture somewhere. It doesn't look like the drawhud method in particular is responsible
You mention though that you are sure it's caused by the drawstring methods ... if you comment those two out in particular does the error go away?
精彩评论