# 技能执行机制 **本文档中引用的文件** - [HeroSkills.ts](file://assets\script\game\hero\HeroSkills.ts) - *重构技能数据组件* - [Skill.ts](file://assets\script\game\skill\Skill.ts) - *新增技能实体与组件结构* - [AtkConCom.ts](file://assets\script\game\skill\AtkConCom.ts) - *优化技能碰撞与方向处理* - [HeroAtk.ts](file://assets\script\game\hero\HeroAtk.ts) - *重构伤害计算系统* - [SkillSet.ts](file://assets\script\game/common/config/SkillSet.ts) - *重构技能配置表* - [SkillView.ts](file://assets\script\game\skill\SkillView.ts) - *更新目标选择与范围伤害逻辑* ## 更新摘要 **变更内容** - 根据最新重构提交更新技能执行机制文档 - 新增技能数据组件(SDataCom)和移动组件(SMoveDataComp)说明 - 重构技能伤害计算流程,增加命中检测与伤害类型处理 - 更新技能碰撞检测逻辑,支持范围伤害与目标数量限制 - 优化技能加载与方向处理机制 - 支持前后摇动画配置 - 更新核心组件架构图以反映ECS实体结构变化 ## 目录 1. [概述](#概述) 2. [核心组件架构](#核心组件架构) 3. [技能冷却检测机制](#技能冷却检测机制) 4. [技能施放流程](#技能施放流程) 5. [多段连发技能机制](#多段连发技能机制) 6. [目标选择策略](#目标选择策略) 7. [异常处理与资源清理](#异常处理与资源清理) 8. [性能优化考虑](#性能优化考虑) 9. [最佳实践总结](#最佳实践总结) ## 概述 SkillConComp类是游戏技能控制系统的核心组件,负责管理英雄的技能冷却、自动施放条件判断以及技能执行流程。该系统采用ECS架构模式,结合定时器机制和节点有效性检查,实现了复杂的技能逻辑控制。近期重构优化了伤害计算与技能释放逻辑,增加了命中检测和伤害类型处理,并支持范围伤害和数量限制。 ## 核心组件架构 ```mermaid classDiagram class Skill { +addComponents() void +load() void +SDataCom : SDataCom +SMoveCom : SMoveDataComp +SView : SkillView } class SDataCom { +group : number +hit_count : number +Attrs : any +caster : HeroViewComp } class SMoveDataComp { +startPos : Vec3 +targetPos : Vec3 +s_uuid : number +scale : number +rePos() void } class SkillView { +s_uuid : number +group : number +SConf : SkillConfig +sData : SDataCom +anim : Animation +start() void +update() void +onBeginContact() void +do_linear() void +do_bezier() void +do_fixedStart() void +apply_damage() void } class HeroSkillsComp { +skills : Record +initSkills() void +addSkill() void +getSkill() void +canCast() void } Skill --> SDataCom : "包含" Skill --> SMoveDataComp : "包含" Skill --> SkillView : "包含" SkillView --> SDataCom : "引用" SkillView --> SMoveDataComp : "引用" HeroSkillsComp --> SkillSlot : "管理" ``` **图表来源** - [Skill.ts](file://assets\script\game\skill\Skill.ts#L1-L39) - [SDataCom.ts](file://assets\script\game\skill\SDataCom.ts#L1-L20) - [SMoveComp.ts](file://assets\script\game\skill\SMoveComp.ts#L1-L25) - [SkillView.ts](file://assets\script\game\skill\SkillView.ts#L1-L200) - [HeroSkills.ts](file://assets\script\game\hero\HeroSkills.ts#L1-L91) **章节来源** - [Skill.ts](file://assets\script\game\skill\Skill.ts#L1-L74) - [HeroSkills.ts](file://assets\script\game\hero\HeroSkills.ts#L1-L91) ## 技能冷却检测机制 ### update循环中的冷却检测 SkillConComp的update方法实现了精确的技能冷却管理系统: ```mermaid flowchart TD Start([update循环开始]) --> CheckMission{"检查游戏状态
smc.mission.play && !pause"} CheckMission --> |否| End([结束]) CheckMission --> |是| CheckStatus{"检查状态
!isStun && !isFrost"} CheckStatus --> |否| End CheckStatus --> |是| LoopSkills["遍历技能列表"] LoopSkills --> AddCD["累积冷却时间
skills[i].cd += dt"] AddCD --> CheckCD{"冷却完成
cd > cd_max?"} CheckCD --> |否| NextSkill["下一技能"] CheckCD --> |是| CheckMP{"检查魔法值
mp >= cost?"} CheckMP --> |否| NextSkill CheckMP --> |是| CheckType{"技能类型
SType.damage?"} CheckType --> |否| NextSkill CheckType --> |是| CheckAttack{"正在攻击
is_atking?"} CheckAttack --> |否| NextSkill CheckAttack --> |是| CastSkill["调用castSkill"] CastSkill --> ResetCD["重置冷却
skills[i].cd = 0"] ResetCD --> ConsumeMP["消耗魔法值
mp -= cost"] ConsumeMP --> NextSkill NextSkill --> MoreSkills{"还有技能?"} MoreSkills --> |是| LoopSkills MoreSkills --> |否| End ``` **图表来源** - [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L35-L52) ### 冷却检测的关键要素 1. **时间累积机制**:每个技能的冷却时间通过`skills[i].cd += dt`逐步累积 2. **阈值判断**:当冷却时间超过最大冷却时间`cd_max`时触发 3. **资源检查**:确保魔法值充足`this.HeroView.mp >= skills[i].cost` 4. **状态验证**:排除眩晕和冰冻状态影响 5. **攻击状态检查**:只有在攻击状态下才允许施放伤害技能 **章节来源** - [HeroSkills.ts](file://assets\script\game\hero\HeroSkills.ts#L50-L55) ## 技能施放流程 ### castSkill与doSkill方法调用链 ```mermaid sequenceDiagram participant Player as "玩家输入/自动触发" participant SkillCon as "SkillConComp" participant HeroView as "HeroViewComp" participant SkillEnt as "Skill" participant ECS as "ECS系统" Player->>SkillCon : castSkill(config) SkillCon->>SkillCon : check_wfuny() SkillCon->>SkillCon : doSkill(config, wfuny, dmg) Note over SkillCon : 节点有效性检查 SkillCon->>SkillCon : 检查节点有效性 alt 目标组为Self SkillCon->>SkillCon : targets = [this.node.position] else 目标组为Enemy SkillCon->>SkillCon : selectTargets(config.t_num) end SkillCon->>HeroView : playSkillEffect(config.uuid) HeroView->>HeroView : 播放技能特效 SkillCon->>ECS : ecs.getEntity(Skill) SkillCon->>SkillCon : 创建setTimeout定时器 Note over SkillCon : 延迟执行300ms SkillCon->>SkillCon : 定时器回调函数 SkillCon->>SkillCon : 再次检查节点有效性 SkillCon->>SkillEnt : sEnt.load(...) SkillCon->>SkillEnt : load方法 SkillEnt->>SkillEnt : 加载技能预制体 SkillEnt->>SkillEnt : 设置节点属性 SkillEnt->>SkillEnt : 添加SkillView组件 alt wfuny机制启用 SkillCon->>SkillCon : scheduleOnce(doSkill, 0.1) end Note over SkillCon : 保存定时器ID SkillCon->>SkillCon : this._timers[`skill_${config.uuid}`] = timerId ``` **图表来源** - [Skill.ts](file://assets\script\game\skill\Skill.ts#L35-L74) - [SkillView.ts](file://assets\script\game\skill\SkillView.ts#L27-L61) ### 节点有效性检查机制 系统实现了双重节点有效性检查: 1. **初始检查**:在`doSkill`方法开头进行基础节点有效性验证 2. **延迟检查**:在定时器回调函数中再次确认节点状态 这种设计确保了即使在技能施放过程中节点被销毁,也不会导致错误操作。 **章节来源** - [Skill.ts](file://assets\script\game\skill\Skill.ts#L35-L74) ## 多段连发技能机制 ### wfuny机制实现原理 wfuny机制是一种基于概率的技能连发系统: ```mermaid flowchart TD Start([doSkill开始]) --> CheckWfuny{"检查wfuny
check_wfuny()"} CheckWfuny --> |false| NormalSkill["正常技能执行"] CheckWfuny --> |true| ScheduleOnce["scheduleOnce(doSkill, 0.1)"] ScheduleOnce --> RecursiveCall["递归调用doSkill
is_wfuny=false"] RecursiveCall --> CheckWfuny2{"再次检查wfuny"} CheckWfuny2 --> |false| FinalExecution["最终技能执行"] CheckWfuny2 --> |true| ContinueRecursion["继续递归"] ContinueRecursion --> ScheduleOnce NormalSkill --> SaveTimer["保存定时器ID"] FinalExecution --> SaveTimer SaveTimer --> End([结束]) ``` **图表来源** - [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L82-L87) ### wfuny概率计算 ```typescript check_wfuny() { let random = Math.random() * 100 if (random < this.HeroView.Attrs[Attrs.WFUNY]) { return true } return false } ``` 该方法: 1. 生成0-100之间的随机数 2. 与英雄的WFUNY属性值比较 3. 当随机数小于WFUNY值时返回true,触发连发 **章节来源** - [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L89-L95) ## 目标选择策略 ### selectTargets方法实现 ```mermaid flowchart TD Start([selectTargets开始]) --> GetEntities["获取目标实体
check_target()"] GetEntities --> CheckEmpty{"实体列表为空?"} CheckEmpty --> |是| DefaultPos["返回默认位置
t_num个相同坐标"] DefaultPos --> Return([返回目标坐标数组]) CheckEmpty --> |否| FindFront["找到最前排目标
get_front(entities)"] FindFront --> PushFront["targets.push(frontPos)"] PushFront --> LoopOthers["循环处理剩余目标
i=1 to t_num-1"] LoopOthers --> SelectRandom["随机选择实体
Math.floor(Math.random() * entities.length)"] SelectRandom --> GetRandomPos["获取随机实体位置"] GetRandomPos --> PushRandom["targets.push(randomPos)"] PushRandom --> MoreTargets{"还有目标?"} MoreTargets --> |是| LoopOthers MoreTargets --> |否| Return ``` **图表来源** - [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L112-L155) ### 目标选择算法详解 1. **实体获取**:通过`check_target()`方法获取敌方实体列表 2. **前排优先**:第一个目标总是最前排的实体 3. **随机分布**:后续目标从所有可用实体中随机选择 4. **重复可能**:由于随机选择,可能出现重复目标 5. **默认处理**:当没有可用目标时,返回预设的默认位置 ### 默认位置处理逻辑 ```typescript const defaultPos = this.HeroView.fac === FacSet.HERO ? v3(400, 0, 0) : v3(-400, 0, 0) ``` 系统根据施法者阵营确定默认位置: - 英雄阵营:x=400 - 敌人阵营:x=-400 **章节来源** - [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L112-L155) ## 异常处理与资源清理 ### 定时器管理机制 ```mermaid classDiagram class TimerManagement { -_timers : object +clear_timer() void +reset() void +onDestroy() void } class TimerOperations { +Object.values(this._timers).forEach(clearTimeout) +this._timers = {} +this.off(GameEvent.CastHeroSkill) } TimerManagement --> TimerOperations : "执行" ``` **图表来源** - [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L157-L177) ### 异常处理策略 1. **节点有效性检查**:在关键操作前后检查节点状态 2. **定时器清理**:确保技能执行完成后清理相关定时器 3. **事件监听移除**:在组件销毁时移除事件监听器 4. **资源释放**:在组件销毁时释放ECS实体资源 ### 资源清理最佳实践 ```typescript public clear_timer() { Object.values(this._timers).forEach(clearTimeout); } reset() { this.clear_timer(); } onDestroy() { Object.values(this._timers).forEach(clearTimeout); this._timers = {}; this.off(GameEvent.CastHeroSkill); } ``` 这些方法确保: - 防止内存泄漏 - 避免僵尸定时器 - 清理事件监听器 - 正确释放ECS资源 **章节来源** - [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L157-L177) ## 性能优化考虑 ### 定时器优化策略 1. **延迟执行**:技能实体创建延迟300ms,避免立即创建大量对象 2. **条件检查**:在每次操作前进行有效性检查,防止无效操作 3. **批量清理**:使用`Object.values`一次性清理所有定时器 ### 内存管理优化 1. **及时清理**:在组件销毁时立即清理所有资源 2. **弱引用**:避免循环引用导致的内存泄漏 3. **对象池**:利用ECS系统提供的实体池机制 ## 最佳实践总结 ### 技能系统设计原则 1. **模块化设计**:SkillConComp专注于控制逻辑,Skill负责实体管理 2. **事件驱动**:通过ECS系统实现松耦合的组件通信 3. **容错机制**:多重节点有效性检查确保系统稳定性 4. **资源管理**:完善的定时器和事件监听器清理机制 ### 开发建议 1. **扩展性考虑**:为新的技能类型预留接口 2. **性能监控**:定期检查定时器数量和内存使用情况 3. **调试支持**:保留必要的日志输出便于问题排查 4. **测试覆盖**:确保各种边界情况都有相应的测试用例 这个技能执行机制展现了现代游戏开发中复杂系统的设计精髓,通过合理的架构设计和完善的异常处理,实现了稳定可靠的技能控制系统。