Files
heros/assets/script/game/skill/SkillView.ts
walkpan 1091b0399e fix: 修复技能碰撞检测和英雄prefab配置问题
修复技能碰撞检测逻辑,确保正确应用伤害并过滤同组碰撞
调整多个英雄prefab的_enabled状态和碰撞组配置
优化技能视图的日志输出和伤害应用逻辑
移除不必要的prefab组件和调试日志
2025-11-01 23:10:38 +08:00

136 lines
5.9 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, Animation, CCInteger, Collider2D, Contact2DType, UITransform, v3, Vec3 } 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 { HeroViewComp } from "../hero/HeroViewComp";
import { DTType, EType, RType, SkillConfig, SkillSet } from "../common/config/SkillSet";
import { BoxSet, FacSet } from "../common/config/BoxSet";
import { SDataCom } from "./SDataCom";
import { SMoveDataComp } from "./SMoveComp";
import { Attrs } from "../common/config/HeroAttrs";
import { MonMoveComp } from "../hero/MonMove";
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
import { HeroMoveComp } from "../hero/HeroMove";
import { DamageQueueHelper } from "../hero/DamageQueueComp";
const { ccclass, property } = _decorator;
/** 视图层对象 */
@ccclass('SkillView')
@ecs.register('SkillView', false)
export class SkillView extends CCComp {
/** 视图层逻辑代码分离演示 */
@property({ type: CCInteger })
atk_x: number = 0
@property({ type: CCInteger })
atk_y: number = 0
anim:Animation=null;
group:number=0;
SConf:SkillConfig=null;
sData:SDataCom=null;
s_uuid:number=1001
start() {
this.SConf = SkillSet[this.s_uuid]
this.sData=this.ent.get(SDataCom)
this.anim=this.node.getComponent(Animation)
this.node.active = true;
let collider = this.getComponent(Collider2D);
if(collider) {
collider.group = this.group;
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
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);
}
}
onBeginContact (seCol: Collider2D, oCol: Collider2D) {
if(oCol.group==this.group) return
if (!this.SConf) return;
if(this.SConf.EType!=EType.collision) return
let target = oCol.getComponent(HeroViewComp)
if(target == null) return;
let model=target.ent.get(HeroAttrsComp)
if(!model) return
if(model.is_dead) 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.apply_damage(target)
}
onAnimationFinished(){
if(this.SConf.EType==EType.animationEnd){
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);
}
});
// 根据配置的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;
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(
target.ent,
this.sData.Attrs,
this.sData.caster,
this.sData.s_uuid
);
// 更新技能命中次数
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// 技能命中次数
}
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
reset() {
this.node.destroy();
}
}