XNA绘制:在整个游戏中使用一个精灵批次



我正在开发一款XNA游戏。这是我对架构小心的时候了。直到今天,我一直用这种方式实现我自己的绘制方法:

public void Draw(SpriteBatch sb, GameTime gameTime)
{
sb.Begin();
// ... to draw ...
sb.End();
}

我在挖掘DrawableGameComponent,看到Draw方法是这样来的:

public void Draw(GameTime gameTime)
{
// ...
}

首先,我知道SpriteBatch可以在Begin和End之间收集许多Texture2D,因此对它们进行排序或使用相同的效果绘制会很有用。

我的问题是关于通过SpriteBatch的性能和成本。在DrawableGameComponent中,如果游戏对象的spritebatch是公共的,就可以调用它。

建议是什么,xna游戏程序员应该做什么?

谢谢你的建议。

DrawableGameComponent的一个严重缺点是您被锁定在其提供的方法签名中。虽然DrawableGameComponent本身没有什么"错误",但不要认为它是"一个真正的体系结构"。你最好把它看作一个可能的体系结构的例子。

如果您发现自己需要将SpriteBatch(或其他任何东西)传递到"游戏组件"的绘制方法-的最佳方法是将其作为参数传递。其他任何事情都是错综复杂的。

显然,这意味着您不能使用XNA提供的GameComponent系统,您必须做出自己的选择。但这几乎是微不足道的:在最基本的层面上,它只是一些具有适当虚拟方法的基类型的列表。


当然,如果你必须使用GameComponent,或者你的游戏非常简单(例如:原型),以至于你并不真正关心架构,那么你基本上可以使用你喜欢的任何方法来获得SpriteBatch。它们都有缺点。

下一个架构上最健壮的方法可能是将SpriteBatch实例传递到每个组件的构造函数中。这样可以使组件与游戏类解耦。

另一方面,如果你把架构抛到九霄云外,我建议你把MyGame.spriteBatch字段设为public static。这是允许在任何地方访问它的最简单方法。它很容易实现,以后需要时也很容易清理。


回答您关于性能的问题:任何与传递SpriteBatch有关的事情对性能的影响都几乎可以忽略不计(如果对Draw/Begin/End的调用顺序保持不变)。别担心。

(如果您在代码中看到SpriteBatch whatever,则表示引用。引用是32位值(在32位程序中,所有XNA游戏都是)。这与intfloat的大小相同。它非常小,而且非常便宜,可以四处走动/进入等)

如果你偶然发现这个问题,你可能正在寻找一个不错的通用解决方案。我建议你看看这个:

https://gamedev.stackexchange.com/questions/14217/several-classes-need-to-access-the-same-data-where-should-the-data-be-declared/14232#14232

我觉得有必要纠正这个问题,因为"最好的方法是把它作为一个论点来传递。其他任何事情都很复杂。">只是不正确

就我个人而言,我现在在我的GameBase类中是这样做的:

protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
SpriteBatch = new SpriteBatch(GraphicsDevice);
this.Services.AddService(typeof(SpriteBatch), SpriteBatch);
}

现在,由于您在游戏类的Initialize方法中添加了DrawableGameComponents,您将能够调用

this.Game.Services.GetService(typeof(SpriteBatch))

我认为这是解决问题最干净的方法。

如果DrawableGameComponent应该是父级SpriteBatch的一部分,那么只需通过构造函数将其传入并存储在私有成员中(如果愿意,也可以将其作为属性公开)。

如果需要,也可以将SpriteBatch公开为Game类的属性,就像您建议的那样,但每次引用this.Game时,都需要将其强制转换为特定的Game类类型。

((MyGame)this.Game).SpriteBatch.Draw(...)

或者您可以让DrawableGameComponent创建一个新的SpriteBatch。这没什么错(就我所见)。我想这取决于你要创建多少个DrawableGameComponent以及多久创建一次。

也可以浏览搜索DrawableGameComponent的结果——那里有很多好的建议。

相关内容

最新更新