14 KiB
14 KiB
技能机制
**本文档中引用的文件** - [Mon.ts](file://assets/script/game/hero/Mon.ts) - [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts) - [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts) - [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts) - [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts) - [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts) - [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts) - [heroSet.ts](file://assets/script/game/common/config/heroSet.ts)目录
概述
本游戏采用基于ECS(Entity-Component-System)架构的技能系统,通过多个核心组件协同工作,实现了复杂的技能机制。技能系统支持主动技能、被动技能、技能组合以及自定义技能行为,为战斗提供了丰富的策略深度。
核心组件架构
classDiagram
class Monster {
+MonModelComp HeroModel
+HeroViewComp HeroView
+BattleMoveComp BattleMove
+hero_init(uuid, node, scale, box_group, is_boss, is_call, strength_multiplier)
+load(pos, scale, uuid, is_boss, is_call, strengthMultiplier)
}
class SkillConComp {
+HeroView HeroView
+HeroEntity HeroEntity
+TALCOMP TALCOMP
+skill_cd number
+update(dt)
+castSkill(config)
+doSkill(config, is_wfuny, dmg)
+selectTargets(t_num)
}
class SkillEnt {
+load(startPos, parent, uuid, targetPos, caster, dmg)
+destroy()
}
class HeroViewComp {
+skills any[]
+mp number
+hp number
+Attrs any[]
+playSkillEffect(skill_id)
+do_atked(remainingDamage, CAttrs, s_uuid)
}
class SkillSet {
+uuid number
+name string
+SType SType
+TGroup TGroup
+ap number
+cd number
+cost number
}
Monster --> SkillConComp : "包含"
SkillConComp --> HeroViewComp : "控制"
SkillConComp --> SkillEnt : "创建"
SkillEnt --> SkillViewCom : "加载"
HeroViewComp --> SkillSet : "使用配置"
图表来源
技能初始化机制
hero_init方法详解
hero_init方法是技能初始化的核心入口,负责根据英雄配置动态创建技能实例并设置各项参数。
flowchart TD
A["开始 hero_init"] --> B["获取英雄配置"]
B --> C["初始化基础属性"]
C --> D["遍历技能数组"]
D --> E["创建技能对象"]
E --> F["设置UUID、CD、消耗值"]
F --> G["添加到技能列表"]
G --> H["初始化属性系统"]
H --> I["结束"]
E --> E1["uuid: SkillSet[hero.skills[i]].uuid"]
E --> E2["cd_max: SkillSet[hero.skills[i]].cd"]
E --> E3["cost: SkillSet[hero.skills[i]].cost"]
E --> E4["cd: 0"]
图表来源
技能初始化步骤
- 英雄配置获取:从
HeroInfo中获取英雄基础数据 - 属性基础值设置:根据强度倍率调整基础属性值
- 技能数组遍历:逐个处理英雄配置中的技能UUID
- 技能对象创建:为每个技能创建包含UUID、冷却时间、消耗值的对象
- 技能列表填充:将创建的技能对象添加到
HeroView.skills数组 - 属性系统初始化:调用
initAttrs()初始化完整属性系统
节来源
技能配置数据结构
技能配置通过SkillSet常量定义,支持多种技能类型和效果:
| 属性 | 类型 | 描述 | 示例值 |
|---|---|---|---|
| uuid | number | 技能唯一标识符 | 6001, 6005 |
| name | string | 技能显示名称 | "挥击", "火球术" |
| SType | SType | 技能效果类型 | SType.damage, SType.heal |
| TGroup | TGroup | 目标群体类型 | TGroup.Enemy, TGroup.Self |
| ap | number | 攻击力百分比 | 100, 300 |
| cd | number | 冷却时间(秒) | 1, 5 |
| cost | number | 技能消耗值 | 0, 20 |
| hit_num | number | 攻击目标数量 | 1, 3 |
节来源
技能控制系统
SkillConComp组件功能
SkillConComp是技能系统的核心控制器,负责技能触发、冷却管理和释放流程。
sequenceDiagram
participant Player as "玩家输入"
participant SkillCon as "SkillConComp"
participant HeroView as "HeroViewComp"
participant SkillEnt as "SkillEnt"
participant SkillView as "SkillViewCom"
Player->>SkillCon : 技能触发请求
SkillCon->>SkillCon : 检查冷却时间
SkillCon->>SkillCon : 检查MP消耗
SkillCon->>SkillCon : castSkill()
SkillCon->>SkillCon : doSkill()
SkillCon->>SkillCon : selectTargets()
SkillCon->>SkillEnt : 创建技能实体
SkillEnt->>SkillView : 加载技能视图
SkillView->>SkillView : 执行技能动画
SkillView->>SkillView : 处理碰撞检测
SkillView->>HeroView : 造成伤害/效果
图表来源
技能触发机制
技能触发遵循以下优先级和条件:
- 状态检查:确保角色未处于眩晕或冰冻状态
- 冷却检查:技能CD时间超过最大值
- 资源检查:MP值足够支付技能消耗
- 类型匹配:技能类型为伤害类且角色处于攻击状态
节来源
冷却管理系统
flowchart TD
A["update(dt)"] --> B{"游戏状态检查"}
B --> |暂停/未开始| C["跳过更新"]
B --> |正常| D["遍历技能列表"]
D --> E["累积CD时间"]
E --> F{"CD > CD_MAX AND MP >= COST?"}
F --> |是| G["触发技能"]
F --> |否| H["继续等待"]
G --> I["重置CD = 0"]
I --> J["扣除MP"]
J --> K["播放技能效果"]
图表来源
节来源
技能数据结构
SkillSet配置系统
SkillSet提供了完整的技能数据结构定义,支持技能的完整生命周期管理。
classDiagram
class SkillConfig {
+uuid : number
+name : string
+sp_name : string
+path : string
+TGroup : TGroup
+SType : SType
+act : string
+DTType : DTType
+DType : DType
+ap : number
+cd : number
+t_num : number
+hit_num : number
+hit : number
+hitcd : number
+speed : number
+cost : number
+with : number
+buffs : BuffConf[]
+neAttrs : NeAttrsConf[]
+info : string
}
class BuffConf {
+buff : Attrs
+BType : BType
+value : number
+time : number
+chance : number
}
class NeAttrsConf {
+neAttrs : NeAttrs
+value : number
+time : number
}
SkillConfig --> BuffConf : "包含"
SkillConfig --> NeAttrsConf : "包含"
图表来源
技能类型枚举
| SType值 | 类型名称 | 效果描述 | 使用场景 |
|---|---|---|---|
| 0 | damage | 造成伤害 | 主要攻击技能 |
| 1 | heal | 治疗效果 | 辅助/回复技能 |
| 2 | shield | 护盾效果 | 防御型技能 |
| 3 | atk_speed | 攻击速度提升 | 增益技能 |
| 4 | power_up | 力量提升 | 战斗强化技能 |
| 5 | ap_up | 攻击力提升 | 输出增强技能 |
| 10 | zhaohuan | 召唤技能 | 召唤物技能 |
| 11 | buff | 通用增益 | 多功能增益技能 |
节来源
技能释放流程
技能实体创建流程
sequenceDiagram
participant SkillCon as "SkillConComp"
participant ECS as "ECS系统"
participant SkillEnt as "SkillEnt"
participant SkillView as "SkillViewCom"
participant AtkCon as "AtkConCom"
SkillCon->>ECS : 获取SkillEnt实体
ECS-->>SkillCon : 返回SkillEnt实例
SkillCon->>SkillEnt : load(startPos, parent, uuid, targetPos, caster, dmg)
SkillEnt->>SkillEnt : 验证技能配置
SkillEnt->>SkillEnt : 加载技能预制体
SkillEnt->>SkillEnt : 设置节点属性
SkillEnt->>SkillView : 添加SkillViewCom组件
SkillView->>SkillView : 初始化技能参数
SkillView->>SkillView : 创建AtkConCom实例
SkillView->>AtkCon : 配置攻击组件
AtkCon->>AtkCon : 执行具体技能逻辑
图表来源
目标选择算法
技能系统实现了智能的目标选择机制,支持多种目标选择策略:
flowchart TD
A["开始目标选择"] --> B{"是否有目标实体?"}
B --> |否| C["返回默认位置"]
B --> |是| D["获取所有目标实体"]
D --> E["第一个目标:最前排"]
E --> F["后续目标:随机选择"]
F --> G["返回目标坐标数组"]
E --> E1["计算最前排位置"]
E1 --> E2["选择最近的实体"]
F --> F1["随机选择实体"]
F1 --> F2["重复选择可重复"]
图表来源
节来源
技能类型与效果
伤害计算机制
技能造成的伤害通过多层计算确定:
flowchart TD
A["基础攻击力"] --> B["应用技能AP比例"]
B --> C["计算最终伤害"]
C --> D{"是否暴击?"}
D --> |是| E["应用暴击伤害倍率"]
D --> |否| F["普通伤害"]
E --> G["应用穿透效果"]
F --> G
G --> H["应用护盾吸收"]
H --> I["最终伤害值"]
G --> G1["计算穿透衰减"]
G1 --> G2["应用穿透属性"]
H --> H1["检查护盾值"]
H1 --> H2["计算吸收量"]
图表来源
Buff系统集成
技能系统与Buff系统紧密集成,支持技能触发Buff效果:
| Buff类型 | BType | 效果 | 应用时机 |
|---|---|---|---|
| 数值型 | VALUE | 直接数值加成 | 属性计算时 |
| 百分比型 | RATIO | 百分比加成 | 属性计算时 |
| 持久型 | - | 永久生效 | 持续应用 |
| 临时型 | - | 按时间衰减 | 定时更新 |
节来源
开发指引
为怪物配置主动技能
- 编辑heroSet.ts:在
HeroInfo中添加怪物配置 - 配置技能数组:在
skills字段中指定技能UUID - 调整属性值:根据怪物定位设置HP、MP、AP等属性
- 测试平衡性:验证技能冷却和消耗的合理性
实现技能组合
// 示例:配置多重技能组合
const monsterConfig = {
uuid: 5201,
name: "兽人战士",
skills: [6001, 6005, 6006], // 多个技能
// 其他属性...
};
// 在技能触发时添加组合效果
SkillConComp.prototype.comboSkills = function() {
// 实现技能组合逻辑
// 如:连续使用技能获得额外效果
};
自定义技能行为
- 扩展SkillSet:在
SkillSet中添加新技能配置 - 实现特殊效果:在
AtkConCom中添加自定义逻辑 - 注册事件监听:监听技能触发相关事件
- 测试兼容性:确保新技能与现有系统兼容
节来源
常见问题与解决方案
技能同步问题
问题描述
多人游戏中技能释放不同步,导致战斗结果不一致。
解决方案
flowchart TD
A["技能释放请求"] --> B["客户端验证"]
B --> C["发送服务器确认"]
C --> D["服务器验证"]
D --> E{"验证通过?"}
E --> |是| F["广播技能效果"]
E --> |否| G["拒绝请求"]
F --> H["客户端同步显示"]
G --> I["显示错误提示"]
D --> D1["检查冷却时间"]
D --> D2["检查资源充足"]
D --> D3["检查状态允许"]
实现要点
- 服务器端验证:所有技能释放必须经过服务器验证
- 延迟补偿:处理网络延迟导致的技能时间差
- 状态同步:确保客户端和服务器状态一致
- 错误处理:优雅处理同步失败的情况
性能优化建议
技能实体管理
// 优化技能实体创建和销毁
class SkillEntityManager {
private pool: SkillEnt[] = [];
createSkill(config: SkillConfig): SkillEnt {
let skill = this.pool.pop();
if (!skill) {
skill = ecs.getEntity<SkillEnt>(SkillEnt);
}
skill.load(...);
return skill;
}
recycleSkill(skill: SkillEnt): void {
skill.reset();
this.pool.push(skill);
}
}
冷却时间优化
- 批量更新:每帧批量处理所有技能的CD更新
- 优先级调度:优先处理重要技能的冷却检查
- 内存池:复用技能对象减少GC压力
调试工具
技能日志系统
class SkillDebugger {
static logSkillExecution(skillId: number, params: any): void {
console.log(`[Skill] 执行技能 ${skillId}`, {
timestamp: Date.now(),
params,
performance: performance.now()
});
}
static logCooldownUpdate(skillId: number, currentCD: number, maxCD: number): void {
console.log(`[Skill] 技能${skillId}冷却: ${currentCD}/${maxCD}`);
}
}
节来源
总结
本技能系统通过ECS架构实现了高度模块化和可扩展的设计,主要特点包括:
- 模块化架构:各组件职责明确,便于维护和扩展
- 灵活配置:通过SkillSet实现技能的完全配置化
- 性能优化:采用对象池和批量处理提高性能
- 扩展性强:支持自定义技能类型和效果
- 网络友好:内置同步机制确保多人游戏一致性
该系统为游戏战斗提供了坚实的技术基础,支持复杂技能组合和策略玩法,是构建高质量战斗体验的重要组成部分。