3

我正在开发 XNA 游戏。这是我对架构小心的时候了。直到今天,我一直都是这样实现自己的 draw 方法的:

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-game程序员应该做什么?

谢谢指教。

4

3 回答 3

5

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

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

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

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

我会说这是解决问题的最干净的方法。

于 2013-05-30T14:13:07.903 回答
4

的严重缺点之一DrawableGameComponent是您被锁定在其提供的方法签名中。虽然没有什么“错误”,但就其本身而言,DrawableGameComponent不要将其视为“一个真正的架构”。您最好将其视为可能架构的示例。

如果您发现自己需要将 a SpriteBatch(或其他任何东西)传递给“游戏组件”的 draw 方法 -最好的方法将其作为参数传递。其他任何事情都是令人费解的。

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


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

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

另一方面,如果你把建筑抛在脑后,我建议你做你的MyGame.spriteBatchfield public static。这是允许在任何地方访问它的最简单方法。它很容易实现,并且在以后/如果需要时易于清理。


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

(如果您SpriteBatch whatever在代码中看到,它代表一个引用。引用是一个 32 位值(在 32 位程序中,所有 XNA 游戏都是)。它的大小与 anint或 a相同float。它非常小而且非常便宜传递/访问/等)

于 2012-10-04T10:53:04.437 回答
1

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

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

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

或者你可以只DrawableGameComponent创建一个新的SpriteBatch. 这没有什么问题(据我所见)。我想这取决于您将创建多少DrawableGameComponents 以及多久创建一次。

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

于 2012-10-03T19:32:33.670 回答