XNA绘制:在整个游戏中使用一个spritebatch

时间:2012-10-03 18:37:59

标签: xna spritebatch

我正在开发一款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是公共的,则可以调用它的spritebatch。

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

感谢您的建议。

3 个答案:

答案 0 :(得分:4)

DrawableGameComponent的一个严重缺点是您被锁定在其提供的方法签名中。虽然没有任何“错误”,但本身使用DrawableGameComponent,不要将其视为“ one true architecture ”。您better off将其视为可能architecture的一个示例。

如果您发现自己需要将SpriteBatch(或其他任何内容)传递给“游戏组件”的绘制方法 - 的最佳方式将其传递为一个论点。其他任何事都令人费解。

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


当然,如果您必须使用GameComponent - 或者您的游戏非常简单(例如:原型),您并不真正关心架构 - 那么您基本上可以使用 any 您希望获得SpriteBatch绘制方法的方法。它们都有缺点。

可能最后一个架构上很健壮的方法是将SpriteBatch实例传递给每个组件的构造函数。这可以使您的组件与游戏类分离。

另一方面,如果您将建筑物投入风中,我建议您制作MyGame.spriteBatch字段public static。这是允许在任何地方访问它的最简单方法。如果需要,它很容易实现并且易于清理。


回答有关效果的问题:与传递SpriteBatch相关的任何操作对性能的影响几乎可以忽略不计(提供对Draw / Begin / {{的调用顺序1}}保持不变)。别担心。

(如果在代码中看到End,则表示引用。引用是32位值(在32位程序中,所有XNA游戏都是)。这与{的大小相同{1}}或SpriteBatch whatever。传递/访问/等等,它非常小且非常便宜。)

答案 1 :(得分:4)

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

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

我觉得有必要纠正这个问题,因为“最好的办法是将其作为一个论点。其他任何事情都是错综复杂的。”只是不正确。< / p>

就我个人而言,我现在正在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);
    }

现在,由于您在Game类的Initialize方法中添加了DrawableGameComponents,因此您可以调用

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

我认为这是解决问题的最简洁方法。

答案 2 :(得分:1)

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

如果您愿意,也可以将SpriteBatch作为Game课程的属性公开,就像您建议的那样,但每次引用this.Game时,您都需要将其转换为Game您的特定((MyGame)this.Game).SpriteBatch.Draw(...) 班级类型。

DrawableGameComponent

或者您可以让SpriteBatch创建新的DrawableGameComponent。这没有什么不对(据我所见)。我想这取决于你要创造多少{{1}}个和多少次。

同时浏览search for DrawableGameComponent的结果 - 那里有很多好建议。