Visual studio 2010 正在构建游戏编辑器,需要加载和保存方面的帮助

Visual studio 2010 正在构建游戏编辑器,需要加载和保存方面的帮助,visual-studio-2010,xml-parsing,xna,save,methodaccessexception,Visual Studio 2010,Xml Parsing,Xna,Save,Methodaccessexception,我和一个小组一起做了一个游戏项目,现在我们遇到了障碍。这个游戏的一个特点是用户可以通过游戏编辑器生成自己的关卡。编辑器将创建一个标高对象,该对象存储标高的长度和宽度以及平铺对象的二维数组。我们已经成功地实现了摄像头系统,可以轻松地编辑一个简单的概念级别,但是成功保存该级别并在以后加载备份的过程是一个很难实现的概念,我希望你们中的一位能够提供一些指导,以实现预期的功能 在当前状态下,当用户按下“S”键时,我们的LevelManager类运行下面的SaveLevel方法: public st

我和一个小组一起做了一个游戏项目,现在我们遇到了障碍。这个游戏的一个特点是用户可以通过游戏编辑器生成自己的关卡。编辑器将创建一个标高对象,该对象存储标高的长度和宽度以及平铺对象的二维数组。我们已经成功地实现了摄像头系统,可以轻松地编辑一个简单的概念级别,但是成功保存该级别并在以后加载备份的过程是一个很难实现的概念,我希望你们中的一位能够提供一些指导,以实现预期的功能

在当前状态下,当用户按下“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>

我有一种隐秘的怀疑,即IntermediateSerializer并没有按照我们所希望的方式工作,但我不确定如何有效地解析和存储数据。我应该在这里使用不同的设置吗?

根据我的经验,100%确保保存和加载基于磁贴的级别的最有效方法是使用BinaryWriter和BinaryReader

不过,我们的层级结构与你们的大不相同;我们有很多层。每个层使用一个平铺集,并由平铺实例组成。平铺保持其位置(矢量2D)和平铺ID(平铺集纹理中平铺的索引)

我们将对象放置在级别中的方式是使用加载时由真实对象替换的平铺集

无论如何,保存和加载数据的一种合适的通用方法是让类拥有一个构造函数,可以将BinaryReader作为参数,以及一个将自身写入BinaryWriter的方法

像这样:

    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);
            }
        }
    }
public Tile(BinaryReader reader)
{
    Position.X = reader.ReadFloat();
    Position.Y = reader.ReadFloat();
    TileId = reader.ReadInt32();
}

public void WriteToStream(BinaryWriter writer)
{
    writer.Write(Position.X);
    writer.Write(Position.Y);
    writer.Write(TileId);
}
如果只有一个类要加载,则可以简单地执行以下操作:

装载:

var tiles = new List<Tile>();
var reader = new BinaryReader(File.Open("level.bin"));

while (reader.BaseStream.Position < reader.BaseStream.Length)
{
    var tile = new Tile(reader);
    tiles.Add(tile);
}
reader.Close();
但是,如果列表包含不同类型的项,则还需要存储该类型。 一种非常通用的方法是插入:

writer.Write(tile.GetType().FullName);
在tile.WriteToStream(writer)之前

然后在加载时,您需要:

var tileType = Type.GetType(reader.ReadString()); //Read the type from the stream
var constructor = tileType.GetConstructor(new [] { typeof(BinaryReader)}); //get a constructor that can use a binaryreader
var tile = constructor.Invoke(new [] { reader }); //use said constructor to create an instance

希望这有帮助。请注意,我是用内存写的,所以很可能会出现语法错误……

谢谢您的回复。实际上,我们使用了DataContractSerializer路由,它工作得很好。事实证明,我们的问题是,VS4.5不再支持IntermediateSerializer类,作为其替代品的DataContract库。一旦我们的xml容量超过10mb,我们就会发现它太慢、太庞大。10mb的xml最终被
writer.Write(tile.GetType().FullName);
var tileType = Type.GetType(reader.ReadString()); //Read the type from the stream
var constructor = tileType.GetConstructor(new [] { typeof(BinaryReader)}); //get a constructor that can use a binaryreader
var tile = constructor.Invoke(new [] { reader }); //use said constructor to create an instance