我刚刚开始玩XNA,但在网上找不到关于这个问题的任何内容。有没有办法判断是否已在特定的SpriteBatch对象上调用SpriteBatch.Begin(和相反的End)?
目前,我只为系统使用一个基本上全局的SpriteBatch对象,主要是因为这似乎是我读过的文章中的首选方法。我假设为每个对象创建一个SpriteBatch实例会导致过多的开销。无论如何,我在保持SpriteBatch.Begin / End同步方面遇到了问题。特别是当绘图对象可以包含其他绘图对象时。如果我可以测试是否已经调用了Begin / End,那么我的问题就会消失。我想我可以尝试像SpriteBatch类的子类化,但在我看来,这个操作是如此基本,以至于必须有一个内置的方式来告诉。我只是无法弄清楚如何。
感谢您提供的任何见解!
答案 0 :(得分:1)
如果您查看此链接,我认为它会回答您的问题,对不起,如果该链接的版本与您使用的版本不同:
http://www.ziggyware.com/forum/viewthread.php?forum_id=12&thread_id=12996
由开发人员决定他们编写的代码是否在开头和结尾之内。你想要确保你“抓住”你需要绘制的所有内容,直到你打电话给“开始”然后在那之后画画。
此外,您可能想看一些关于“游戏循环”的文章以及它们如何操作它将帮助您更好地理解如何以不应该出现此问题的方式进行编码。
希望这有帮助! : - )
例如,创建一个可以继承的接口,它具有Draw()方法。然后回到游戏循环中,确保循环浏览所有要绘制的对象(从该界面继承)并在开始结束行中调用它们的draw方法。每个对象中的代码都可以具有绘图细节,但是你知道它会在假设时被调用。也许这会澄清一点。
答案 1 :(得分:1)
我假设为每个对象创建一个SpriteBatch实例会导致过多的开销。
顾名思义,SpriteBatch用于组织一批精灵,并以特定方式在缓冲区中绘制它们。当你调用SpriteBatch.End()时,SpriteBatch中添加的sprite会被排序(或不)并使用特定的混合模式和SpriteBatch.End()之前指定的其他选项写入缓冲区(例如:屏幕)。 p>
当你调用SpriteBatch.Begin()时,你必须在再次调用SpriteBatch.Begin()之前调用SpriteBatch.End()(使用相同的SpriteBatch对象)。
所以这段代码错了:
class Main
{
private Ship ship;
private SpriteBatch spriteBatch;
//logic to create the ship/spriteBatch
public override void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Begin();
ship.Draw(spriteBatch);
spriteBatch.End();
}
}
class Ship
{
private Texture2D image;
//logic to create the image
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Draw(image, Vector2.Zero, Color.White);
spriteBatch.End();
}
}
因为spriteBatch.Begin被调用两次。正确的方法:
class Main
{
private Ship ship;
private SpriteBatch spriteBatch;
//logic to create the ship/spriteBatch
public override void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Begin();
ship.Draw(spriteBatch);
spriteBatch.End();
}
}
class Ship
{
private Texture2D image;
//logic to create the image
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(image, Vector2.Zero, Color.White);
}
}