什么是成就
成就系统可以理解为对某个角色成长过程重大事件的记录;玩家通过查看成就跟踪角色涉及的重大事件。
成就的策划模版数据
ID, 这个成就的唯一标识;
Name, 命名;
EventCategroy, 完成的事件对应的类型,类型是对各种事件大一个范围的分类;
EventCategroy2, 实际需求中可能有多种类型;
EventID1, 完成的事件ID,事件是指游戏中自定义各种事件,比如升级事件、完成多少任务事件等;
EventValue1, 上面的事件ID对应的值, 如升到20级,完成了1000次任务等;
。。。
EventIDN
EventValueN, 有些成就要完成多个事件才能完成;
其他各种限制参数,比如成就次数是否可累积等。
成就初步实现方法
1. 成就模版管理
将上面的模版生成一个简单list。
2. 判断成就完成的触发点
游戏过程中,存在很多地方会触发判断成就完成逻辑,比如,完成某个任务之后、升级之后、从某个副本出来之后等等。
3. 记录和成就相关的数据
游戏过程中,将成就相关的数据记录下来;如果其他模块已经记录的,成就模块无须记录。这些记录的数据供4使用。
4. 确定哪些成就完成
当某个模块触发了判断成就完成的逻辑时,会传入事件集合给成就模块。
成就模块拿这些事件ID&Value和1中list比较,事件满足模版要求,说明这个成就就完成了。
性能优化
如果一个游戏成就数目50个以内,上面的实现方法性能上是可接受的。成就如果再多一些,有必要做优化。下面介绍另外一种处理时间和成就个数不成线关系的方法,效率是O(1)。
1. 生成模版时要做一些额外的小动作
生成 EventCategory + EventID->AchivementID 的一个映射表, EventCategory, EventID做为组合key。
table1:
EventCategory1 EventID1 -> AchievementID1, AchievementID2
EventCategory2 EventID2 -> AchievementID2, AchievementID3
以成就ID为key,生成一个成就hash表,根据成就ID可以得到对应成就的内容, 并且EventCategory与EventID要顺序。
table2:
AchievementID1 -> EventCategory1 EventID1 EventValue1 EventCategory2 EventID2 EventValue2
上面两个映射表在系统初始化时生成1次。
2. 触发时处理
触发时,某个模块会传进来事件集合,根据table1, 得到所有事件所对应的成就IDs,最后形成类似下面一个以成就ID为key的临时表:
table3:
AchievementID1 -> EventCategory1 EventID1 EventValue1, ........
AchievementIDn -> ..........
注意,EventCategory&EventID排序规则和table2相同。
生成上面的table3时, 我们还要记录哪些成就须要去判断是否完成,这个非常关键!所以我还要弄个表保存这些成就IDs。
table4:
1 2 3 9 2 1
table4中有重复的ID,想个效率是O(1)的办法避免他重复。
最后,先拿table4中的各个成就ID,从table3定位到对应的触发事件集合,用这个集合和table2比较一下,就知道哪些成就完成了。
经过优化,策划弄个10个或10000个成就模版,成就模块运行的效率是一样的。有兴趣的同学可以体会一下。