我正在开发一款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游戏都是)。这与int
或float
的大小相同。它非常小,而且非常便宜,可以四处走动/进入等)
如果你偶然发现这个问题,你可能正在寻找一个不错的通用解决方案。我建议你看看这个:
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
的结果——那里有很多好的建议。