.net序列化:如何在维护哪个东西的同时使用原始二进制写入器

时间:2013-05-15 13:46:04

标签: c# .net serialization xna

我正在使用程序生成的级别在XNA中制作一个roguelike游戏。

生成一个全新的关卡需要大约一秒钟,但序列化大约需要4秒钟,用我当前的方法反序列化大约需要8秒钟。文件也很庞大(大约10兆,取决于级别有多大)

我像这样序列化。

private void SerializeLevel()
{
    string name = Globals.CurrentLevel.LvLSaveString;

    using (Stream stream = new FileStream("SAVES\\"+name+".lvl", FileMode.Create, FileAccess.Write, FileShare.None))
    {
        formatter.Serialize(stream, Globals.CurrentLevel);
        stream.Close();
    }
}

我的游戏引擎架构基本上是一堆嵌套列表,可能会......

Level\Room\Interior\Interiorthing\sprite

此层次结构对于维护游戏/性能非常重要。例如,通常只考虑当前房间中的内容进行更新和绘制。

我想尝试this post中显示的原始二进制格式化程序,以提高序列化/反序列化性能

我可以保存对应于事物/配置的所有位置的整数和浮点数和bool,并在我加载一个级别(只需要一秒钟)时重新实例化所有内容

我的问题是如何使用这个原始二进制序列化程序,同时还要维护哪个对象是哪个,它是什么类型以及它所在的嵌套列表。 在引用的示例中,OP只是序列化一个巨大的整数列表,每个第三个都被视为新坐标的开始。

可能为每个房间中的每种不同类型的事物都有一个新的流但是会导致不同文件的加载(我认为)有没有办法将原始二进制流与某些文件隔离开来层次结构? IE浏览器。将它分成不同的部分,不同的房间和不同的事物清单?


更新

好吧,一个让我失望的是,在question I reference OP中,“手动序列化”是指“原始二进制序列化”,我无法找到任何信息。

1 个答案:

答案 0 :(得分:1)

如果要独立序列化Globals的每个成员,并在反序列化时手动更新成员值,则需要知道在反序列化时当前正在处理的成员。我可以建议你这些:

  • 按相同顺序处理项目。示例中的代码会将二进制数据放入流中几乎无法提取的内容,除非您按照顺序对成员进行反序列化序列化。如果添加新项目,这将是维护地狱,并且不是代码清晰度,可维护性和向后兼容性的良好解决方案。

  • 使用字典。根据评论,Globals似乎是一个静态类,因此它本身不可序列化。序列化时,将Globals类的所有成员放在字典中,并对其进行序列化。反序列化后,您将知道您有一个字典(而不是随机乱七八糟的对象)。然后从反序列化的字典中恢复Globals对象

  • 使用自定义类。使用所有设置创建一个类(更好的方法)。使用类的单个静态实例来访问设置。您可以序列化和反序列化该类

  • 设置即可。第二种方法更接近.NET中已经内置的概念 - Settings。看一看,似乎Globals类实际上是设置配置的自定义变体