import { _decorator,Collider2D ,Contact2DType,v3,IPhysics2DContact,Vec3, tween, math, RigidBody2D, Animation, sp, Tween} from "cc"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { smc } from "../common/SingletonModuleComp"; import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops"; import { GameEvent } from "../common/config/GameEvent"; import { AType, EType, RType, SkillSet } from "../common/config/SkillSet"; import { BoxSet, FacSet } from "../common/config/BoxSet"; import { HeroFac, HeroSet } from "../common/config/heroSet"; import { HeroViewComp } from "../hero/HeroViewComp"; import { BezierMove } from "../BezierMove/BezierMove"; import { FightConComp } from "../map/FightConComp"; import { MonModelComp } from "../hero/MonModelComp"; import { FightSet } from "../common/config/Mission"; import { HeroModelComp } from "../hero/HeroModelComp"; const { ccclass, property } = _decorator; /** 视图层对象 */ @ccclass('SkillCom') @ecs.register('SkillCom') export class SkillCom extends CCComp { s_uuid:number = 0; s_name:string = ""; hero:number = 0; speed:number = 200; scale:number = 1; angle:number = 0; atk_count:number = 0; is_destroy:boolean = false; enemys:any = []; AType: number = 0; // 运动类型 startPos: Vec3 = v3(); // 起始位置 targetPos: Vec3 = v3(); // 目标位置 duration: number = 0; // 技能持续时间 prefabName: string = ""; // 预制体名称 animName: string = ""; group:number = 0; //阵营 fac:number=0; //阵营 caster:any=null; distance_x:number=0; distance_y:number=0; ap:number=0; FIGHTCON:FightConComp=null; run_time:number=0; hited_time:number=0; hit_count:number=0; spine:sp.Skeleton=null; anim:Animation=null; tweenInstance:Tween = null; t_end_x:number=0; caster_crit:number=0; caster_crit_d:number=0; private moveDirection: Vec3 | null = null; // 添加一个属性来存储移动方向 protected onLoad(): void { this.FIGHTCON=this.node.parent.getComponent(FightConComp) } start() { this.node.setPosition(this.startPos.x,this.startPos.y,0) if(this.node.getChildByName('anm')){ this.spine=this.node.getChildByName('anm').getComponent('sp.Skeleton') as sp.Skeleton; }else{ this.anim=this.node.getComponent(Animation) } oops.message.on(GameEvent.MissionEnd, this.doDestroy, this); this.node.active = true; console.log("[SkillCom]:caster",this.caster) let collider = this.getComponent(Collider2D); if(collider) { collider.group = this.group; collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this); } // console.log(this.group +"技能 collider ",collider); switch(SkillSet[this.s_uuid].AType){ case AType.parabolic: this.node.angle +=10 let bm=this.node.getComponent(BezierMove) // bm.speed=700 if(this.group==BoxSet.MONSTER) bm.controlPointSide=-1 bm.moveTo(this.targetPos) break; case AType.linear: // this.distance_x=SkillSet[this.s_uuid].in*this.speed // this.t_end_x =400 // if(this.group==BoxSet.MONSTER){ // this.t_end_x=-400 // this.node.scale=v3(this.node.scale.x*-1,1,1) // } // this.tweenInstance = tween(this.node).to(SkillSet[this.s_uuid].in, { position:v3(this.t_end_x,this.node.position.y,0)},{ // onComplete: (target?: object) => { // // this.node.setPosition(tx,this.node.position.y-300,0) // } // }).start() break; case AType.fixedStart: break; case AType.fixedEnd: this.node.setPosition(this.targetPos.x,this.targetPos.y,0) if(this.node.getComponent(Animation)){ let anim = this.node.getComponent(Animation); console.log("[SkillCom]:has anim",anim) anim.on(Animation.EventType.FINISHED, this.onAnimationFinished, this); } if(this.node.getChildByName('anm')){ if(this.node.getChildByName('anm').getComponent('sp.Skeleton')){ console.log("[SkillCom]:has spine",this.spine) this.spine.setCompleteListener((trackEntry) => { this.onAnimationFinished() console.log("[SkillCom]:[track %s][animation %s] complete: %s", trackEntry.trackIndex); }); } } break; } } onAnimationFinished(){ if(SkillSet[this.s_uuid].EType==EType.timeEnd) return this.is_destroy=true } //范围伤害 range_damage(){ this.hit_count++ let enemys=ecs.query(ecs.allOf(MonModelComp)) if(this.fac==FacSet.MON) enemys=ecs.query(ecs.allOf(HeroModelComp)) enemys.forEach(entity => { let view=entity.get(HeroViewComp) if(view){ let dis =Math.abs(this.node.position.x-view.node.position.x) if(dis > SkillSet[this.s_uuid].with) return this.single_damage(view) } }); } //单体伤害 single_damage(target:HeroViewComp){ this.hit_count++ console.log("[SkillCom]:onBeginContact hit_count:",this.hit_count,SkillSet[this.s_uuid].hit) if(this.hit_count>=SkillSet[this.s_uuid].hit) this.is_destroy=true // 技能命中次数 if(target == null) return; target.do_atked(this.ap,this.caster_crit,this.caster_crit_d) // ap 及暴击 属性已经在skill.ts 处理 if(SkillSet[this.s_uuid].debuff>0){ let deUP =this.get_debuff() // 因为不是每个技能都需要,debuff的增益在这里处理, ap 及暴击 属性已经在skill.ts 处理 let debuff=SkillSet[this.s_uuid] let dev=debuff.deV*(100+deUP.deV)/100 let deR=debuff.deR+deUP.deR dev=Math.round(dev*100)/100 let deC=debuff.deC+deUP.deC //dec只作为次数叠加 console.log("[SkillCom]:debuff",SkillSet[this.s_uuid].name,debuff.debuff,deUP.deV,deUP.deC) target.add_debuff(debuff.debuff,dev,deC,deR) } } onBeginContact (seCol: Collider2D, oCol: Collider2D) { // console.log(this.scale+"碰撞开始 ",seCol,oCol); let target = oCol.getComponent(HeroViewComp) if(oCol.group!=this.group){ if(target == null) return; this.single_damage(target) // this.ent.destroy() } } get_debuff(){ //debuff 加成 let debuff = {deV:0,deC:0,deR:0} let buff=null if(this.caster.is_master) buff = this.FIGHTCON.hero_buff if(this.caster.is_friend) buff = this.FIGHTCON.friend_buff if(this.caster.is_boss||this.caster.is_kalami) buff = this.FIGHTCON.enemy_buff if(buff==null) return debuff debuff.deV=buff.DEBUFF_VALUE debuff.deC=buff.DEBUFF_COUNT debuff.deR=buff.DEBUFF_UP return debuff } private startLinearMove(dt: number) { if (!this.speed || this.is_destroy) return; // 使用角度方向移动 const newX = this.node.position.x + this.speed * dt; const newY = this.node.position.y; this.node.setPosition(newX, this.node.position.y, this.node.position.z); // 检查是否超出边界 if (newX < -400 || newX > 400) { this.is_destroy = true; } } update(deltaTime: number) { let config=SkillSet[this.s_uuid] if(smc.mission.pause) { if(this.spine) this.spine.paused=true if(this.anim) this.anim.pause() return; } if(this.anim) this.anim.resume() if(this.spine) this.spine.paused=false if (!this.node || !this.node.isValid) return; if(config.EType==EType.timeEnd){ this.run_time+=deltaTime if(this.run_time>config.in){ console.log("[SkillCom]: timeEnd destroy",this.s_uuid,this.run_time) this.is_destroy=true } } //范围伤害 this.hited_time+=deltaTime if(this.hited_time>config.hited&&this.hit_count == 0&&(config.EType==EType.animationEnd||config.EType==EType.timeEnd)){ this.hited_time=0 this.range_damage() } //直线移动 if(this.AType == AType.linear) this.startLinearMove(deltaTime); this.toDestroy(); } toDestroy() { if(this.is_destroy){ if (this.ent) { this.ent.destroy(); } else { // 如果ent不存在,直接销毁节点 if (this.node && this.node.isValid) { this.node.destroy(); } } } } doDestroy(){ // console.log("[SkillCom]:doDestroy") this.is_destroy=true } to_console(value:any,value2:any=null,value3:any=null){ console.log("[SkillCom]:["+this.s_name+this.s_uuid+"]:",value,value2,value3) } /** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */ reset() { this.is_destroy = false; this.AType = 0; this.speed = 0; this.startPos.set(); this.targetPos.set(); this.moveDirection = null; // 重置移动方向 // 先移除所有碰撞回调 const collider = this.getComponent(Collider2D); if (collider) { collider.off(Contact2DType.BEGIN_CONTACT); } this.scheduleOnce(() => { this.node.destroy(); }, 0); } }