使用XNA的ContentTypeWriter类将DrawableGameComponent序列化为XML

时间:2009-06-16 00:59:16

标签: c# xml xna

我正在XNA中编写一个小型2D射击游戏,我已经决定,为了能够在游戏中实现自定义内容,它会从XML文件中加载游戏对象的定义。当我发现XNA有一个易于使用的XML序列化程序时,它使它更容易。问题是,我要序列化的对象是DrawableGameComponent。 XNA的XML序列化程序,即您为创建自定义内容编写器而扩展的ContentTypeWriter类,要求对象具有默认情况下没有参数的构造函数。但是,DrawableGameComponent在其构造函数中需要一个Game对象,并且在初始化对象后不允许您设置游戏。但是,我不能足够地修改ContentTypeWriter的行为来接受非空构造函数,因为内容是由一个我无法覆盖的完全不同的方法加载的。基本上我有这个:

class Star : DrawableGameComponent{
    public Star(Game game)
        : base(game)
    {
    }
}

ContentTypeWriter要求构造函数不带参数。我不能创建一个,因为那时我无法将一个Game对象放入Star类。我可能只是不能使它成为DrawableGameComponent,但我试图将这些对象与主要游戏类分离,以便我可以重复使用它们等。如果没有Game对象,这是非常困难的。因此,我的问题是,有没有人知道如何修改ContentTypeWriter足以允许带有参数的构造函数,或者任何方法?

我还考虑过使用XPath或Linq XML类编写自己的XML解析代码,但是如果我在项目中有任何不遵循XNA架构但不会构建的XML文件,那么XNA会引发一个问题。编写只包含类的主要字段和使用装饰器模式的DrawableGameComponent版本的基类,并仅序列化基类是否合理?我正在拔出我的头发试图解决这个问题,并想知道在这种情况下我应该做些什么。

1 个答案:

答案 0 :(得分:2)

我也是通过解析级别文件来构建关卡,我使用System.Xml来加载数据。我更改了添加到以下内容的Xml文件的属性: 构建动作:无 复制到输出目录:如果更新则复制

然后我写了一些像这样的代码:

public static LevelInfo LoadLevel(
    string xmlFile, 
    GraphicsDevice device, 
    PhysicsSimulator sim, 
    ContentManager content)
{
    FileInfo xmlFileInfo = new FileInfo(xmlFile);

    XDocument fileDoc = XDocument.Load(xmlFile);
    //this part is game specific
    LevelInfo levelData = new LevelInfo();
    levelData.DynamicObjects = LevelLoader.LoadDynamicObjects(device, sim, content, xmlFileInfo, fileDoc);
    levelData.StaticObjects = LevelLoader.LoadStaticObjects(device, sim, content, xmlFileInfo, fileDoc);
    levelData.LevelAreas = LevelLoader.LoadAreas(device, xmlFileInfo, fileDoc);
    return levelData;
}

这只是一个示例,但它允许您根据需要使用任何XML数据构建对象。

对于那些好奇的人,这是xml文件:

<Level>
  <Object Type="Custom" 
          PositionX="400" 
          PositionY="400" 
          IsStatic="true"
          Rotation="0"
          Texture="sampleObj1_geometrymap"
          Mass="5"
          ColorR="0"
          ColorG="255"
          ColorB="0">
  </Object>
  <Object Type="Custom"
          PositionX="400"
          PositionY="600"
          IsStatic="false"
          Rotation="0"
          Texture="sampleObj2_geometrymap"
          Mass="5"
          ColorR="230"
          ColorG="230"
          ColorB="255">
  </Object>
  <Object Type="Area"
          MinPositionX="0"
          MinPositionY="0"
          MaxPositionX="300"
          MaxPositionY="300"
          AreaType="Goal">
  </Object>
</Level>