390 lines
12 KiB
Markdown
390 lines
12 KiB
Markdown
# 多段连发技能执行机制深度解析
|
||
|
||
<cite>
|
||
**本文档引用的文件**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts)
|
||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts)
|
||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts)
|
||
- [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts)
|
||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts)
|
||
- [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [引言](#引言)
|
||
2. [WFUNY属性机制概述](#wfuny属性机制概述)
|
||
3. [核心组件架构](#核心组件架构)
|
||
4. [check_wfuny概率触发机制](#check_wfuny概率触发机制)
|
||
5. [递归调度执行模型](#递归调度执行模型)
|
||
6. [技能执行链路分析](#技能执行链路分析)
|
||
7. [ECS实体生成与管理](#ecs实体生成与管理)
|
||
8. [定时器延迟加载机制](#定时器延迟加载机制)
|
||
9. [节点有效性检查机制](#节点有效性检查机制)
|
||
10. [性能优化与风险控制](#性能优化与风险控制)
|
||
11. [总结](#总结)
|
||
|
||
## 引言
|
||
|
||
本系统实现了一套基于WFUNY属性的概率性多段技能连发机制,通过随机数与英雄属性的比较实现技能触发概率控制,配合递归调度和ECS实体管理,构建了一个完整的技能执行流水线。该机制不仅支持技能连续释放效果,还通过多重验证确保异步执行的安全性。
|
||
|
||
## WFUNY属性机制概述
|
||
|
||
WFUNY属性作为系统的核心概率控制因子,定义了技能连发的基础触发概率。该属性属于百分比型属性,其数值直接影响技能连发的成功概率。
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class HeroAttrs {
|
||
+WFUNY : number
|
||
+check_wfuny() boolean
|
||
+calculateAttributeGains() object
|
||
}
|
||
class SkillConComp {
|
||
+check_wfuny() boolean
|
||
+castSkill() void
|
||
+doSkill() void
|
||
-_timers : object
|
||
}
|
||
class SkillEnt {
|
||
+load() void
|
||
+destroy() void
|
||
}
|
||
HeroAttrs --> SkillConComp : "提供WFUNY属性"
|
||
SkillConComp --> SkillEnt : "创建技能实体"
|
||
```
|
||
|
||
**图表来源**
|
||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L40-L45)
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L95-L104)
|
||
|
||
**章节来源**
|
||
- [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts#L40-L45)
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L95-L104)
|
||
|
||
## 核心组件架构
|
||
|
||
系统采用ECS架构模式,主要包含以下核心组件:
|
||
|
||
### 技能控制器组件 (SkillConComp)
|
||
负责技能的整体调度和生命周期管理,维护定时器集合和技能状态。
|
||
|
||
### 技能实体 (SkillEnt)
|
||
作为ECS实体,封装技能的完整生命周期,包括特效加载、参数传递和资源管理。
|
||
|
||
### 技能视图组件 (SkillViewCom)
|
||
处理技能的视觉表现和动画控制,协调技能的执行时机和效果展示。
|
||
|
||
### 攻击组件 (AtkConCom)
|
||
实现具体的伤害计算和碰撞检测逻辑,支持多种攻击模式和伤害类型。
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "技能执行流水线"
|
||
A[技能触发] --> B[check_wfuny概率检查]
|
||
B --> C{是否满足连发条件}
|
||
C --> |是| D[scheduleOnce递归调度]
|
||
C --> |否| E[doSkill执行]
|
||
D --> F[doSkill递归调用]
|
||
F --> G[技能实体创建]
|
||
G --> H[特效播放]
|
||
H --> I[伤害计算]
|
||
end
|
||
subgraph "ECS实体管理"
|
||
J[SkillEnt实体] --> K[SkillViewCom组件]
|
||
K --> L[AtkConCom组件]
|
||
L --> M[碰撞检测]
|
||
end
|
||
E --> G
|
||
I --> N[目标伤害处理]
|
||
```
|
||
|
||
**图表来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L58-L110)
|
||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L13-L77)
|
||
|
||
**章节来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L1-L35)
|
||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L1-L33)
|
||
|
||
## check_wfuny概率触发机制
|
||
|
||
`check_wfuny`方法实现了基于随机数的概率触发逻辑,这是整个连发机制的核心判断点。
|
||
|
||
### 概率计算算法
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[开始check_wfuny] --> B[生成0-100的随机数]
|
||
B --> C[获取WFUNY属性值]
|
||
C --> D{random < WFUNY?}
|
||
D --> |是| E[返回true - 触发连发]
|
||
D --> |否| F[返回false - 不触发连发]
|
||
E --> G[继续技能连发]
|
||
F --> H[结束当前技能]
|
||
```
|
||
|
||
**图表来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L95-L104)
|
||
|
||
### 实现细节分析
|
||
|
||
该方法采用简单的概率判断逻辑:
|
||
1. 生成0-100范围内的随机浮点数
|
||
2. 获取英雄的WFUNY属性值
|
||
3. 比较随机数与WFUNY值
|
||
4. 当随机数小于WFUNY时返回true,否则返回false
|
||
|
||
这种设计确保了技能连发的概率可控,且与英雄属性紧密关联。
|
||
|
||
**章节来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L95-L104)
|
||
|
||
## 递归调度执行模型
|
||
|
||
系统采用`scheduleOnce`方法实现递归调度,每次调度间隔为0.1秒,形成稳定的技能连发节奏。
|
||
|
||
### 调度机制流程
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant SC as SkillConComp
|
||
participant Timer as scheduleOnce
|
||
participant DS as doSkill
|
||
participant SE as SkillEnt
|
||
participant SV as SkillViewCom
|
||
SC->>SC : castSkill触发
|
||
SC->>SC : check_wfuny判断
|
||
alt WFUNY触发成功
|
||
SC->>Timer : scheduleOnce(doSkill, 0.1)
|
||
Timer->>DS : 0.1秒后回调
|
||
DS->>SC : 递归调用doSkill
|
||
SC->>SE : 创建技能实体
|
||
SE->>SV : 初始化技能组件
|
||
SV->>SV : 执行技能逻辑
|
||
else WFUNY触发失败
|
||
SC->>DS : 直接执行doSkill
|
||
DS->>SE : 创建技能实体
|
||
SE->>SV : 初始化技能组件
|
||
SV->>SV : 执行技能逻辑
|
||
end
|
||
```
|
||
|
||
**图表来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L66-L110)
|
||
|
||
### 递归安全机制
|
||
|
||
系统通过以下机制避免无限递归:
|
||
|
||
1. **概率控制**:WFUNY属性限制了连发的概率
|
||
2. **条件检查**:每次递归都进行节点有效性验证
|
||
3. **状态管理**:通过定时器ID管理和清理机制
|
||
|
||
**章节来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L66-L110)
|
||
|
||
## 技能执行链路分析
|
||
|
||
技能执行遵循严格的调用链路,确保各组件间的协调工作。
|
||
|
||
### 主要执行路径
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A[castSkill] --> B[check_wfuny]
|
||
B --> C{WFUNY检查}
|
||
C --> |成功| D[doSkill + 递归调度]
|
||
C --> |失败| E[doSkill + 直接执行]
|
||
D --> F[技能实体创建]
|
||
E --> F
|
||
F --> G[特效播放]
|
||
G --> H[目标选择]
|
||
H --> I[伤害计算]
|
||
I --> J[效果应用]
|
||
```
|
||
|
||
**图表来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L58-L110)
|
||
|
||
### 关键执行步骤
|
||
|
||
1. **技能触发阶段**:`castSkill`方法启动技能执行
|
||
2. **概率验证阶段**:`check_wfuny`验证连发条件
|
||
3. **实体创建阶段**:通过ECS框架创建技能实体
|
||
4. **特效播放阶段**:播放技能视觉效果
|
||
5. **目标选择阶段**:根据技能配置选择目标
|
||
6. **伤害计算阶段**:计算并应用伤害效果
|
||
|
||
**章节来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L58-L110)
|
||
|
||
## ECS实体生成与管理
|
||
|
||
系统采用ECS架构模式,通过SkillEnt实体统一管理技能的生命周期。
|
||
|
||
### 实体创建流程
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class SkillEnt {
|
||
+load(startPos, parent, uuid, targetPos, caster, dmg) void
|
||
+destroy() void
|
||
-init() void
|
||
}
|
||
class SkillViewCom {
|
||
+s_uuid : number
|
||
+caster : HeroViewComp
|
||
+Attrs : object
|
||
+doSkill() void
|
||
+move() void
|
||
}
|
||
class AtkConCom {
|
||
+single_damage() void
|
||
+onBeginContact() void
|
||
+update() void
|
||
}
|
||
SkillEnt --> SkillViewCom : "添加组件"
|
||
SkillViewCom --> AtkConCom : "协作处理"
|
||
```
|
||
|
||
**图表来源**
|
||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L13-L77)
|
||
- [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts#L13-L155)
|
||
|
||
### 实体参数传递
|
||
|
||
SkillEnt.load方法负责将所有必要的参数传递给技能实体:
|
||
|
||
| 参数 | 类型 | 描述 | 用途 |
|
||
|------|------|------|------|
|
||
| startPos | Vec3 | 技能起始位置 | 确定技能发射点 |
|
||
| parent | Node | 父节点 | 设置技能层级关系 |
|
||
| uuid | number | 技能唯一标识 | 查找技能配置 |
|
||
| targetPos | any[] | 目标位置数组 | 多目标技能支持 |
|
||
| caster | HeroViewComp | 施法者组件 | 获取施法者属性 |
|
||
| dmg | number | 伤害值 | 支持伤害倍率计算 |
|
||
|
||
**章节来源**
|
||
- [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts#L13-L77)
|
||
|
||
## 定时器延迟加载机制
|
||
|
||
系统采用setTimeout实现300毫秒的延迟加载,确保技能特效完全播放后再开始执行。
|
||
|
||
### 延迟加载流程
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant SC as SkillConComp
|
||
participant Timer as setTimeout
|
||
participant SE as SkillEnt
|
||
participant SV as SkillViewCom
|
||
SC->>SC : doSkill执行
|
||
SC->>SC : playSkillEffect播放特效
|
||
SC->>Timer : setTimeout(300ms)
|
||
Timer->>SC : 300ms后回调
|
||
SC->>SE : ecs.getEntity<SkillEnt>()
|
||
SC->>SE : load()加载技能
|
||
SE->>SV : 初始化技能组件
|
||
SV->>SV : 开始技能逻辑
|
||
```
|
||
|
||
**图表来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L66-L110)
|
||
|
||
### 定时器管理策略
|
||
|
||
系统维护一个定时器字典,每个技能UUID对应一个定时器ID:
|
||
|
||
```typescript
|
||
private _timers: { [key: string]: any } = {};
|
||
```
|
||
|
||
这种设计允许:
|
||
- 单独管理每个技能的定时器
|
||
- 支持技能中断和清理
|
||
- 避免定时器泄漏
|
||
|
||
**章节来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L20-L25)
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L177)
|
||
|
||
## 节点有效性检查机制
|
||
|
||
为了确保异步执行的安全性,系统在多个关键节点实施有效性检查。
|
||
|
||
### 检查层次结构
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[技能开始] --> B{this.node有效?}
|
||
B --> |否| C[直接返回]
|
||
B --> |是| D{this.HeroView有效?}
|
||
D --> |否| C
|
||
D --> |是| E{HeroView.node有效?}
|
||
E --> |否| C
|
||
E --> |是| F[继续执行]
|
||
F --> G[技能实体创建]
|
||
G --> H{再次检查节点}
|
||
H --> |否| I[清理资源]
|
||
H --> |是| J[执行技能逻辑]
|
||
```
|
||
|
||
**图表来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L75-L85)
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L78-L85)
|
||
|
||
### 检查时机分布
|
||
|
||
1. **技能触发前检查**:验证调用者的有效性
|
||
2. **定时器回调检查**:确保延迟执行时对象仍然存在
|
||
3. **技能实体创建检查**:验证目标节点的有效性
|
||
4. **组件更新检查**:防止已销毁对象的访问
|
||
|
||
这种多层次的检查机制有效防止了内存泄漏和空指针异常。
|
||
|
||
**章节来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L75-L85)
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L78-L85)
|
||
|
||
## 性能优化与风险控制
|
||
|
||
### 性能优化策略
|
||
|
||
1. **ECS架构优势**:组件化设计提高内存利用率
|
||
2. **延迟加载**:300ms延迟避免立即创建大量对象
|
||
3. **定时器复用**:统一管理定时器资源
|
||
4. **条件检查**:及时退出无效执行路径
|
||
|
||
### 风险控制机制
|
||
|
||
1. **概率限制**:WFUNY属性控制连发频率
|
||
2. **超时保护**:0.1秒间隔避免CPU占用过高
|
||
3. **内存管理**:自动清理定时器和销毁实体
|
||
4. **异常捕获**:节点有效性检查防止崩溃
|
||
|
||
### 安全边界设计
|
||
|
||
```mermaid
|
||
graph LR
|
||
A[输入验证] --> B[概率控制]
|
||
B --> C[定时器管理]
|
||
C --> D[节点检查]
|
||
D --> E[资源清理]
|
||
E --> F[异常处理]
|
||
```
|
||
|
||
**章节来源**
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L95-L104)
|
||
- [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts#L150-L177)
|
||
|
||
## 总结
|
||
|
||
这套基于WFUNY属性的多段技能连发机制展现了现代游戏开发中复杂系统的设计精髓:
|
||
|
||
1. **概率驱动的动态行为**:通过WFUNY属性实现技能连发的概率控制,使战斗更具策略性和不确定性
|
||
2. **异步执行的安全保障**:多重节点有效性检查确保了异步操作的稳定性
|
||
3. **ECS架构的高效利用**:组件化设计提供了良好的扩展性和维护性
|
||
4. **资源管理的精细化**:定时器管理和实体生命周期控制体现了对性能的关注
|
||
5. **递归调度的巧妙运用**:0.1秒间隔的递归调度既保证了流畅性,又避免了性能问题
|
||
|
||
这套机制不仅实现了技能连发功能,更为复杂的技能系统扩展奠定了坚实基础,是游戏开发中概率性技能系统设计的优秀范例。 |