1

很多时候,我发现自己想知道是否有一种简单的方法可以在 XNA 中只使用一个 spritebatch,发现微软的内置组件系统是一个好主意,但构建起来却很神秘。

我只能假设 XNA 的很多方式是由于向后兼容性或 Xbox 兼容性,这本身并不是坏事,而且我确信有一些细节会导致事情按照它们的方式开发,但主系统似乎有点神秘。

4

2 回答 2

0
  1. 制作您自己的替换基类DrawableGameComponent(以及相关的基础设施 - 基本上有一个List<MyComponentBaseType>)。
  2. 修改该Draw基类的方法以获取SpriteBatch参数。
  3. 利润。

请参阅此处此处此处的讨论,详细解释为什么这是一个好主意(以及GameComponent真正IServiceProvider用途和用途)。

于 2013-06-14T10:59:42.003 回答
-1

这就是我一直以来的想法,直到我意识到游戏“服务”的真正目的和能力,以及它们与装箱/拆箱和 .Net 类型系统的联系。

我承认微软的一个缺点是他们缺乏创造性的命名。起初我一直认为游戏服务与系统服务相关联,或者服务是某种特殊的类或接口。

事实上,游戏的服务集合只不过是对象的集合。服务允许任何已连接到游戏的游戏组件从游戏中检索数据。

SpriteBatch 就是一个例子。通过将 SpriteBatch 添加到游戏的服务中,并将其注册到 typeof(SpriteBatch),任何组件都可以通过将 typeof(SpriteBatch) 提供给 GetService 方法从服务中提取该 SpriteBatch。

下面是一些示例代码(未经测试,只是一个示例):

public namespace MyGame
{
  public class MainGame:Game
  {
    SpriteBatch spriteBatch;
    protected override void Initialize()
    {
      spriteBatch = new SpriteBatch(GraphicsDevice);
      Services.AddService(typeof(SpriteBatch), spriteBatch);
      base.Initialize();
    }
  }
  public class DrawableComponent : DrawableGameComponent
  {
    SpriteBatch spriteBatch;
    public override void Initialize()
    {
      spriteBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
      if(spriteBatch == null)
      { throw new Exception("No SpriteBatch found in services"); }
    }
  }
}

我在这里的例子也展示了一个非常被忽视的因素。Microsoft 的默认游戏模板将 SpriteBatch 创建放在加载内容方法中,导致许多人认为必须保留在那里。事实上,你可以自由地将它向前移动,直到初始化方法(但不是构造函数),这意味着它可以在任何组件初始化之前被移动到服务中,从而确保所有组件都从初始化方法中的服务将获得一个。

请务必注意,如果给定项目为 null,则添加到服务会引发异常,从它们中取出不会,它只会返回 null 并继续执行,因此必须尽快执行 null 检查。另请注意,如果在游戏中期创建组件,则不会调用其初始化,因此必须通过某种方式对其进行补偿。

这种技术的更多例子可以在这里找到:http: //itspaulsblog.blogspot.co.uk/2011/02/xna-common-sprite-batch-as-game-service.html

于 2013-06-14T04:54:20.063 回答