2

我正在用程序生成的关卡在 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

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

我想尝试类似这篇文章中显示的原始二进制格式化程序来提高序列化/反序列化性能

我可以保存与事物的所有位置/配置相对应的整数、浮点数和布尔值,并在加载关卡时重新实例化所有内容(只需一秒钟)

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

可以为每个房间中的每种不同类型的事物创建一个新流,但这会导致加载不同的文件(我认为)有没有办法用某种层次结构分离原始二进制流?IE。将它分成与不同房间和不同物品清单有关的不同部分?


更新

好的,让我失望的一个想法是,有问题我引用OP 将“手动序列化”称为“原始二进制序列化”,我找不到任何信息。

4

1 回答 1

1

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

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

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

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

  • 设置第二种方法更接近 .NET - Settings中已经内置的概念 。看了一下,貌似这个Globals类其实是一个settings配置的自定义变种

于 2013-05-15T13:57:09.683 回答