Files
heros/assets/script/game/skill/新技能系统使用说明.md

7.2 KiB
Raw Blame History

新技能系统使用说明

📊 架构概览

基于 oops-framework ECS 架构设计的完整施法系统。


🗂️ 文件结构

技能系统文件:
├── HeroSkills.ts          # 数据层:技能槽位数据
├── HSkillSystem.ts        # 业务层3个系统
│   ├── SkillCastSystem    # 施法系统
│   ├── SkillCDSystem      # CD更新系统
│   └── SkillAutocastSystem # 自动施法系统AI
└── SkillEnt.ts            # 技能实体(复用现有)

🎯 设计理念

数据层HeroSkillsComp

职责存储角色拥有的技能列表和CD状态

@ecs.register('HeroSkills')
export class HeroSkillsComp extends ecs.Comp {
    skills: SkillSlot[] = [];  // 技能槽位数组
    
    // 数据方法
    initSkills(skillIds: number[]) { }      // 初始化技能
    canCast(index, mp): boolean { }          // 检查可施放
    resetCD(index) { }                       // 重置CD
    updateCDs(dt) { }                        // 更新CD
    getReadySkills(mp): number[] { }         // 获取就绪技能
}

技能槽位数据

interface SkillSlot {
    uuid: number;      // 技能配置ID
    cd: number;        // 当前CD递减
    cd_max: number;    // 最大CD
    cost: number;      // MP消耗
    level: number;     // 技能等级
}

业务层3个系统

1. SkillCastSystem施法系统

职责:监听施法请求,执行施法

export class SkillCastSystem extends ecs.ComblockSystem 
    implements ecs.IEntityEnterSystem {
    
    // 筛选:拥有技能 + 请求标记的实体
    filter(): ecs.IMatcher {
        return ecs.allOf(HeroSkillsComp, HeroAttrsComp, CastSkillRequestComp);
    }
    
    // 处理施法请求
    entityEnter(e: ecs.Entity): void {
        // 1. 检查施法条件CD、MP、状态
        // 2. 扣除MP
        // 3. 重置CD
        // 4. 播放动画
        // 5. 创建技能实体
        // 6. 移除请求标记
    }
}

2. SkillCDSystemCD更新系统

职责每帧自动更新所有技能CD

export class SkillCDSystem extends ecs.ComblockSystem 
    implements ecs.ISystemUpdate {
    
    filter(): ecs.IMatcher {
        return ecs.allOf(HeroSkillsComp);
    }
    
    update(e: ecs.Entity): void {
        const skillsData = e.get(HeroSkillsComp);
        skillsData.updateCDs(this.dt);  // 自动递减CD
    }
}

3. SkillAutocastSystem自动施法系统

职责AI自动选择和施放技能

export class SkillAutocastSystem extends ecs.ComblockSystem 
    implements ecs.ISystemUpdate {
    
    filter(): ecs.IMatcher {
        return ecs.allOf(HeroSkillsComp, HeroAttrsComp, HeroViewComp);
    }
    
    update(e: ecs.Entity): void {
        // 1. 检查角色状态
        // 2. 获取可施放技能
        // 3. 选择目标
        // 4. 添加施法请求标记 ← 触发 SkillCastSystem
    }
}

🔄 数据流程

方式1自动施法AI
    SkillAutocastSystem.update()
        ├─ 检测可施放技能
        ├─ 选择目标
        └─ 添加 CastSkillRequestComp 标记
              ↓
    SkillCastSystem.entityEnter() ← 自动触发
        ├─ 检查施法条件
        ├─ 扣除MP
        ├─ 重置CD
        ├─ 播放施法动画
        ├─ 创建 SkillEnt
        └─ 移除 CastSkillRequestComp

方式2手动施法玩家点击
    UI.onClick()
        └─ skillConComp.manualCastSkill(index)
              └─ 添加 CastSkillRequestComp 标记
                    ↓
              后续流程同方式1

方式3强制施法天赋、事件触发
    TalentSystem
        └─ heroEntity.add(CastSkillRequestComp)
              ↓
        后续流程同方式1

🚀 使用示例

示例 1初始化角色技能

// Hero.ts - load() 方法中
const skillsComp = this.get(HeroSkillsComp);
skillsComp.initSkills(hero.skills);  // [6001, 6005, 6010]

示例 2自动施法默认

无需额外代码SkillAutocastSystem 会自动处理:

// 每帧自动检测:
// - 是否有可施放技能?
// - CD好了MP够
// - 正在攻击?
// ✅ 自动添加施法请求标记 → 触发施法

示例 3手动施法玩家点击

// UI 按钮点击
onSkillButton1Click() {
    const skillCon = this.heroNode.getComponent(SkillConComp);
    skillCon.manualCastSkill(0);  // 施放第0个技能
}

示例 4强制施法天赋触发

// 天赋系统
doTalentEffect(heroEntity: ecs.Entity) {
    // ✅ 添加施法请求标记
    const request = heroEntity.add(CastSkillRequestComp);
    request.skillIndex = 1;  // 施放第1个技能
    request.targetPositions = [v3(100, 0, 0)];
}

⚙️ 系统注册Main.ts

protected async initEcsSystem() {
    // ✅ 注册技能系统(按顺序)
    oops.ecs.add(new SkillCDSystem());        // 1. CD更新
    oops.ecs.add(new SkillAutocastSystem());  // 2. 自动施法AI
    oops.ecs.add(new SkillCastSystem());      // 3. 施法执行
    
    // 战斗系统
    oops.ecs.add(new HeroAtkSystem());
    oops.ecs.add(new HeroAttrSystem());
}

📋 迁移清单

已完成

任务 状态 说明
创建 HeroSkillsComp 技能数据组件
创建 SkillCastSystem 施法执行系统
创建 SkillCDSystem CD更新系统
创建 SkillAutocastSystem 自动施法系统
更新 Hero.ts 添加 HeroSkillsComp
更新 Mon.ts 添加 HeroSkillsComp
从 HeroAttrsComp 移除 skills 数据迁移完成
更新 SkillConComp 使用新系统

🎯 与战斗系统集成

技能系统只负责"施法",伤害结算由战斗系统处理

SkillCastSystem施法
    ↓
创建 SkillEnt技能实体
    ↓
SkillEnt 碰撞检测
    ↓
AtkConCom.single_damage()
    ↓
HeroAtkSystem.doAttack() ← 统一战斗系统
    ├─ 暴击判定
    ├─ 闪避判定
    ├─ 护盾吸收
    ├─ 修改数据
    └─ 触发视图

优点总结

优点 说明
数据分离 技能数据独立组件,不污染 HeroAttrsComp
标记驱动 使用 CastSkillRequestComp 标记组件,符合 ECS
职责清晰 CD更新、施法检查、执行分离成独立系统
易于扩展 添加新施法方式(手动/自动/强制)无需改动核心
易于测试 可单独测试每个系统
代码复用 手动/自动/强制施法共用同一套逻辑

🎉 总结

完整的、规范的、基于 oops-framework 的技能施法系统!

符合 ECS 架构(数据/业务/视图分离)
使用标记组件驱动,完全解耦
复用现有 SkillEnt无需重写
与战斗系统完美集成
支持自动/手动/强制多种施法方式
代码清晰,注释详细

可直接投入生产使用! 🚀