我在XNA中创建基于磁贴的游戏,并将从xml文件加载级别信息。我没有加载xml数据的问题,但我想反馈我正在考虑用于读取xml文件的方法。
代码具有类层次结构,以便:
Level类包含:
- TileLayers的集合
- Tilesets的集合
TileLayer类包含
- Tiles的集合
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>
你认为这种方法有用吗? 你能预见到任何困难吗? 这种方法过于简单/复杂吗? 任何建设性的批评都欢迎!
由于
答案 0 :(得分:2)
根据您的评论,我看到您正在使用Tiled Map Editor。这导致我建议你使用TiledLib。以下是如何启动和运行导入.tmx文件以供游戏使用的简要说明。
档案 - &gt;内容导入 - &gt;内容流程 - &gt;内容写 - &gt; .xnb - &gt; ContentRead - &gt;游戏对象
TiledLib仅处理上图中的ContentImporter
部分。它本质上处理读取.tmx XML并允许您将数据处理为运行时所需的任何对象。幸运的是,TiledLib作者也在下载中提供了演示部分。
BasicDemo
包含ContentManager.Load调用的主游戏项目。BasicDemoContent
项目,其中包含来自Tiled的.tmx文件BasicDemoContentPipeline
项目,其中包含ContentProcessor
TiledLib
,其中包含ContentImporter
您只需要担心ContentProcessor
的工作原理,因为TiledLib会为您处理所有导入。虽然我建议查看不同的类以了解它如何反序列化XML(用于教育目的)。
Basic Demo项目中的示例ContentProcessor
从MapContent
(TiledLib)中获取ContentImporter
对象,并输出一个DemoMapContent
对象,该对象被序列化为.xnb at构建时间并在运行时反序列化为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
的评论以了解正在发生的事情,但简而言之,这是基础知识:
只要您坚持基本类型(模糊,我知道),您也不必担心内容管道的ContentWriter
和ContentReader
部分。它将分别在构建和运行时自动序列化和反序列化.xnb文件。查看我问过的一个问题:here。
另外,您会注意到,如果您在Tiled中使用对象图层,则演示不会向您展示如何处理这些对象图层。 TiledLib正确导入它们,您只需要将数据拉出并将其粘贴到适当的类中。我稍后会尝试编辑这个答案,并举例说明如何做到这一点。
答案 1 :(得分:1)
如果您只是想在不操纵数据的情况下加载XML,则可以使用内置的XNA Content Serializer。
基本上,您定义了一个映射到xml格式的类,然后将XML读入该类的实例。
例如。在这里,我定义了要加载的类:
我选择了这个,因为它有嵌套类,就像你描述的情况一样。请注意,它会进入XNA解决方案的ContentDefinitions项目。
现在这里是填充SpriteRenderDefinition内容的xml文件:
该XML的格式直接映射到SpriteRenderDefinition的成员名称。
最后,在运行时将XML数据实际加载到实际Object中的代码非常简单:
SpriteRenderDefinition def = GameObjectManager.pInstance.pContentManager.Load<SpriteRenderDefinition>(fileName);
在调用该行之后,您将拥有一个SpriteRenderDefintion对象,其中填充了XML文件的所有内容!这就是我写的所有代码。其他一切都内置于XNA中。如果你花一个小时左右的时间来弄清楚它,它真的很光滑和有用!