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

297 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 新技能系统使用说明
## 📊 架构概览
基于 **oops-framework ECS** 架构设计的完整施法系统。
---
## 🗂️ 文件结构
```
技能系统文件:
├── HeroSkills.ts # 数据层:技能槽位数据
├── HSkillSystem.ts # 业务层3个系统
│ ├── SkillCastSystem # 施法系统
│ ├── SkillCDSystem # CD更新系统
│ └── SkillAutocastSystem # 自动施法系统AI
└── SkillEnt.ts # 技能实体(复用现有)
```
---
## 🎯 设计理念
### **数据层HeroSkillsComp**
**职责**存储角色拥有的技能列表和CD状态
```typescript
@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[] { } // 获取就绪技能
}
```
**技能槽位数据**
```typescript
interface SkillSlot {
uuid: number; // 技能配置ID
cd: number; // 当前CD递减
cd_max: number; // 最大CD
cost: number; // MP消耗
level: number; // 技能等级
}
```
---
### **业务层3个系统**
#### **1. SkillCastSystem施法系统⭐**
**职责**:监听施法请求,执行施法
```typescript
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
```typescript
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自动选择和施放技能
```typescript
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初始化角色技能**
```typescript
// Hero.ts - load() 方法中
const skillsComp = this.get(HeroSkillsComp);
skillsComp.initSkills(hero.skills); // [6001, 6005, 6010]
```
---
### **示例 2自动施法默认**
**无需额外代码**`SkillAutocastSystem` 会自动处理:
```typescript
// 每帧自动检测:
// - 是否有可施放技能?
// - CD好了MP够
// - 正在攻击?
// ✅ 自动添加施法请求标记 → 触发施法
```
---
### **示例 3手动施法玩家点击**
```typescript
// UI 按钮点击
onSkillButton1Click() {
const skillCon = this.heroNode.getComponent(SkillConComp);
skillCon.manualCastSkill(0); // 施放第0个技能
}
```
---
### **示例 4强制施法天赋触发**
```typescript
// 天赋系统
doTalentEffect(heroEntity: ecs.Entity) {
// ✅ 添加施法请求标记
const request = heroEntity.add(CastSkillRequestComp);
request.skillIndex = 1; // 施放第1个技能
request.targetPositions = [v3(100, 0, 0)];
}
```
---
## ⚙️ 系统注册Main.ts
```typescript
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无需重写
✅ 与战斗系统完美集成
✅ 支持自动/手动/强制多种施法方式
✅ 代码清晰,注释详细
**可直接投入生产使用!** 🚀