王者荣耀复刻项目 背包系统篇
设计
基本实现
数据库中只存储物品id、物品数量;客户端本地二进制式存储cfg,来显示物品详情;服务端本地二进制式存储cfg,来确定物品效果。
整体流程如下:
- 客户端登录时,获取到背包信息(物品id、物品数量)。
- 客户端打开背包时,根据内存中的背包信息 + 本地cfg,来展示物品。
- 客户端使用物品时,发送请求到服务端并让服务端在数据库验证数量。
- 如果数量不足,则失败;
- 如果数量足够,则根据服务端本地cfg来计算出账号收益,更新数据库后返回结果给客户端。
- 客户端获得返回结果,刷新内存数据。
优化
- 虚拟列表
- 对象池
- 异步加载
基础实现
Scroller View
Viewport,遮罩,决定能看到的内容。(视野)
Content,真实内容。(履带)
设置格子锚点到左上角。
数据类型
主要分为3块。
- BagMgr,用来获取道具信息。
- BagItem,背包格子类。
- BagPanel,背包页面逻辑。
显式获取
要计算出 起始显示的格子索引值、结束显示的格子索引值:
=====================================================================
可视范围的起始位置Y / 一个格子的高 = 可视范围中,起始显示的是哪一行(向下取整),
可视范围中,起始显示的是哪一行 * 一行有多少格子 = 起始显示的格子索引值,
用同样的方法,根据可视范围的结束位置Y也可以计算出结束显示的格子索引值。
=====================================================================
将上面计算出来的索引值取下来记录,放到 Dictionary<int索引,格子对象> 里。这些就是画面正要显示的格子们。
格子位置确定
物品位置确定。通过简单计算获得:
1 | // index是物品下标, oneRowColumns是一行几个, childWidth是格子宽度, paddingWidth是格子横向间隔 |
未显示就不加载的虚拟列表
显式获取 + 格子位置确定 就可以实现。
优化
在上面未显示就不加载的虚拟列表的实现基础上,进行优化。
对象池
对物品进行对象池管理,加载从池中取,销毁就返回池。
去掉加载过、现在不显示的物品
在update中调用刷新物品方法,
计算显示下标 => 根据本次下标范围与上次记录下来的下标范围,算出哪些不再显示 => 把他们放回对象池。
异步加载
将异步加载的过程放入协程中执行。
简单地说就是一帧不加载完物品,至少是2帧,异步加载成功后触发回调。
1 | //异步加载协程 |
解决方案
demo已上传github。
项目使用
实际项目使用更为复杂。这里只展示一下实现了什么。
- 物品数量数据库存储:使用字符串标记,规则
物品id:数量
类似于1:2#3:1#5:10
。 - 物品选择状态显示:简单业务实现。
- 服务端物品检测:数据处理使用服务端本地cfg读表,避免客户端作弊。
- 二进制读表:luban 二进制读表,在加载流程中读取物品配置。
- 优化:虚拟列表 + 对象池。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 CodingCodingK Blog!