使用LitJson进行序列化和反序列化
好久不见。
这是第31篇与游戏开发有关的文章。
| 写在最前
最近在写小玩具的时候,遇到了需要将游戏记录到本地、并从本地读取的情况,如:保存游戏战斗录像或是存储、读取游戏存档。有多种方法可以实现这个需求,在这里我使用的是序列化成Json的方法;因为它够简单,结构清晰且可读性强,很方便我们对保存的内容进行直观查看。
| 关于LitJson
Json的书写格式就不再介绍了,网络上也有很多第三方库可以帮助我们快速生成和解析Json文件,在此我使用的是LitJson,它比较常用,而且十分易用。
LitJson使用简单,通常我们直接使用JsonMapper就可以进行Json的序列化和反序列化了。
但是本文记录的是使用JsonWriter和JsonReader进行序列化和反序列化的过程。
之所以没有使用更简单易用的JsonMapper,而使用LitJson中偏基础些的Reader和Writer,主要是因为:
1、对于一些需要二次处理的内容,JsonWriter和JsonReader用起来更灵活些;
2、洋气。
| 关于JsonWriter和JsonReader
· JsonWriter
JsonWriter像是模仿手写Json,通过WriteArrayStart、WriteArrayEnd和WriteObjectStart、WriteObjectEnd来控制当前所写的是数组或是对象;再通过WritePropertyName和Write来写键值对,非常容易理解。
· JsonReader
可以通过输出JsonReader的读入信息,来快速了解它的工作方式。
某Json的读入打印
JsonReader的工作方式可以简单理解为“读到什么告诉你什么”。
尽管JsonWriter和JsonReader非常容易使用,但在实际运用中,所面对的数据结构通常都较为复杂。
本文记录的是在处理相对复杂情况下的一些心得。
我们的目标是尝试序列化和反序列化一场SLG战斗(battleField),这场战斗仅包含战斗地图(battleMap)和参战单位(battleUnits)两部分。
一场粗糙的战斗
| 创建战斗(战场)
序列化战场的前提是先要真正的创建一场战斗。
按照示意图的流程,用代码轻松组织起一场战斗吧。
创建战斗
| 序列化战斗
序列化战斗与创建战斗的套路一致,可简单表示为:序列化战斗 = 序列化地图 + 序列化参战单位。
为了偷懒,我们为JsonWriter增加一些常用的扩展。
准备一些方便使用的函数
逐级序列化战斗
战斗序列化完成,让我们将Json导出,看一下结构。
战场json文件
| 反序列化战斗
反序列化较序列化而言要麻烦一些,原因在于,对象和数组比简单的键值组合要复杂些;因为Reader的读取特点是,你需要想一些办法来记录当前读到的对象、数组都包含什么,以及它们的嵌套关系。
但当你把每一个对象、数组都清晰的提取出来后,问题就变成了”我读到的这一个对象、数组或键值对,应该交给谁来处理,并变成什么?“。
为了让结构清晰,我们让各单位只做自己负责的事情,比如:战场battleField反序列化json数据时,当读取到了名为battleMap的json对象时,就交给battleMap自己处理,至于这个对象里还嵌套了别的东西(如:包含特殊格子索引的数组),或还想做特殊的处理逻辑(如:标记一些格子为特殊),都交给battleMap类的反序列化接口去解决。
同样,为了偷懒,我们也为反序列化增加一些扩展。
准备一些方便使用的函数
部分逐级反序列化流程
| 验证反序列化
一个相对简单的方法来验证反序列化,是将反序列化生成的战斗,再重新序列化成新的Json文件,再与反序列化前读取的Json文件对比,看是否完全一致。
通过对比文件检验反序列化是否出现了错误
以上就是使用JsonWriter和JsonReader进行序列化及反序列化的一些简单体会。
对了,如果使用JsonMapper来做同样的事情会是什么样呢?
仅用两行代码就搞定了:
序列化
JsonMapper.ToJson(battleField);
反序列化
JsonMapper.ToObject<BattleField>(fieldData);
十分的方便!
... 图源网络
| 写在最后
感觉好几年没更新了,都快忘了自己在维护一个公众号的事儿了...水一篇先,惭愧。
将Demo工程的Github地址奉上。
https://github.com/elsong823/SerializeHelperDemo
其实,LitJson仅是一个工具而已,本文并不是想介绍LitJson的接口都有什么作用及如何使用(也根本没这么做)。
我更想表达的东西是:无论一件事情有多复杂,我们总能找到方法去拆解它,用相似的结构去处理、分解它。最终就会发现,我们把它弄得更复杂了,可能这就是程序的魅力吧。
非常感谢您能读到这里,下回见。
我的公众号 偶尔学学Unity 会特别不定期更新与游戏开发可能有关的文章,欢迎关注,谢谢。