XNA:使用一个spritebatch的简单方法

本文关键字:spritebatch 一个 简单 方法 XNA | 更新日期: 2023-09-27 18:18:34

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

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

XNA:使用一个spritebatch的简单方法

  1. 创建自己的基类,取代DrawableGameComponent(以及相关的基础设施-基本上有一个List<MyComponentBaseType>)。
  2. 修改该基类的Draw方法,使其接受SpriteBatch参数
  3. 利润。

参见这里,这里和这里的讨论,详细解释为什么这是一个好主意(以及GameComponentIServiceProvider 真正的是什么)。

我一直是这么想的,直到我意识到游戏"服务"的真正目的和能力,以及它们与装箱/拆箱和。net类型系统的联系。

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

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

这方面的一个例子是SpriteBatch。通过将SpriteBatch添加到游戏的服务中,并将其注册为typeof(SpriteBatch),任何组件都可以通过向GetService方法提供typeof(SpriteBatch)来从服务中提取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"); }
    }
  }
}

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

请务必注意,虽然添加到服务将抛出一个异常,如果给定的项目是空的,从他们不会,它将简单地返回空并继续执行,因此空检查必须尽快执行。还需要注意的是,如果一个组件是在游戏中期创建的,那么它的初始化将不会被调用,所以这必须通过某种方式得到补偿。

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