188 lines
5.4 KiB
TypeScript
188 lines
5.4 KiB
TypeScript
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<ecs.Entity> 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);
|
|
}
|
|
}
|
|
|
|
|
|
|