@@ -30,7 +30,6 @@ export class SkillView extends CCComp {
sData :SDataCom = null ;
s_uuid :number = 1001
// 已命中目标追踪,防止重复伤害
private hitTargets : Set < string > = new Set ( ) ;
start() {
this . SConf = SkillSet [ this . s_uuid ]
this . sData = this . ent . get ( SDataCom )
@@ -49,24 +48,28 @@ export class SkillView extends CCComp {
}
onBeginContact ( seCol : Collider2D , oCol : Collider2D ) {
const targetId = oCol . uuid ;
if ( this . hitTargets . h as( targetId ) ) return ; // 已经命中过,跳过
// 记录命中目标
// if (!this.SConf) return;
// if(this.SConf.EType!=EType.collision) return
if ( oCol . group == seCol . group ) return
let target = oCol . getComponent ( HeroViewComp )
if ( target == null ) return ;
let model = target . ent . get ( HeroAttrsComp )
console . log ( ` [skillView] 碰撞3 ` , oCol . group , seCol . group , model ) ;
if ( model == null ) return
if ( mode l. is_dead ) return
if ( this . sData . fac == model . fac ) return ;
// 检查是否已经命中过这个目标
console . log ( ` [skillView] 碰撞5[ ${ this . sData . caster . box_group } ][ ${ this . sData . caster . ent . get ( HeroAttrsComp ) . hero_name } ][ ${ this . sData . caster . ent . eid } ]的[ ${ this . group } ] [ ${ this . SConf . name } ]碰撞了 [ ${ oCol . group } ][ ${ oCol . getComponent ( HeroViewComp ) . ent . get ( HeroAttrsComp ) . hero_name } ][ ${ oCol . getComponent ( HeroViewComp ) . ent . eid } ] ` ) ;
this . hitTargets . add ( targetId ) ;
this . apply_damage ( target )
// 安全获取双方信息用于日志
const casterName = this . sData . c aster ? . ent ? . get ( HeroAttrsComp ) ? . hero_name ? ? '未知施法者' ;
const casterEid = this . sData . caster ? . ent ? . eid ? ? '未知EID' ;
const targetView = oCol . getComponent ( HeroViewComp ) ;
const targetName = targetView ? . ent ? . get ( HeroAttrsComp ) ? . hero_name ? ? '非英雄对象' ;
const targetEid = targetView ? . ent ? . eid ? ? '未知EID' ;
console . log ( ` [skillView] 碰撞1 [ ${ this . sData . caster . box_group } ][ ${ casterName } ][ ${ casterEid } ]的[ ${ seCol . group } ]:[ ${ this . SConf . name } ][ ${ this . ent . eid } ]碰撞了 [ ${ oCol . group } ]:[ ${ targetName } ][ ${ targetEid } ] ` ) ;
// 基本空值与同组过滤
if ( ! this . sData || ! this . SConf ) {
console . warn ( '[SkillView] onBeginContact 缺少 sData 或 SConf, 忽略此次碰撞' ) ;
return ;
}
if ( oCo l. group === seCol . group ) return ;
// 不是 HeroViewComp, 直接忽略
if ( ! targetView ) return ;
let model = targetView . ent . get ( HeroAttrsComp ) ;
// console.log(`[skillView] 碰撞3`, oCol.group, seCol.group, model);
if ( ! model ) return ;
if ( model . is_dead ) return ;
if ( this . sData . fac == model . fac ) return ;
// 检查是否已经命中过这个目标(日志安全输出)
this . apply_damage ( targetView )
}
onAnimationFinished ( ) {
@@ -74,70 +77,59 @@ export class SkillView extends CCComp {
this . ent . destroy ( )
}
}
//动画帧事件 atk 触发
public atk( args :any ) {
let dis = this . node . getComponent( UITransform) . width / 2
let enemys :any = [ ]
if( this . sData . fac == FacSet . HERO ) {
enemys= ecs . query ( ecs . allOf ( MonMoveComp) )
} else {
enemys= ecs . query ( ecs . allOf ( HeroMoveComp) )
}
let IRTargets : HeroViewComp[ ] = [ ]
// 收集范围内所有敌方目标
enemys. some ( e = > {
const view = e . get ( HeroViewComp) ;
const model= e . get ( HeroAttrsComp)
const distance = Math . abs ( this . node . position . x - view . node . position . x ) ;
if( distance <= dis && ! model . is_dead ) {
IRTargets. push ( view ) ;
}
// // 动画帧事件 atk 触发
// public atk(args:any){
// let dis=this.node. getComponent( UITransform).width/2
// let enemys:any=[]
// if( this.sData.fac==FacSet.HERO){
// enemys=ecs.query(ecs.allOf( MonMoveComp))
// }else{
// enemys=ecs.query(ecs.allOf( HeroMoveComp))
// }
// let IRTargets: HeroViewComp[] = []
// // 收集范围内所有敌方目标
// enemys.some(e => {
// const view = e.get( HeroViewComp);
// const model=e.get( HeroAttrsComp)
// const distance = Math.abs(this.node.position.x - view.node.position.x);
// if( distance <= dis&&!model.is_dead) {
// IRTargets.push(view);
// }
} ) ;
// 根据配置的hit_num决定攻击模式
const hitNum = SkillSet[ this . s_uuid ] . hit_num || 0 ;
if( hitNum > 0 ) {
// 限制目标数量: 按距离排序, 选择最近的N个目标
if( IRTargets. length > 0 ) {
// 按距离排序(从近到远)
IRTargets. sort ( ( a , b ) = > {
const distanceA = Math . abs ( this . node . position . x - a . node . position . x ) ;
const distanceB = Math . abs ( this . node . position . x - b . node . position . x ) ;
return distanceA - distanceB;
} ) ;
// 限制目标数量
const maxTargets = Math . min ( hitNum , IRTargets. length) ;
const sTargets = IRTargets. slice ( 0 , maxTargets) ;
sTargets. forEach( target = > {
this. apply_damage( target, false ) ;
} ) ;
}
} else {
// 范围伤害:对所有范围内目标造成伤害
if( IRTargets. length > 0 ) {
IRTargets. forEach( target = > {
this. apply_damage( target, true ) ;
} ) ;
}
}
}
// });
// // 根据配置的hit_num决定攻击模式
// const hitNum = SkillSet[this.s_uuid].hit_num || 0;
// if( hitNum > 0) {
// // 限制目标数量: 按距离排序, 选择最近的N个目标
// if( IRTargets. length > 0) {
// // 按距离排序(从近到远)
// IRTargets.sort((a, b) => {
// const distanceA = Math.abs(this.node.position.x - a.node.position.x);
// const distanceB = Math.abs(this.node.position.x - b.node.position.x);
// return distanceA - distanceB;
// });
// // 限制目标数量
// const maxTargets = Math.min(hitNum, IRTargets. length);
// const sTargets = IRTargets.slice(0, maxTargets);
// sTargets. forEach( target => {
// this. apply_damage( target, false);
// });
// }
// } else {
// // 范围伤害:对所有范围内目标造成伤害
// if( IRTargets. length > 0) {
// IRTargets. forEach( target => {
// this. apply_damage( target, true);
// });
// }
// }
// }
//伤害应用
apply_damage ( target :HeroViewComp , is_range :boolean = false ) {
if ( target == null ) return ;
if ( ! this . SConf ) return ;
// 检查是否已经命中过这个目标(除非是范围伤害)
const targetId = target . node . uuid ;
if ( ! is_range && this . hitTargets . has ( targetId ) ) {
return ; // 已经命中过,跳过
}
// 记录命中目标(除非是范围伤害)
if ( ! is_range ) {
this . hitTargets . add ( targetId ) ;
}
console . log ( ` [skillView] 伤害 [ ${ this . group } ][ ${ this . sData . caster . ent . get ( HeroAttrsComp ) . hero_name } ][ ${ this . sData . caster . ent . eid } ]的 [ ${ this . SConf . name } ]对 [ ${ target . box_group } ][ ${ target . ent . get ( HeroAttrsComp ) . hero_name } ][ ${ target . ent . eid } ] ` ) ;
// console.log(`[skillView] 伤害 [${this.group}][${this.sData.caster.ent.get(HeroAttrsComp).hero_name}][${this.sData.caster.ent.eid}]的 [${this.SConf.name}]对 [${target.box_group}][ ${target.ent.get(HeroAttrsComp).hero_name}][${target.ent.eid}]`);
// if(this.sData.hit_count > this.SConf.hit_num) return 不能超出 最大伤害数量
// 使用伤害队列系统处理伤害
DamageQueueHelper . addDamageToEntity (
@@ -149,10 +141,21 @@ export class SkillView extends CCComp {
// 更新技能命中次数
this . sData . hit_count ++
// 检查技能是否应该销毁
if ( this . sData . hit_count >= ( this . SConf . hit + this . sData . Attrs [ Attrs . PUNCTURE ] ) && ( this . SConf . DTType != DTType . range ) && ( this . SConf . EType != EType . animationEnd ) && ( this . SConf . EType != EType . timeEnd ) ) this . ent . destroy // 技能命中次数
if (
this . sData . hit_count >= ( this . SConf . hit + this . sData . Attrs [ Attrs . PUNCTURE ] ) &&
( this . SConf . DTType != DTType . range ) &&
( this . SConf . EType != EType . animationEnd ) &&
( this . SConf . EType != EType . timeEnd )
) {
this . ent . destroy ( ) ; // 技能命中次数达到上限后销毁
}
}
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
reset() {
const collider = this . getComponent ( Collider2D ) ;
if ( collider ) {
collider . off ( Contact2DType . BEGIN_CONTACT ) ;
}
this . node . destroy ( ) ;
}
}