SpriteBatch:"在成功调用End之前,不能再次调用Begin。"

时间:2012-11-21 21:58:45

标签: c# exception xna spritebatch

所以我启动了我当前的项目,我做的第一件事是运行它,它给了我上面的例外。昨晚运行得很好。这是我的Draw事件中的所有代码。 spriteBatch.Begin不会出现在项目的任何其他位置。在这里删除Begin会导致spriteBatch.Draw抛出异常,在begin之前放置spriteBatch.End也会引发异常。我不知道什么是错的,以及如何解决这个问题。

GraphicsDevice.Clear(Color.CornflowerBlue);

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

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

spriteBatch.End();

base.Draw(gameTime);

5 个答案:

答案 0 :(得分:1)

嗯,我需要看看你的levek1.Draw和player.Draw我的信息,但我期待的是什么。在你的一个方法中,你正在调用spriteBatch.Begin(),你必须在调用它之前调用End()

因此,如果您的玩家类绘制方法看起来像这样

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

您需要删除BeginEnd来电,因为它们已被父方法调用。

编辑:没看清楚,我看到你相信这不是问题,但我们需要看到其他方法来找出问题。

答案 1 :(得分:1)

你的一个绘制调用可能会抛出异常。如果没有调用spriteBatch.End(),这会让你退出方法,然后下一次,你会在spriteBatch.Begin()上得到一个例外。 (虽然我想知道为什么第一个例外并没有结束你的程序,但第二个例外确实如此。)

如果这是问题,一个解决方案是将绘制调用包装在try / finally块中:

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

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

另一种可能性是你实际上不小心打了spriteBatch.Begin()两次。我个人通过将SpriteBatch对象包装在另一个类中来避免这样做。

例如:

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();
   }
}

答案 2 :(得分:0)

ctrl+F并选择Entire Solution,查找spriteBatch.Begin()并将其删除不属于的地方。我怀疑您在playerlevel平局电话中可能会有额外的副本。

另外请确保您为精灵批处理使用了正确的变量,它可能被称为SpriteBatch,首字母大写。

无论如何,您可以尝试从项目中删除(使用//注释)所有spritebatch调用,看看它是否仍然会抛出异常。

答案 3 :(得分:0)

我自己有这个确切的问题,这里没有提出任何建议。最后,我意识到在我的开始/结束部分,我是await异步方法。

意识到这可能会在完成之前重新启动方法,我只需添加一个bool isDrawing变量并在绘制之前检查它。

HTH

答案 4 :(得分:0)

如果你在 spritebatch 忙于绘图时退出它,你会遇到同样的问题。例如,当您从另一个事件(例如计时器)离开屏幕时。

就我而言,我已经声明了一个私有变量,用于存储 SpriteBatch 是否被中断,

private bool _spriteBatchInterrupted = false;

并在 SpriteBatch 持续绘制时检查它,

    Game.SpriteBatch.Begin();
    if (_spriteBatchInterrupted)
    {
        Game.SpriteBatch.End();
        return;
    }...

然后在其他事件中设置变量,例如timer lapsed事件

private void CountdownTimer_Elapsed(object sender, ElapsedEventArgs e)
{
   _spriteBatchInterrupted = true;
   NavigateTask();
}