import { Node, Vec3 } from "cc"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { HeroViewComp } from "../hero/HeroViewComp"; import { SkillSet } from "../common/config/SkillSet"; import { SkillAnimationComp } from "./SkillAnimation"; import { ProjectileComp } from "./ProjectileComp"; /** 技能触发组件 */ @ecs.register('HerosSkills') export class SkillsComp extends ecs.Comp { /** 技能ID */ skillId: number = 0; /** 目标位置/实体 */ target: Vec3 | Node | null = null; /** 当前冷却时间 */ currentCooldown: number = 0; reset() { this.skillId = 0; this.target = null; this.currentCooldown = 0; } } /** 技能系统 */ @ecs.register('SkillSystem') export class SkillSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate { filter(): ecs.IMatcher { return ecs.allOf(SkillsComp, HeroViewComp); } update(e: ecs.Entity) { let skill = e.get(SkillsComp); let view = e.get(HeroViewComp); if (this.canCastSkill(skill, view)) { this.castSkill(e, skill); } } private canCastSkill(skill: SkillsComp, view: HeroViewComp): boolean { return skill.currentCooldown <= 0 && view.pw >= view.pwm; } private castSkill(entity: ecs.Entity, skill: SkillsComp) { const skillData = SkillSet[skill.skillId]; // // 创建飞弹实体 // const projectile = ecs.createEntity(); // const projView = projectile.add(HeroViewComp); // projView.node = instantiate(skillData.prefab); // projView.node.setParent(entity.get(HeroViewComp).node.parent); // projView.node.setPosition(entity.get(HeroViewComp).node.position); // // 添加投射物组件 // projectile.add(ProjectileComp, { // speed: skillData.speed, // direction: entity.get(HeroViewComp).node.scale.x > 0 ? Vec3.RIGHT : Vec3.LEFT, // maxDistance: skillData.range, // penetrate: skillData.penetrate // }); // 应用冷却时间 skill.currentCooldown = skillData.cooldown; // 根据技能类型处理 switch(skillData.type) { case 'damage': this.handleDamage(entity, skillData); break; case 'heal': this.handleHeal(entity, skillData); break; case 'projectile': this.castProjectileSkill(entity, skillData); break; } // 播放动画(示例) // entity.get(HeroViewComp).playAnimation(skillData.anim); // 触发完成回调 entity.remove(SkillsComp); } private handleDamage(entity: ecs.Entity, data: any) { const view = entity.get(HeroViewComp); // 实现伤害逻辑... } private handleHeal(entity: ecs.Entity, data: any) { const view = entity.get(HeroViewComp); // 实现治疗逻辑... } private castProjectileSkill(entity: ecs.Entity, skillData: any) { const view = entity.get(HeroViewComp); // 创建飞弹实体 } private exit(e: ecs.Entity) { e.remove(SkillsComp); } } // 动画系统 @ecs.register('SkillAnimationSystem') export class SkillAnimationSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate { filter(): ecs.IMatcher { return ecs.allOf(SkillAnimationComp); } update(e: ecs.Entity): void { const anim = e.get(SkillAnimationComp); anim.elapsed += this.dt; // 触发伤害检测 if (anim.elapsed >= anim.damageTriggerTime) { e.add(DamageLineComp); // 添加伤害区域组件 e.remove(SkillAnimationComp); } } } // 直线型伤害区域组件 @ecs.register('DamageLine') export class DamageLineComp extends ecs.Comp { startPos: Vec3 = new Vec3(); direction: Vec3 = Vec3.RIGHT; length: number = 300; width: number = 50; reset() { this.startPos.set(); this.direction.set(Vec3.RIGHT); this.length = 300; this.width = 50; } } // 直线伤害系统 @ecs.register('DamageLineSystem') export class DamageLineSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate { filter(): ecs.IMatcher { return ecs.allOf(DamageLineComp, HeroViewComp); } update(e: ecs.Entity): void { const line = e.get(DamageLineComp); const caster = e.get(HeroViewComp); // 根据角色朝向调整方向 line.direction = caster.node.scale.x > 0 ? Vec3.RIGHT : new Vec3(-1, 0, 0); // 获取直线区域内的目标 const targets = this.getTargetsInLine( caster.node.worldPosition, line.direction, line.length, line.width, caster.box_group ); // 应用伤害 targets.forEach(target => { }); e.remove(DamageLineComp); } private getTargetsInLine(origin: Vec3, dir: Vec3, length: number, width: number, team: number): ecs.Entity[] { return []; } private isInLine(origin: Vec3, dir: Vec3, target: Vec3, length: number, width: number): boolean { return false; // 临时返回值保持类型安全 // const toTarget = target.subtract(origin); // const projection = Vec3.project(toTarget, dir); } }