BlockOS开发日志(六)区块加载
抱歉,这段时间没空写实现的总结型日志了。实现相关的文章后面有空的时候再来补。
对于加载、卸载的需求
只有当玩家的区块坐标出现变化时,才会触发区块加、卸载。因此应该需要一个区块管理器,每次更新检查玩家的区块坐标,然后在变动时,计算出“需要激活的区块”列表。
接着客户端需要让“需要激活的区块”列表与“当前激活的区块”列表取补集,这个补集即需要加载的新区块;让“当前激活的区块”列表与“需要激活的区块”列表取补集,这个补集即需要卸载的旧区块。
对于需要加载的新区块,应该把它们做成请求列表然后发给服务器。对于要卸载的旧区块,应该可以直接抛弃。
最后,需要一个重传机制。每隔一段时间,就让“需要激活的区块”列表与“当前激活的区块”列表取一次补集,只要补集不为空,就再次发送这个补集的请求列表。
相对独立地,区块管理器应该监听“区块加载”事件,如果事件中的新区块在“需要激活的区块”列表内,那么就取出区块信息,然后让一个空闲的区块对象使用这个区块信息进行渲染。
需求分析
先看一下整个过程涉及到了哪几个实体。首先区块管理器是肯定的。然后是区块管理器管理的区块对象。最后是一个用于和服务器通信的代理。这个通信代理可以改造成一个接口,有一个RequestChunks()方法,用于提交加载区块请求,一个OnChunkLoad委托,用于分发加载事件。排列一下,这块也就三个实体:
区块管理器 ChunkManager
区块对象 Chunk
通信代理 IChunkStorage
为了实现不频繁创建、销毁区块对象,需要为区块管理器设计两个容器。一个是“激活的区块”列表。一个是“未激活的区块”列表,旧区块被卸载时,其区块对象就会被放入这个列表,它只要能存取就行,就做成队列吧。
然后区块管理器需要一个更新方法,在这个方法以玩家当前位置为参数。为了判断玩家的区块坐标出现了“变动”,因此区块管理器需要缓存玩家上次的区块坐标,如果不同,才触发计算“需要加载的区块”列表的过程。这个过程中计算出两个补集。当这两个补集存储的内容不为空时,就会做出相应的请求、回收操作。
所以区块管理器需要哪些字段呢?应该需要四个:
用于存储“需要加载的区块”集合与“当前加载的区块”集合之间补集的队列requestedChunks
用于存储“当前加载的区块”集合与“需要加载的区块”集合之间补集的队列garbageChunks
用于存储“当前加载的区块”的字典chunks
用于存储被回收的区块的队列inactivatedChunks
好像轮廓已经很清晰了。那么就开干吧。