繁体   English   中英

从XNA中的xml文件加载级别数据

[英]Loading level data from xml file in XNA

我正在XNA中创建一个基于磁贴的游戏,并将从xml文件加载级别信息。 我没有加载xml数据的问题,但我想反馈我正在考虑用于读取xml文件的方法。

代码具有类层次结构,以便:

Level类包含:
- TileLayers的集合
- Tilesets的集合

TileLayer类包含
- 瓷砖的集合

Tileset类包含:
- TilsetTiles的集合

TilesetTile类包含:
- 一个TileId
- TileProperties的集合
- TileRectangle

上述每个类都需要xml级别文件中的一些信息。

当我加载一个级别时,我想简单地调用Level.Load();

我的意图是每个类都有一个Load()方法,它将:
1.从xml文件加载所需的任何特定信息。
2.在其子节点上调用Load()。

我看到的问题是处理xml的代码将分散在不同的文件中,使更改难以实现(例如,如果我决定加密xml文件),毫无疑问会破坏SOLID原则的几个方面。

我有这个想法,我可以创建一个xmlLevelReader类,其唯一目的是读取xml级文件。 然后,该类可以公开可以从上述每个类中的Load()方法调用的方法。

例如,TileLayer类的Load()方法可以调用xmlLevelReader.GetTiles(),它将返回一个IEnumerable<Tile>

你认为这种方法有效吗?
你能预见到任何困难吗?
这种方法过于简单/复杂吗?
任何建设性的批评都欢迎!

谢谢

根据您的评论,我看到您正在使用Tiled Map Editor。 这导致我建议你使用TiledLib。 以下是如何启动和运行导入.tmx文件以便在游戏中使用的简要说明。

内容管道概述

文件 - >内容导入 - >内容处理 - >内容写入 - > .xnb - > ContentRead - >游戏对象

TiledLib

TiledLib只处理上图中的ContentImporter部分。 它本质上处理读取.tmx XML并允许您将数据处理为运行时所需的任何对象。 幸运的是,TiledLib作者也在下载中提供了演示部分。

基本平铺地图处理器演示

  • BasicDemo主游戏项目,包含ContentManager.Load调用。
  • BasicDemoContent项目,其中包含Tiled的.tmx文件
  • 具有ContentProcessor BasicDemoContentPipeline项目
  • TiledLibContentImporter

您真的只需要担心ContentProcessor工作原理,因为TiledLib会为您处理所有导入。 虽然我建议查看不同的类以了解它如何反序列化XML(用于教育目的)。

该示例ContentProcessor在基本演示项目以在MapContent从物体ContentImporter (TiledLib),并输出一个DemoMapContent其序列在构建时对.xnb和反序列化到对象Map对象在运行时。 以下是完全处理后代表地图的类:

[ContentSerializerRuntimeType("BasicDemo.Map, BasicDemo")]
public class DemoMapContent
{
    public int TileWidth;
    public int TileHeight;
    public List<DemoMapLayerContent> Layers = new List<DemoMapLayerContent>();
}

[ContentSerializerRuntimeType("BasicDemo.Layer, BasicDemo")]
public class DemoMapLayerContent
{
    public int Width;
    public int Height;
    public DemoMapTileContent[] Tiles;
}

[ContentSerializerRuntimeType("BasicDemo.Tile, BasicDemo")]
public class DemoMapTileContent
{
    public ExternalReference<Texture2DContent> Texture;
    public Rectangle SourceRectangle;
    public SpriteEffects SpriteEffects;
}
  • Map包含图块宽度,图块高度和MapLayers列表。
  • MapLayer包含宽度,高度和Tiles列表。
  • MapTile包含一个纹理,一个源矩形(tileset中的适当矩形)和可选的精灵效果(我从未使用过任何)。

这个怎么做的

我建议阅读ContentProcessor的注释以了解正在发生的事情,但简而言之,这是基础知识:

  • 加载图块集的纹理数据
  • 从纹理中获取每个图块的源矩形
  • 迭代地图的所有图层
  • 对于每个图层,迭代所有图块
  • 对于每个图块,获取适当的纹理和源矩形
  • 正确地将输入中的所有数据分配给输出

注意事项

只要你坚持基本类型(模糊,我知道),你也不必担心内容管道的ContentWriterContentReader部分。 它将分别在构建和运行时自动序列化和反序列化.xnb文件。 看到我问过这个问题: 这里

此外,您会注意到如果您在Tiled中使用对象图层,则演示不会向您展示如何处理这些对象图层。 TiledLib正确导入它们,您只需要将数据拉出并将其粘贴到适当的类中。 我稍后会尝试编辑这个答案,并举例说明如何做到这一点。

如果您只是想在不操作数据的情况下加载XML,则可以使用内置的XNA Content Serializer。

基本上,您定义了一个映射到您的xml格式的类,然后将XML读入该类的实例。

例如。 在这里,我定义了要加载的类:

SpriteRenderDefinition.cs

我选择了这个,因为它有嵌套类,就像你描述的情况一样。 请注意,它会进入XNA解决方案的ContentDefinitions项目。

现在这里是填充SpriteRenderDefinition内容的xml文件:

Sprite.xml

该XML的格式直接映射到SpriteRenderDefinition的成员名称。

最后,在运行时将XML数据实际加载到实际Object中的代码非常简单:

SpriteRenderDefinition def = GameObjectManager.pInstance.pContentManager.Load<SpriteRenderDefinition>(fileName);

在调用该行之后,您将拥有一个SpriteRenderDefintion对象,其中填充了XML文件的所有内容! 这就是我写的所有代码。 其他一切都内置于XNA中。 如果花一个小时左右的时间来弄清楚它,它真的非常光滑和有用!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM