本文最后更新于12 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
1. 核心设计架构
项目将技能拆分为三个核心层次,实现了逻辑与数据的完全分离:
- 数据层 (Resources):使用
SkillData(skill_data.gd) 定义技能属性(耗蓝、目标类型),通过SkillEffectData数组定义具体效果。 - 逻辑层 (Effects):每个效果都是一个独立的资源类(如
DamageEffectData),负责具体的数值计算和逻辑执行。 - 系统层 (Autoload):
SkillSystem(skill_system.gd) 作为全局单例,负责验证施法条件、消耗资源并调度效果执行。
2. 各类技能的实现方式
攻击类技能 (Attack)
- 实现类:
DamageEffectData(damage_effect_data.gd) - 逻辑:
- 公式计算:
基础伤害 + 攻击者魔法攻击 * 系数 - 目标魔法防御 * 系数。 - 元素克制:调用
ElementTypes计算元素相克系数(如火克草),影响最终伤害。 - 随机波动:加入
0.9 ~ 1.1的随机浮动。 - 反馈:调用
_request_visual_effect触发受击动画和伤害飘字。
- 公式计算:
治疗类技能 (Heal)
- 实现类:
HealEffectData(heal_effect_data.gd) - 逻辑:基于施法者的魔法攻击力计算治疗量,调用目标的
heal()方法恢复生命值,并显示绿色回复数字。
防御类技能 (Defense)
- 实现方式:通常表现为一个主动技能,施放后为自己施加一个“防御”状态(Status)。
- 设计思路:在
defend.tres状态中,通过attribute_modifiers临时提升DefensePower属性,或者通过trigger_on_events监听on_damage_taken事件来按比例减免伤害。
控制类技能 (Control)
- 核心机制:行动限制标签 (Action Restrictions)。
- 实现逻辑:
ApplyStatusEffectData将一个带有限制条件的状态(如“眩晕”)附加给目标。- 在
SkillStatusData(skill_status_data.gd) 中定义restricted_action_categories。 - 眩晕 (Stun):限制
any_action。 - 沉默 (Silence):限制
magic_skill。 - 角色组件在执行动作前会检查
can_perform_action(),如果当前状态包含限制标签,则动作被拦截。
触发类技能 (Trigger)
- 实现机制:观察者模式 + 游戏事件系统。
- 逻辑:
- 状态资源定义
trigger_on_events(如on_damage_taken)和trigger_effects。 - 当角色受到伤害时,
CharacterCombatComponent调用SkillSystem.trigger_game_event。 SkillSystem遍历角色身上的所有状态,匹配事件类型并自动执行预设的触发效果(如“反击”或“受击回血”)。
- 状态资源定义
3. 各脚本间的相互调用关系
技能执行的完整生命周期如下:
- 指令发起:
BattleManager接收玩家指令,调用Character.execute_action()。 - 组件分发:
Character转发给CharacterCombatComponent。如果是技能,则调用SkillSystem.attempt_execute_skill()。 - 系统验证与消耗:
SkillSystem检查角色SkillComponent中的 MP 是否足够,验证目标合法性。 - 效果迭代:
SkillSystem遍历SkillData中的effects数组,依次调用每个SkillEffectData.process_effect()。 - 目标交互:
DamageEffectData-> 调用目标take_damage()。HealEffectData-> 调用目标heal()。ApplyStatusEffectData-> 调用目标apply_skill_status()。
- 状态与事件响应:
CharacterSkillComponent维护状态列表。如果受到伤害,触发on_damage_taken事件,回到SkillSystem检查并执行触发类效果。
4. 设计亮点总结
- 高复用性:一个“火球术”可以是
DamageEffectData(伤害)+ApplyStatusEffectData(附加燃烧状态)的组合,无需为每个技能写新脚本。 - 属性透明:所有的属性加成(Buff)都通过
SkillAttributeModifier统一管理,自动处理层数堆叠和持续时间。 - 解耦视觉:通过
_request_visual_effect字符串请求视觉效果,使得技能逻辑不依赖具体的动画资源,方便后期更换特效。
条件触发技能:比如目标生命值低于50%额外造成伤害
。。
