refactor(技能系统): 重构技能系统以使用s_uuid作为主键并优化技能施放逻辑

- 将HeroSkillsComp中的技能数组改为以s_uuid为键的对象存储
- 修改CSRequestComp使用s_uuid替代skillIndex
- 优化SkillCastSystem和SACastSystem的施放逻辑
- 为SMoveDataComp添加rePos方法处理技能位置计算
- 移除未使用的SDataComSystem代码
This commit is contained in:
2025-10-31 10:47:05 +08:00
parent b38e63e200
commit 2b3b80b308
11 changed files with 230 additions and 96 deletions

View File

@@ -119,7 +119,7 @@ export class HeroLifecycleSystem extends ecs.ComblockSystem
implements ecs.IEntityEnterSystem, ecs.IEntityRemoveSystem { implements ecs.IEntityEnterSystem, ecs.IEntityRemoveSystem {
filter() { filter() {
return ecs.allOf(HeroAttrsComp); return ecs.allOf(HeroMoveComp);
} }
entityEnter(e: ecs.Entity): void { entityEnter(e: ecs.Entity): void {

View File

@@ -6,7 +6,7 @@ import { SkillSet } from "../common/config/SkillSet";
* 单个技能的运行时数据 * 单个技能的运行时数据
*/ */
export interface SkillSlot { export interface SkillSlot {
uuid: number; // 技能配置ID s_uuid: number; // 技能配置ID
cd: number; // 当前CD时间递减 cd: number; // 当前CD时间递减
cd_max: number; // 最大CD时间 cd_max: number; // 最大CD时间
cost: number; // MP消耗 cost: number; // MP消耗
@@ -31,7 +31,7 @@ export class HeroSkillsComp extends ecs.Comp {
// ==================== 技能槽位列表 ==================== // ==================== 技能槽位列表 ====================
/** 技能槽位数组最多4个技能 */ /** 技能槽位数组最多4个技能 */
skills: SkillSlot[] = []; skills: Record<number, SkillSlot> = {};
// ==================== 辅助方法 ==================== // ==================== 辅助方法 ====================
@@ -47,14 +47,13 @@ export class HeroSkillsComp extends ecs.Comp {
console.warn(`[HeroSkills] 技能配置不存在: ${s_uuid}`); console.warn(`[HeroSkills] 技能配置不存在: ${s_uuid}`);
continue; continue;
} }
this.skills[s_uuid]={
this.skills.push({ s_uuid: config.uuid,
uuid: config.uuid, cd: 0,
cd: 0, // 初始CD为0可立即施放
cd_max: config.cd, cd_max: config.cd,
cost: config.cost, cost: config.cost,
level: 1 level: 1,
}); }
} }
} }
@@ -67,30 +66,31 @@ export class HeroSkillsComp extends ecs.Comp {
console.warn(`[HeroSkills] 技能配置不存在: ${s_uuid}`); console.warn(`[HeroSkills] 技能配置不存在: ${s_uuid}`);
return; return;
} }
this.skills[s_uuid] = {
this.skills.push({ s_uuid: config.uuid,
uuid: config.uuid,
cd: 0, cd: 0,
cd_max: config.cd, cd_max: config.cd,
cost: config.cost, cost: config.cost,
level: 1 level: 1
}); };
} }
/** /**
* 获取指定索引的技能 * 获取指定s_uuid的技能
*/ */
getSkill(index: number): SkillSlot | null { getSkill(s_uuid: number): SkillSlot | null {
return this.skills[index] ?? null; return this.skills[s_uuid] ?? null;
} }
/** /**
* 检查技能是否可施放 * 检查技能是否可施放(通过索引)
* @param index 技能索引 * @param index 技能索引
* @param currentMp 当前MP值 * @param currentMp 当前MP值
*/ */
canCast(index: number, currentMp: number): boolean { canCast(s_uuid: number, currentMp: number): boolean {
const skill = this.getSkill(index); const skill = this.getSkill(s_uuid);
if (!skill) return false; if (!skill) return false;
// 检查CD和MP // 检查CD和MP
@@ -98,11 +98,35 @@ export class HeroSkillsComp extends ecs.Comp {
} }
/** /**
* 重置技能CD开始冷却 * 检查技能是否可施放通过s_uuid
* @param s_uuid 技能配置ID
* @param currentMp 当前MP值
*/
canCastByUuid(s_uuid: number, currentMp: number): boolean {
const skill = this.getSkill(s_uuid);
if (!skill) return false;
// 检查CD和MP
return skill.cd <= 0 && currentMp >= skill.cost;
}
/**
* 重置技能CD开始冷却通过索引
* @param index 技能索引 * @param index 技能索引
*/ */
resetCD(index: number) { resetCD(s_uuid: number) {
const skill = this.getSkill(index); const skill = this.getSkill(s_uuid);
if (skill) {
skill.cd = skill.cd_max;
}
}
/**
* 重置技能CD开始冷却通过s_uuid
* @param s_uuid 技能配置ID
*/
resetCDByUuid(s_uuid: number) {
const skill = this.getSkill(s_uuid);
if (skill) { if (skill) {
skill.cd = skill.cd_max; skill.cd = skill.cd_max;
} }
@@ -113,7 +137,8 @@ export class HeroSkillsComp extends ecs.Comp {
* @param dt 时间增量 * @param dt 时间增量
*/ */
updateCDs(dt: number) { updateCDs(dt: number) {
for (const skill of this.skills) { for (const s_uuid in this.skills) {
const skill = this.skills[Number(s_uuid)];
if (skill.cd > 0) { if (skill.cd > 0) {
skill.cd -= dt; skill.cd -= dt;
if (skill.cd < 0) { if (skill.cd < 0) {
@@ -128,15 +153,15 @@ export class HeroSkillsComp extends ecs.Comp {
*/ */
getReadySkills(currentMp: number): number[] { getReadySkills(currentMp: number): number[] {
const ready: number[] = []; const ready: number[] = [];
for (let i = 0; i < this.skills.length; i++) { for (const s_uuid in this.skills) {
if (this.canCast(i, currentMp)) { if (this.canCastByUuid(Number(s_uuid), currentMp)) {
ready.push(i); ready.push(Number(s_uuid));
} }
} }
return ready; return ready;
} }
reset() { reset() {
this.skills = []; this.skills = {};
} }
} }

View File

@@ -18,7 +18,6 @@ const { ccclass, property } = _decorator;
/** 角色显示组件 */ /** 角色显示组件 */
export interface BuffInfo { export interface BuffInfo {
attr: Attrs;
value: number; value: number;
remainTime?: number; remainTime?: number;
} }

View File

@@ -106,7 +106,7 @@ export class MonLifecycleSystem extends ecs.ComblockSystem
implements ecs.IEntityEnterSystem, ecs.IEntityRemoveSystem { implements ecs.IEntityEnterSystem, ecs.IEntityRemoveSystem {
filter() { filter() {
return ecs.allOf(HeroAttrsComp); return ecs.allOf(MonMoveComp);
} }
entityEnter(e: ecs.Entity): void { entityEnter(e: ecs.Entity): void {

View File

@@ -3,8 +3,8 @@ import { Vec3, v3 } from "cc";
import { HeroAttrsComp } from "./HeroAttrsComp"; import { HeroAttrsComp } from "./HeroAttrsComp";
import { HeroViewComp } from "./HeroViewComp"; import { HeroViewComp } from "./HeroViewComp";
import { SkillSet, SType } from "../common/config/SkillSet"; import { SkillSet, SType } from "../common/config/SkillSet";
import { HeroSkillsComp } from "./HeroSkills"; import { HeroSkillsComp, SkillSlot } from "./HeroSkills";
import { CSRequestComp } from "../skill/STagComps"; import { Skill } from "../skill/Skill";
/** /**
* ==================== 自动施法系统 ==================== * ==================== 自动施法系统 ====================
@@ -30,38 +30,116 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
update(e: ecs.Entity): void { update(e: ecs.Entity): void {
const skills = e.get(HeroSkillsComp); const skills = e.get(HeroSkillsComp);
const heroModel = e.get(HeroAttrsComp); const heroAttrs = e.get(HeroAttrsComp);
const heroView = e.get(HeroViewComp); const heroView = e.get(HeroViewComp);
if (!skills || !heroModel || !heroView) return; if (!skills || !heroAttrs || !heroView) return;
// 检查基本条件 // 检查基本条件
if (heroModel.is_dead || heroModel.isStun() || heroModel.isFrost()) return; if (heroAttrs.is_dead || heroAttrs.isStun() || heroAttrs.isFrost()) return;
// 检查是否正在攻击(只有攻击时才释放技能) // 检查是否正在攻击(只有攻击时才释放技能)
if (!heroModel.is_atking) return; if (!heroAttrs.is_atking) return;
// 获取所有可施放的技能 // 获取所有可施放的技能
const readySkills = skills.getReadySkills(heroModel.mp); const readySkills = skills.getReadySkills(heroAttrs.mp);
if (readySkills.length === 0) return; if (readySkills.length === 0) return;
// 选择第一个可施放的伤害技能 // 选择第一个可施放的伤害技能
for (const skillIndex of readySkills) { for (const s_uuid of readySkills) {
const skill = skills.getSkill(skillIndex); const skill = skills.getSkill(s_uuid);
if (!skill) continue; if (!skill) continue;
const config = SkillSet[skill.uuid]; const config = SkillSet[skill.s_uuid];
if (!config || config.SType !== SType.damage) continue; if (!config || config.SType !== SType.damage) continue;
// ✅ 添加施法请求标记组件 // ✅ 开始执行施法
const request = e.add(CSRequestComp) as CSRequestComp; this.startCast(e,skill);
request.skillIndex = skillIndex;
request.targets = this.sTargets(heroView);
// 一次只施放一个技能 // 一次只施放一个技能
break; break;
} }
} }
private startCast(e: ecs.Entity,skill:SkillSlot): void {
if (!skill||!e) return
const skills = e.get(HeroSkillsComp);
const heroAttrs = e.get(HeroAttrsComp);
const heroView = e.get(HeroViewComp);
// 3. 检查施法条件
if (!this.checkCastConditions(skills, heroAttrs, skill.s_uuid)) return
// 4. 执行施法
this.executeCast(e, skill.s_uuid, heroView);
// 5. 扣除资源和重置CD
heroAttrs.mp -= skill.cost;
skills.resetCD(skill.s_uuid);
}
/**
* 检查施法条件
*/
private checkCastConditions(skills: HeroSkillsComp, heroAttrs: HeroAttrsComp, s_uuid: number): boolean {
// 检查角色状态
if (heroAttrs.is_dead) {
return false;
}
// 检查控制状态(眩晕、冰冻)
if (heroAttrs.isStun() || heroAttrs.isFrost()) {
return false;
}
// 检查CD和MP
if (!skills.canCast(s_uuid, heroAttrs.mp)) {
return false;
}
return true;
}
/**
* 执行施法
*/
private executeCast(casterEntity: ecs.Entity, s_uuid: number, heroView: HeroViewComp) {
const config = SkillSet[s_uuid];
if (!config) {
console.error("[SkillCastSystem] 技能配置不存在:", s_uuid);
return;
}
// 1. 播放施法动画
heroView.playSkillEffect(s_uuid);
// 2. 延迟创建技能实体(等待动画)
const delay = config.with ?? 0.3; // 施法前摇时间
heroView.scheduleOnce(() => {
this.createSkill(s_uuid, heroView);
}, delay);
const heroAttrs = casterEntity.get(HeroAttrsComp);
console.log(`[SkillCastSystem] ${heroAttrs?.hero_name ?? '未知'} 施放技能: ${config.name}`);
}
/**
* 创建技能实体
*/
private createSkill(s_uuid: number, caster: HeroViewComp) {
// 检查节点有效性
if (!caster.node || !caster.node.isValid) {
console.warn("[SkillCastSystem] 施法者节点无效");
return;
}
// 获取场景节点
const parent = caster.node.parent;
if (!parent) {
console.warn("[SkillCastSystem] 场景节点无效");
return;
}
const targets=this.sTargets(caster);
// ✅ 使用Skill 创建技能
const skill = ecs.getEntity<Skill>(Skill);
}
/** /**
* 选择目标位置 * 选择目标位置
*/ */
@@ -71,8 +149,8 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
// 这里可以调用 SkillConComp 的目标选择逻辑 // 这里可以调用 SkillConComp 的目标选择逻辑
// 暂时返回默认位置 // 暂时返回默认位置
const heroModel = caster.ent.get(HeroAttrsComp); const heroAttrs = caster.ent.get(HeroAttrsComp);
const fac = heroModel?.fac ?? 0; const fac = heroAttrs?.fac ?? 0;
const defaultX = fac === 0 ? 400 : -400; const defaultX = fac === 0 ? 400 : -400;
targets.push(v3(defaultX, 0, 0)); targets.push(v3(defaultX, 0, 0));
@@ -84,11 +162,11 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
*/ */
private sDamageTargets(caster: HeroViewComp, config: any, maxTargets: number): Vec3[] { private sDamageTargets(caster: HeroViewComp, config: any, maxTargets: number): Vec3[] {
const targets: Vec3[] = []; const targets: Vec3[] = [];
const heroModel = caster.ent.get(HeroAttrsComp); const heroAttrs = caster.ent.get(HeroAttrsComp);
if (!heroModel) return targets; if (!heroAttrs) return targets;
// 寻找最近的敌人 // 寻找最近的敌人
const enemyPositions = this.findNearbyEnemies(caster, heroModel.fac, config.range || 300); const enemyPositions = this.findNearbyEnemies(caster, heroAttrs.fac, config.range || 300);
// 选择最多maxTargets个目标 // 选择最多maxTargets个目标
for (let i = 0; i < Math.min(maxTargets, enemyPositions.length); i++) { for (let i = 0; i < Math.min(maxTargets, enemyPositions.length); i++) {
@@ -97,7 +175,7 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
// 如果没有找到敌人,使用默认位置 // 如果没有找到敌人,使用默认位置
if (targets.length === 0) { if (targets.length === 0) {
targets.push(...this.sDefaultTargets(caster, heroModel.fac)); targets.push(...this.sDefaultTargets(caster, heroAttrs.fac));
} }
return targets; return targets;
@@ -108,11 +186,11 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
*/ */
private sHealTargets(caster: HeroViewComp, config: any, maxTargets: number): Vec3[] { private sHealTargets(caster: HeroViewComp, config: any, maxTargets: number): Vec3[] {
const targets: Vec3[] = []; const targets: Vec3[] = [];
const heroModel = caster.ent.get(HeroAttrsComp); const heroAttrs = caster.ent.get(HeroAttrsComp);
if (!heroModel) return targets; if (!heroAttrs) return targets;
// 寻找血量最低的友军 // 寻找血量最低的友军
const allyPositions = this.findLowHealthAllies(caster, heroModel.fac, config.range || 200); const allyPositions = this.findLowHealthAllies(caster, heroAttrs.fac, config.range || 200);
for (let i = 0; i < Math.min(maxTargets, allyPositions.length); i++) { for (let i = 0; i < Math.min(maxTargets, allyPositions.length); i++) {
targets.push(allyPositions[i]); targets.push(allyPositions[i]);
@@ -179,5 +257,6 @@ export class SACastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdat
return allies; return allies;
} }
} }

View File

@@ -24,7 +24,7 @@ import { CSRequestComp } from "../skill/STagComps";
* - 施法检查与执行分离 * - 施法检查与执行分离
* - 自动处理资源消耗和CD重置 * - 自动处理资源消耗和CD重置
*/ */
@ecs.register('SkillCastSystem') // @ecs.register('SkillCastSystem')
export class SkillCastSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem { export class SkillCastSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem {
/** /**
@@ -38,28 +38,28 @@ export class SkillCastSystem extends ecs.ComblockSystem implements ecs.IEntityEn
* 实体进入时触发(即请求施法时) * 实体进入时触发(即请求施法时)
*/ */
entityEnter(e: ecs.Entity): void { entityEnter(e: ecs.Entity): void {
const skills = e.get(HeroSkillsComp); const skillsComp = e.get(HeroSkillsComp);
const heroModel = e.get(HeroAttrsComp); const heroAttrs = e.get(HeroAttrsComp);
const request = e.get(CSRequestComp); const request = e.get(CSRequestComp);
const heroView = e.get(HeroViewComp); const heroView = e.get(HeroViewComp);
// 1. 验证数据完整性 // 1. 验证数据完整性
if (!skills || !heroModel || !request || !heroView) { if (!skillsComp || !heroAttrs || !request || !heroView) {
console.warn("[SkillCastSystem] 数据不完整,取消施法"); console.warn("[SkillCastSystem] 数据不完整,取消施法");
e.remove(CSRequestComp); e.remove(CSRequestComp);
return; return;
} }
// 2. 获取技能数据 // 2. 获取技能数据
const skill = skills.getSkill(request.skillIndex); const skill = skillsComp.getSkill(request.s_uuid);
if (!skill) { if (!skill) {
console.warn(`[SkillCastSystem] 技能索引无效: ${request.skillIndex}`); console.warn(`[SkillCastSystem] 技能索引无效: ${request.s_uuid }`);
e.remove(CSRequestComp); e.remove(CSRequestComp);
return; return;
} }
// 3. 检查施法条件 // 3. 检查施法条件
if (!this.checkCastConditions(skills, heroModel, request.skillIndex)) { if (!this.checkCastConditions(skillsComp, heroAttrs, request.s_uuid)) {
e.remove(CSRequestComp); e.remove(CSRequestComp);
return; return;
} }
@@ -68,8 +68,8 @@ export class SkillCastSystem extends ecs.ComblockSystem implements ecs.IEntityEn
this.executeCast(e, skill, request.targets, heroView); this.executeCast(e, skill, request.targets, heroView);
// 5. 扣除资源和重置CD // 5. 扣除资源和重置CD
heroModel.mp -= skill.cost; heroAttrs.mp -= skill.cost;
skills.resetCD(request.skillIndex); skillsComp.resetCD(request.s_uuid);
// 6. 移除请求标记 // 6. 移除请求标记
e.remove(CSRequestComp); e.remove(CSRequestComp);
@@ -78,19 +78,19 @@ export class SkillCastSystem extends ecs.ComblockSystem implements ecs.IEntityEn
/** /**
* 检查施法条件 * 检查施法条件
*/ */
private checkCastConditions(skills: HeroSkillsComp, heroModel: HeroAttrsComp, skillIndex: number): boolean { private checkCastConditions(skillsComp: HeroSkillsComp, heroAttrs: HeroAttrsComp, skillIndex: number): boolean {
// 检查角色状态 // 检查角色状态
if (heroModel.is_dead) { if (heroAttrs.is_dead) {
return false; return false;
} }
// 检查控制状态(眩晕、冰冻) // 检查控制状态(眩晕、冰冻)
if (heroModel.isStun() || heroModel.isFrost()) { if (heroAttrs.isStun() || heroAttrs.isFrost()) {
return false; return false;
} }
// 检查CD和MP // 检查CD和MP
if (!skills.canCast(skillIndex, heroModel.mp)) { if (!skillsComp.canCast(skillIndex, heroAttrs.mp)) {
return false; return false;
} }
@@ -116,8 +116,8 @@ export class SkillCastSystem extends ecs.ComblockSystem implements ecs.IEntityEn
this.createSkill(skill.uuid, heroView, targets); this.createSkill(skill.uuid, heroView, targets);
}, delay); }, delay);
const heroModel = casterEntity.get(HeroAttrsComp); const heroAttrs = casterEntity.get(HeroAttrsComp);
console.log(`[SkillCastSystem] ${heroModel?.hero_name ?? '未知'} 施放技能: ${config.name}`); console.log(`[SkillCastSystem] ${heroAttrs?.hero_name ?? '未知'} 施放技能: ${config.name}`);
} }
/** /**

View File

@@ -18,16 +18,16 @@ export class SDataCom extends ecs.Comp {
} }
} }
/** 业务层业务逻辑处理对象 */ // /** 业务层业务逻辑处理对象 */
export class SDataComSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem { // export class SDataComSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem {
filter(): ecs.IMatcher { // filter(): ecs.IMatcher {
return ecs.allOf(SDataCom); // return ecs.allOf(SDataCom);
} // }
entityEnter(e: ecs.Entity): void { // entityEnter(e: ecs.Entity): void {
// 注:自定义业务逻辑 // // 注:自定义业务逻辑
e.remove(SDataCom); // e.remove(SDataCom);
} // }
} // }

View File

@@ -2,6 +2,7 @@ import { Vec3, v3 } from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { BezierMove } from "../BezierMove/BezierMove"; import { BezierMove } from "../BezierMove/BezierMove";
import { RType, SkillSet } from "../common/config/SkillSet"; import { RType, SkillSet } from "../common/config/SkillSet";
import { BoxSet } from "../common/config/BoxSet";
/** /**
* 技能移动数据组件 * 技能移动数据组件
* 存储技能实体的移动相关数据 * 存储技能实体的移动相关数据
@@ -29,6 +30,21 @@ export class SMoveDataComp extends ecs.Comp {
this.direction.set(0, 0, 0); this.direction.set(0, 0, 0);
this.autoDestroy = true; this.autoDestroy = true;
} }
rePos(originalStart:Vec3){
if(!originalStart){
return
}
// 计算延长后的目标点坐标
const originalTarget = v3(this.targetPos.x, this.targetPos.y + BoxSet.ATK_Y);
const direction = new Vec3();
Vec3.subtract(direction, originalTarget, originalStart);
const distance = direction.length();
direction.normalize();
const extendedTarget = new Vec3();
Vec3.scaleAndAdd(extendedTarget, originalTarget, direction, 720);
this.startPos.set(originalStart);
this.targetPos.set(extendedTarget);
}
} }
// /** 业务层业务逻辑处理对象 */ // /** 业务层业务逻辑处理对象 */

View File

@@ -12,13 +12,13 @@ import { Vec3 } from "cc";
@ecs.register('CSRequest') @ecs.register('CSRequest')
export class CSRequestComp extends ecs.Comp { export class CSRequestComp extends ecs.Comp {
/** 技能索引(在 HeroSkillsComp.skills 中的位置) */ /** 技能索引(在 HeroSkillsComp.skills 中的位置) */
skillIndex: number = 0; s_uuid: number = 0;
/** 目标位置数组(由请求者提供) */ /** 目标位置数组(由请求者提供) */
targets: Vec3[] = []; targets: Vec3[] = [];
reset() { reset() {
this.skillIndex = 0; this.s_uuid = 0;
this.targets = []; this.targets = [];
} }
} }

View File

@@ -13,6 +13,7 @@ import { SkillView } from "./SkillView";
import { SDataCom } from "./SDataCom"; import { SDataCom } from "./SDataCom";
import { Attrs } from "../common/config/HeroAttrs"; import { Attrs } from "../common/config/HeroAttrs";
import { SMoveDataComp } from "../skill/SMoveComp"; import { SMoveDataComp } from "../skill/SMoveComp";
import { HeroViewComp } from "../hero/HeroViewComp";
/** Skill 模块 */ /** Skill 模块 */
@ecs.register(`Skill`) @ecs.register(`Skill`)
@@ -32,10 +33,12 @@ export class Skill extends ecs.Entity {
this.addComponents<SDataCom>(); this.addComponents<SDataCom>();
this.addComponents<SMoveDataComp>(); this.addComponents<SMoveDataComp>();
} }
load(startPos: Vec3, parent: Node, uuid: number, targetPos: Vec3,casterAttrs:Attrs[]=[],scale:number=1,fac:FacSet=FacSet.MON,type:HType=HType.warrior,box_group:BoxSet=BoxSet.HERO) { load(startPos: Vec3, parent: Node, s_uuid: number, targetPos: Vec3,
const config = SkillSet[uuid]; caster:HeroViewComp) {
const config = SkillSet[s_uuid];
let casterAttrs=caster.ent.get(HeroAttrsComp).Attrs
if (!config) { if (!config) {
console.error("[Skill] 技能配置不存在:", uuid); console.error("[Skill] 技能配置不存在:", s_uuid);
return; return;
} }
@@ -53,32 +56,35 @@ export class Skill extends ecs.Entity {
// 设置节点属性 // 设置节点属性
node.setPosition(startPos); node.setPosition(startPos);
if(fac==FacSet.MON){ if(casterAttrs.fac==FacSet.MON){
node.scale=v3(node.scale.x*-1,1,1) node.scale=v3(node.scale.x*-1,1,1)
}else{ }else{
if(type==HType.warrior){ if(casterAttrs.type==HType.warrior){
if(scale<0){ if(casterAttrs.node.scale<0){
node.scale=v3(node.scale.x*-1,node.scale.y,1) node.scale=v3(node.scale.x*-1,node.scale.y,1)
} }
} }
} }
// 添加技能组件 // 初始视图
const SView = node.getComponent(SkillView); // 初始化技能参数 const SView = node.getComponent(SkillView);
// 只设置必要的运行时属性,配置信息通过 SkillSet[uuid] 访问 // 只设置必要的运行时属性,配置信息通过 SkillSet[uuid] 访问
// 核心标识 // 核心标识
SView.s_uuid= uuid SView.s_uuid= s_uuid
SView.group= box_group SView.group= caster.box_group
this.add(SView); this.add(SView);
// 初始化移动组件
const sDataCom = this.get(SDataCom);
const sMoveCom = this.get(SMoveDataComp); const sMoveCom = this.get(SMoveDataComp);
sMoveCom.startPos=startPos sMoveCom.startPos=startPos
sMoveCom.targetPos=targetPos sMoveCom.targetPos=targetPos
sMoveCom.s_uuid=uuid sMoveCom.s_uuid=s_uuid
sDataCom.group=box_group
// 初始化数据组件
const sDataCom = this.get(SDataCom);
sDataCom.group=caster.box_group
sDataCom.caster=caster
sDataCom.attrs=casterAttrs sDataCom.attrs=casterAttrs
sDataCom.s_uuid=uuid sDataCom.s_uuid=s_uuid
} }

View File

@@ -1,4 +1,4 @@
import { _decorator, Animation, Collider2D, Contact2DType, Vec3 } from "cc"; import { _decorator, Animation, CCInteger, Collider2D, Contact2DType, v3, Vec3 } from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { HeroViewComp } from "../hero/HeroViewComp"; import { HeroViewComp } from "../hero/HeroViewComp";
@@ -15,6 +15,11 @@ const { ccclass, property } = _decorator;
@ecs.register('SkillView', false) @ecs.register('SkillView', false)
export class SkillView extends CCComp { export class SkillView extends CCComp {
/** 视图层逻辑代码分离演示 */ /** 视图层逻辑代码分离演示 */
@property({ type: CCInteger })
atk_x: number = 0
@property({ type: CCInteger })
atk_y: number = 0
anim:Animation=null; anim:Animation=null;
group:number=0; group:number=0;
SConf:any=null; SConf:any=null;
@@ -29,6 +34,9 @@ export class SkillView extends CCComp {
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this); collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
} }
const SMove=this.ent.get(SMoveDataComp) const SMove=this.ent.get(SMoveDataComp)
// 计算延长后的目标点坐标
SMove.rePos(v3(this.node.position.x + this.atk_x, this.node.position.y + this.atk_y))
switch(this.SConf.RType){ switch(this.SConf.RType){
case RType.linear: case RType.linear:
this.do_linear(SMove.startPos,SMove.targetPos) this.do_linear(SMove.startPos,SMove.targetPos)
@@ -54,6 +62,7 @@ export class SkillView extends CCComp {
if (!this.SConf) return; if (!this.SConf) return;
} }
} }
do_bezier(startPos:Vec3,targetPos:Vec3){ do_bezier(startPos:Vec3,targetPos:Vec3){
let bm=this.node.getComponent(BezierMove) let bm=this.node.getComponent(BezierMove)
this.node.angle +=10 this.node.angle +=10