Answers:
大概您需要保存的只是随机种子,它通常只是一个整数。如果您想使int更加不透明,可以将int编码为base64,但这可能就不需要了。
JSON很好,但是YAML更好。:)http://www.yaml.org/和http://code.google.com/p/yaml-cpp/,这是一种易于使用的实现。
YAML是JSON的超集,它增加了对一些不错功能的支持,最值得注意的是:
如果您想序列化游戏中的所有数据,我建议您将JSON作为文件格式,这就是为什么使用XML更容易并且对多种语言的支持都很好的原因。
我已经将此库用于C ++,并且效果很好。
如果您不受大小的限制并且XML本身受支持(例如,.NET和Flash),那么XML是一个不错的选择,但是如果您想要一种苗条的格式,则可以轻松地创建自己的格式和解析器。我通常使用1个字符,例如。以逗号分隔每个对象。要对字符串进行解码,请对逗号进行分割。现在,每个对象都需要不同的属性,因此请使用不同的字符(例如,半冒号)分隔这些属性,并使用另一个字符将属性名称与属性值分开,例如。结肠。因此,仅通过使用string.split就可以轻松地解码所有内容而无需使用正则表达式。这是一个例子:
id:1;x:5;y:45.2;angle:45,id:28;x:56;y:89;angle:12;health:78
您可以通过将属性名称的字符数减少到1个字符来节省更多空间,例如,h表示健康。例如。
i:1;x:5;y:45.2;a:45,i:28;x:56;y:89;a:12;h:78
与JSON替代方案比较:
{"o":[{"i":1, "x":5, "y":45.2, "a":45}, {"i":28, "x":56, "y":89, "a":12, "h":78}]}
另外,如果您想减小数字的大小,则可以使用全套可打印的UTF16字符对它们进行编码。这个线程启发了我在Stack Overflow上问一个问题,您可以将多少数据打包成一个屏幕字符。如果您不介意使用烤肉,汉字和国际象棋棋子,答案似乎是一个整数超过40,000个值:♔♕♖♗♘♙♚♛♜♝♞♟
为了进一步减小大小,可以使用读/写顺序确定哪个值是哪个值,因此前两个字符代表id,后两个字符代表x位置,后两个字符y,然后是角度,然后是健康值等等。
F5DGP@%&002DFTK#OP1F
可以存储与其他示例相同的所有信息。
瓦片网格可以存储为一个字符串,每个字符代表不同类型的瓦片,例如:
i789pog5h3kl
我可能是指熔岩,9是草等
如果您使用.Net进行编码,那么XML非常容易使用,因为您可以仅用几行就可以将级别类序列化/反序列化为XML,也可以将其反序列化为XML,然后将其全部托管在一个很好的托管类中。
TheMap将是Map类型的变量,您已将所有数据加载到其中。
Dim TheMap As New Map
假设您已经构建了一个Map类,这会将您的地图保存为XML:
Dim Serializer As New System.Xml.Serialization.XmlSerializer(GetType(TheMap))
Dim Strm As New FileStream("c:\Map.xml", FileMode.Create, FileAccess.Write, FileShare.None)
Serializer.Serialize(Strm, TheMap)
Strm.Close()
然后,这会将XML加载回您的地图类中,以再次在代码中使用。
Dim Reader As New StreamReader("map.xml")
Dim Serializer As New System.Xml.Serialization.XmlSerializer(GetType(TheMap))
TheMap = Serializer.Deserialize(Reader)
Reader.Close()
至此,您的XML文件现在已加载到您的类中,以方便使用。
至于您的“级别字符串”问题,前面所说的将很有效,您可以将种子编号用作“级别字符串”。
否则,您可以只预生成所需的许多不同地图,然后将它们全部保存为“ Level String”,然后使用它来拉出适当的地图。
我会使用简单struct
或类似的设备(取决于您的语言)将所有游戏状态存储在一个中央位置。如果要保护设置器/获取器,可以将结构包装在中class
。
如果您愿意,可以使用位域,或者简单地使用按位运算符自己进行位操作。
请注意,在某些语言中,结构填充和打包的规则可能会有些复杂-但是如果您有一个或两个填充字节,则对于您的情况也可能没有太大关系。
您也可以使用#pragma
(#pragma pack(1)
或)或__attribute__
紧密封装结构,从而消除填充。根据您的编译器和目标体系结构,此方法可能有效也可能无效。
请注意,使用位域和压缩实用程序或属性会降低可移植性。在整个硬件体系结构中,结构字段的字节序(字节顺序)也可能发生变化。因此,如果您尝试进行可移植性,则可能要避免这种情况。
(例如,对于吃豆人,该结构可能天真地包含一个地图ID或地图种子,一个吃豆人x和y位置,四个幽灵x和y位置以及一个大的位域,用于显示是否存在32-64个药丸,不论最大值是多少。)
获得结构后,将其传递给xxencode函数:
encode_save( char * outStringBuf, size_t outStringBufSize,
const SaveStruct * inSaveData, size_t inSaveDataSize )
编写此函数有点容易出错。您需要根据需要对字节进行移位和组合,以一次获得6位,然后转换为适当的字符。我个人会尝试查找别人的代码,除非我这样做是为了“有趣”(而且我可能想要一个测试套件)。
永远不要低估struct
正确位置上老派的力量。我们在这里为GBA和DS游戏大量使用了它。
XML适用于任意结构化的文档(元素可以出现在树的不同级别)或外来格式嵌入(例如将svg放在xhtml页面中)。如果您没有这些要求,那是一种效率很低的格式,最好使用csv或json等更简单的格式。