上节我们说了战斗如何表现,这节我们拆解战斗的实现。
1.模块分类
- 英雄行动控制模块 (负责英雄的行动流程,可以使用行为树)
- 日志模块 (负责不同类型日志的生成)
- 全局信息模块 (负责全局信息的处理,如累计回合数)
- 战斗过程产生的数据保存 (负责保存如英雄a累计造成的伤害,某个技能累计回复血量)
- 事件系统 (负责事件广播与触发)
- 使用端监听后需要注意移除
- 事件监听 (监听不同事件)
- 事件广播 (回合开始事件,攻击事件,死亡事件等),广播时会携带详细数据(如某uid攻击某uid,造成xx伤害)
- 条件检测模块
- 是否有某英雄
- 英雄状态判断
- 效果层数满足某些条件
- 英雄单元模块 (负责英雄数据的存储)
- 属性: 血量,攻击力,护盾,抗性...
- buff:
- 技能拆解
- 一般来说,一个大的技能会有多个效果。所以需要将其拆解成下面操作单元的集合
- 同时还要记录技能释放上下文 (谁对谁释放,释放原因等)
- 数据操作单元Effect (负责各种具体操作的实现,可以绑定在英雄类上)
- 造成伤害
- 更新属性
- 治疗
- 添加中毒
- 添加护盾
- 添加致盲
- .....
- 上面单元会使用事件系统监听事件触发并使用条件检测模块判断是否要执行操作(如回合开始时中毒生效)
- Effect的叠加方式 (Effect为同一类型才执行叠加,同一类型的定义由策划设定)
- 叠加
- 叠加回合
- 叠加伤害
- 覆盖
- 使用最新Effect的值
- 使用最大值
- 独立 (互不影响)
- 叠加
2.数据表配置
数据表配置的本质就是以合理的方式将代码所需要的数据准备好,方便程序加载使用。
如我们有
一个疗养技能攻击对面并治疗己方。
一个毒伤技能攻击对面并添加中毒。
skill表里我们配置
1 疗养1 1,100,xx|2,xx,xx
2 疗养2 1,120,xx|2,xx,xx
3 毒伤 1,100,xx|3,xx,xx
4 毒伤 1,150,xx|4,xx,xx
Effect表里我们配置
1 攻击 图标1 无
2 治疗 图标2 可叠加
3 中毒1 图标3 可叠加
4 中毒2 图标4 不可叠加
以上仅为示例。
目的是为了建立这样一个概念,当我们要创建一个Effect实例时,(甚至推广到新建各种实例时)。Effect实例不变的部分我们从Effect表取
变化的部分通过更上层的表作为参数传入。
同样skill实例不变的部分从skill表取,变化的部分可以从人物表或其他表用不同参数传入。
3.战斗流程
类图依赖大致如下
2.英雄行动流程
对方六个英雄,我方六个英雄,需要一个流程控制来轮流行动。
对于单个英雄的行动如下。
另外不同effect是会监听不同事件的,如中毒effect会监听回合开始事件然后中毒生效。
3.日志生成
日志生成包含两部分,日志数据和日志顺序。
战斗日志的数据只要能完成描述操作,让表现层知道发生了什么即可。
日志的顺序: 添加一个waitId字段用来标记需要等待哪个日志完成。
为了简化等待逻辑,当需要等待多个日志时,如A需要等待BCD的完成时,我们引用WaitMultyLog,让WaitMultyLog等待BCD,然后A等待WaitMultyLog。
示例如下:
使用等待逻辑的好处在于,客户端可以随意设置不同的特效时长,而不用担心前后端不一致。逻辑上也不用考虑弹道特效的速度和命中时机的帧号。