Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpriteBatch: "Begin cannot be called again until End has been successfully called."

So I started up my current project, and the first thing I did was run it, and it gave me the above exception. It was running fine last night. This is all the code in my Draw event. spriteBatch.Begin doesn't appear anywhere else in the project. Removing the Begin here causes the spriteBatch.Draw to throw an exception, putting a spriteBatch.End right before the begin also throws an exception. I'm at a loss as to what's wrong and how to fix this.

GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin();
spriteBatch.Draw(background, Vector2.Zero, Color.White);

player.Draw(spriteBatch);
level1.Draw(spriteBatch);

spriteBatch.End();

base.Draw(gameTime);
like image 472
GanonsSpirit Avatar asked Nov 21 '12 21:11

GanonsSpirit


2 Answers

Well I need to see your levek1.Draw and player.Draw for my info, but what im expecting this. In one of you methods, you are calling spriteBatch.Begin(), You MUST call End() before calling this.

So if your player class draw method looks like this

Draw(Spritebatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Draw(PlayerSprite,PlayerPosition, etc);
spriteBatch.End();
}

You need to remove the Begin and End calls, because they were already called by the parent method.

EDIT: Didn't read clearly, I see you belive that this is not the problem, But we need to see the other methods to figure out the problem.

like image 194
Cyral Avatar answered Oct 21 '22 01:10

Cyral


It's possible that one of your draw calls is throwing an exception. This would throw you out of the method without calling spriteBatch.End(), and then the next time through, you'd get an exception on spriteBatch.Begin(). (Although I would wonder why the first exception didn't end your program, but the second one did.)

If that is the issue, one solution would be to wrap the draw calls in a try/finally block:

spriteBatch.Begin();
spriteBatch.Draw(background, Vector2.Zero, Color.White);

try {
   player.Draw(spriteBatch);
   level1.Draw(spriteBatch);
} finally {
   spriteBatch.End();
}

Another possibility is that you are actually accidentally calling spriteBatch.Begin() twice. Personally I avoid doing this by wrapping the SpriteBatch object in a different class.

Ex:

internal sealed class DrawParams
{
   private SpriteBatch mSpriteBatch;
   private bool mBegin;

   /// <summary>Calls SpriteBatch.Begin if the begin value is true. Always call this in a draw method; use the return value to determine whether you should call EndDraw.</summary>
   /// <returns>A value indicating whether or not begin was called, and thus whether or not you should call end.</returns>
   public bool BeginDraw()
   {
      bool rBegin = mBegin;

      if (mBegin)
      {
         mSpriteBatch.Begin();
         mBegin = false;
      }

      return rBegin;
   }

   /// <summary>Always calls SpriteBatch.End. Use the return value of BeginDraw to determine if you should call this method after drawing.</summary>
   public void EndDraw()
   {
      mSpriteBatch.End();
   }
}
like image 45
Dave Cousineau Avatar answered Oct 21 '22 00:10

Dave Cousineau