Files
heros/assets/script/game/hero/SkillConComp.ts
panw 22726eed3b fix(skills): 修正技能预制体锚点并添加调试日志
- 将atk1和atk2技能预制体的锚点y值从0.5改为0
- 在SkillConComp中加载技能时添加uuid为6001时的起始坐标日志输出
- 在Skill加载函数中,uuid为6001时输出加载起始坐标日志
- 在SkillCom组件中,uuid为6001时输出起始位置日志
- 删除HeroPageComp中load_hero函数的实现内容,保留函数体
- 修正Skill加载时节点父级赋值逻辑,确保正确设置父节点
2025-10-13 13:27:40 +08:00

237 lines
8.4 KiB
TypeScript
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.

import { _decorator, Component, Node, ProgressBar, v3, Vec3 } from 'cc';
import { HeroViewComp } from './HeroViewComp';
import { BuffAttr, CdType, DTType, SKILL_CONST, SkillSet, SType, TGroup, TType } from '../common/config/SkillSet';
import { Skill } from '../skills/Skill';
import { ecs } from 'db://oops-framework/libs/ecs/ECS';
import { oops } from 'db://oops-framework/core/Oops';
import { GameEvent } from '../common/config/GameEvent';
import { BoxSet, FacSet } from '../common/config/BoxSet';
import { smc } from '../common/SingletonModuleComp';
import { CCComp } from 'db://oops-framework/module/common/CCComp';
import { MonModelComp } from './MonModelComp';
import { HeroModelComp } from './HeroModelComp';
import { FightSet } from '../common/config/Mission';
import { Timer } from 'db://oops-framework/core/common/timer/Timer';
const { ccclass, property } = _decorator;
@ccclass('SkillCon')
@ecs.register('SkillCon')
export class SkillConComp extends CCComp {
HeroView:any=null;
HeroEntity:any=null;
skill_cd=0
private _timers: { [key: string]: any } = {};
init(): void {
this.on(GameEvent.FightEnd, this.clear_timer, this);
}
onLoad(){
this.HeroView=this.node.getComponent(HeroViewComp)
// //console.log(this.HeroView.uid+"=>"+this.HeroView.hero_name+"=> SkillConComp onLoad")
}
start() {
// //console.log(this.HeroView.uuid+"=>"+this.HeroView.hero_name+"=> SkillConComp start")
this.HeroEntity=this.HeroView.ent
}
update(dt: number) {
if(!smc.mission.play||smc.mission.pause) return
if(this.HeroView.DEBUFF_STUN <= 0&&this.HeroView.DEBUFF_FROST <= 0) {
let skills=this.HeroView.skills
for(let i=0;i<skills.length;i++){
if(SkillSet[skills[i].uuid].CdType==CdType.cd) {
skills[i].cd += dt;
if(skills[i].cd > (i==0?this.HeroView.Attrs[BuffAttr.ATK_CD]:skills[i].cd_max)){
if(SkillSet[skills[i].uuid].SType==SType.damage&&this.HeroView.is_atking){
this.castSkill(SkillSet[skills[i].uuid])
this.HeroView.skills[i].cd = 0
}
}
}
}
if(skills[1]){
if(this.HeroView.fac==FacSet.HERO) {
// console.log("[SkillConComp] 角色状态:",this.HeroView.hero_name+"=>能量:"+this.HeroView.power+"/"+this.HeroView.power_max,skills)
}
this.HeroView.power+=(1+this.HeroView.Attrs[BuffAttr.POWER_UP])*dt*SKILL_CONST.POWER_UP
let progress=this.HeroView.power/this.HeroView.power_max
this.HeroView.node.getChildByName("top").getChildByName("pow").getComponent(ProgressBar).progress=progress
if(this.HeroView.power>this.HeroView.power_max){
this.HeroView.power=0
}
}else{
if(this.HeroView.fac==FacSet.HERO) {
}
}
}
}
/** 施放技能 */
castSkill(config: typeof SkillSet[keyof typeof SkillSet]) {
// //console.log(view.uuid+"=>"+view.hero_name+"施放技能:"+config.uuid);
let wfuny=this.check_wfuny()
let dmg=0
this.doSkill(config,wfuny,dmg);
}
private doSkill(config: typeof SkillSet[keyof typeof SkillSet],is_wfuny:boolean=false,dmg:number=0) {
// 添加节点有效性检查
if (!this.node || !this.node.isValid || !this.HeroView || !this.HeroView.node || !this.HeroView.node.isValid) {
return;
}
let target:any=null
switch(config.TGroup){
case TGroup.Enemy: //单个敌人
target = this.filterFrontRow()
break
case TGroup.Ally: //所有敌人
target = this.selectAllyTargets()
break
case TGroup.Self: //自身
target = this.node.position
break
case TGroup.Team: //所有友方
target = this.node.position
break
case TGroup.All: //所有单位
break
}
this.HeroView.playSkillEffect(config.uuid)
const skillEntity = ecs.getEntity<Skill>(Skill);
const timerId = setTimeout(() => {
// 再次检查节点有效性
if (!this.node || !this.node.isValid || !this.HeroView || !this.HeroView.node || !this.HeroView.node.isValid) {
return;
}
if(config.uuid==6001){
console.log("[SkillConComp] 技能起始坐标:",this.HeroView.node.position.x + BoxSet.ATK_X * this.HeroView.scale,this.HeroView.node.position.y + BoxSet.ATK_Y,0)
}
skillEntity.load(
new Vec3(this.HeroView.node.position.x + BoxSet.ATK_X * this.HeroView.scale,
this.HeroView.node.position.y + BoxSet.ATK_Y, 0),
this.node.parent,
config.uuid,
new Vec3(target.x, target.y+BoxSet.ATK_Y, 0),
this.HeroView,
0,
dmg
);
}, 300);
if(is_wfuny){
this.scheduleOnce(()=>{
this.HeroView.ex_show("blue")
this.doSkill(config,false,dmg)
},0.1)
}
// 保存定时器ID
this._timers[`skill_${config.uuid}`] = timerId;
}
check_wfuny(){
let random = Math.random()*100
if(random < this.HeroView.Attrs[BuffAttr.WFUNY]){
return true
}
return false
}
check_target(){
if(this.HeroView.fac==FacSet.HERO){
return ecs.query(ecs.allOf(MonModelComp))
}else{
return ecs.query(ecs.allOf(HeroModelComp))
}
}
get_front(entities:any){
let keyPos = this.HeroView.fac==FacSet.HERO ?
Math.min(...entities.map(e => e.get(HeroViewComp).node.position.x)) :
Math.max(...entities.map(e => e.get(HeroViewComp).node.position.x));
let keyEntity = entities.find(e => e.get(HeroViewComp).node.position.x === keyPos);
return keyEntity.get(HeroViewComp).node.position;
}
/** 筛选最前排单位 */
private filterFrontRow(): Vec3{
// 敌方最前排是x坐标最大的我方最前排是x坐标最小的,若目标不存在,敌人 取400,我方取-400
let pos=v3(0,0)
let entities=this.check_target()
if(entities.length==0){
if(this.HeroView.fac==FacSet.HERO){
return v3(400,0)
}else{
return v3(-400,0)
}
}
pos=v3(this.get_front(entities))
return pos
}
private selectAllyTargets( ): Vec3 {
// 敌方最前排是x坐标最大的+50我方最前排是x坐标最小的+50,若目标不存在,敌人 取320/2,我方取-320/2
let kp=50
if(this.HeroView.fac==FacSet.MON) kp=0
let pos=v3(0,0)
let entities=this.check_target()
if(entities.length==0){
if(this.HeroView.fac==FacSet.HERO){
return v3(320/2+kp,0)
}else{
return v3(-320/2-kp,0)
}
}
pos=v3(this.get_front(entities).x+kp,this.get_front(entities).y-BoxSet.ATK_Y,0)
return pos
}
/** 随机选择目标 */
private pickRandomTarget(count: number): ecs.Entity[] {
let entities:any=null
if(this.HeroView.fac==FacSet.HERO){
entities = ecs.query(ecs.allOf(MonModelComp))
}else{
entities = ecs.query(ecs.allOf(HeroModelComp))
}
const shuffled = [...entities].sort(() => 0.5 - Math.random());
return shuffled.slice(0, count);
}
public clear_timer() {
// console.log("[SkillConComp]:clear_timer",this.HeroView);
Object.values(this._timers).forEach(clearTimeout);
}
get_count(count:number,view:HeroViewComp){
let re=count+view.wfuny
if(re<1) re=1
return re
}
reset() {
this.clear_timer();
}
onDestroy() {
// 清理所有定时器
// console.log("[SkillConComp]:onDestroy:",this.node.name)
Object.values(this._timers).forEach(clearTimeout);
this._timers = {};
// 移除事件监听
this.off(GameEvent.CastHeroSkill);
}
}