我已经和一个小组一起做一个游戏项目已经有一段时间了,我们遇到了一个障碍。该游戏的特色之一是用户能够通过使用游戏内编辑器生成自己的关卡。编辑器会创建一个 Level 对象,该对象存储关卡的长度和宽度以及 Tile 对象的二维数组。我们已经成功实现了相机系统,并且可以毫无困难地一起编辑一个简单的概念关卡,但是成功保存关卡并稍后重新加载它的过程是一个困难的概念,我希望你们中的一个人可以提供一些指导以降低预期的功能。
在当前状态下,当用户按下“S”键时,我们的 LevelManager 类运行下面的 SaveLevel 方法:
public static void SaveLevel()
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
using (XmlWriter writer = XmlWriter.Create("example.xml", settings))
{
IntermediateSerializer.Serialize(writer, CurrentLevel, null);
}
}
它将我们的关卡 (CurrentLevel) 序列化为项目中的一个 XML 文件(在我们完成这个基本设置后,我们会担心保存到不同的文件。)我运行了程序,创建了一个小地图并保存了它,这是输出在生成的 XML 文件中:
<?xml version="1.0" encoding="utf-8"?>
<XnaContent>
<Asset Type="LevelEditorPrototype.Level">
<TileGrid>
<Item>
<Item Type="LevelEditorPrototype.TileFloor">
<X>0</X>
<Y>0</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FFFFFFFF</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileBlock">
<X>0</X>
<Y>32</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FF0000FF</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileVoid">
<X>0</X>
<Y>64</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FFFF0000</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileFloor">
<X>0</X>
<Y>96</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FFFFFFFF</Tint>
</Item>
</Item>
<Item>
<Item Type="LevelEditorPrototype.TileVoid">
<X>32</X>
<Y>0</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FFFF0000</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileFloor">
<X>32</X>
<Y>32</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FFFFFFFF</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileBlock">
<X>32</X>
<Y>64</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FF0000FF</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileVoid">
<X>32</X>
<Y>96</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FFFF0000</Tint>
</Item>
</Item>
<Item>
<Item Type="LevelEditorPrototype.TileBlock">
<X>64</X>
<Y>0</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FF0000FF</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileVoid">
<X>64</X>
<Y>32</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FFFF0000</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileFloor">
<X>64</X>
<Y>64</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FFFFFFFF</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileBlock">
<X>64</X>
<Y>96</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FF0000FF</Tint>
</Item>
</Item>
<Item>
<Item Type="LevelEditorPrototype.TileFloor">
<X>96</X>
<Y>0</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FFFFFFFF</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileBlock">
<X>96</X>
<Y>32</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FF0000FF</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileVoid">
<X>96</X>
<Y>64</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FFFF0000</Tint>
</Item>
<Item Type="LevelEditorPrototype.TileFloor">
<X>96</X>
<Y>96</Y>
<Width>32</Width>
<Height>32</Height>
<Origin>0 0</Origin>
<Depth>0</Depth>
<Tint>FFFFFFFF</Tint>
</Item>
</Item>
</TileGrid>
</Asset>
</XnaContent>
所以至少我们确实有关于在关卡中生成的图块的数据信息,所以这就是一些东西。我们希望我们的用户也能够在运行时加载保存的关卡,因此我们映射了“L”键来加载保存的 XML 文件,这就是问题出现的地方。我们的阅读看起来像这样:
public static void LoadLevel()
{
using (FileStream stream = new FileStream("example.xml", FileMode.Open))
{
using (XmlReader reader = XmlReader.Create(stream))
{
currentLevel = IntermediateSerializer.Deserialize<Level>(reader, null);
}
}
}
当我们尝试测试该功能时,我们会收到以下错误:
System.MethodAccessException was unhandled
HResult=-2146233072
Message=Attempt by method 'DynamicClass.ReflectionEmitUtils(System.Object, System.Object)' to access method 'DynamicClass.ReflectionEmitUtils(System.Object, System.Object)' failed.
我暗中怀疑 IntermediateSerializer 并不能完全按照我们希望的方式工作,但我不确定如何有效地解析和存储数据。我应该在这里使用不同的设置吗?