fix(hero): 修复英雄视图组件的空指针异常和死亡逻辑

- 添加ent和model的安全检查防止空指针异常
- 重构死亡计时逻辑,使用deadCD代替Timer
- 统一死亡事件触发顺序并添加安全检查
- 在reset方法中清理碰撞器事件和伤害队列
This commit is contained in:
2025-11-03 16:32:30 +08:00
parent c98f20ba1d
commit 04aa5f9c78

View File

@@ -32,12 +32,18 @@ export class HeroViewComp extends CCComp {
box_group:number = BoxSet.HERO; // 碰撞组 box_group:number = BoxSet.HERO; // 碰撞组
usePower:boolean = false; usePower:boolean = false;
useMp:boolean = false; useMp:boolean = false;
deadTime:Timer=new Timer(10) realDeadTime:number=10
deadCD:number=0
// ==================== UI 节点引用 ==================== // ==================== UI 节点引用 ====================
private top_node: Node = null!; private top_node: Node = null!;
// ==================== 直接访问 HeroAttrsComp ==================== // ==================== 直接访问 HeroAttrsComp ====================
get model() { get model() {
// 🔥 修复添加安全检查防止ent为null时的访问异常
if (!this.ent) {
console.warn("[HeroViewComp] ent is null, returning null for model");
return null;
}
return this.ent.get(HeroAttrsComp); return this.ent.get(HeroAttrsComp);
} }
@@ -102,10 +108,15 @@ export class HeroViewComp extends CCComp {
update(dt: number){ update(dt: number){
if(!smc.mission.play || smc.mission.pause) return; if(!smc.mission.play || smc.mission.pause) return;
// 添加安全检查防止在实体销毁过程中访问null的model // 🔥 修复:添加安全检查防止在实体销毁过程中访问null的model
if(!this.ent) return;
if (!this.model) return; if (!this.model) return;
if(this.model.is_dead){ if(this.model.is_dead){
if( this.deadTime.update(dt)) this.realDead() this.deadCD+=dt
if(this.deadCD>=this.realDeadTime){
this.deadCD=0
this.realDead()
}
return return
} ; } ;
// ✅ View 层职责:处理表现相关的逻辑 // ✅ View 层职责:处理表现相关的逻辑
@@ -277,7 +288,6 @@ export class HeroViewComp extends CCComp {
alive(){ alive(){
this.model.is_dead=false this.model.is_dead=false
this.deadTime.reset()
this.as.do_buff(); this.as.do_buff();
this.status_change("idle"); this.status_change("idle");
this.model.hp =this.model.Attrs[Attrs.HP_MAX]*50/100; this.model.hp =this.model.Attrs[Attrs.HP_MAX]*50/100;
@@ -302,20 +312,26 @@ export class HeroViewComp extends CCComp {
} }
realDead(){ realDead(){
// 根据阵营触发不同事件 // 🔥 修复添加model安全检查防止实体销毁过程中的空指针异常
if(this.model.fac === FacSet.MON){ if (!this.model) {
oops.message.dispatchEvent(GameEvent.MonDead, { console.warn("[HeroViewComp] realDead called but model is null, skipping");
hero_uuid: this.model.hero_uuid, return;
position: this.node.position }
});
this.ent.destroy();
}
if(this.model.fac === FacSet.HERO){ if(this.model.fac === FacSet.HERO){
// 英雄死亡:延迟触发死亡事件 // 英雄死亡:延迟触发死亡事件
oops.message.dispatchEvent(GameEvent.HeroDead, { oops.message.dispatchEvent(GameEvent.HeroDead, {
hero_uuid: this.model.hero_uuid hero_uuid: this.model.hero_uuid
}); });
} }
// 根据阵营触发不同事件
if(this.model.fac === FacSet.MON){
oops.message.dispatchEvent(GameEvent.MonDead, {
hero_uuid: this.model.hero_uuid,
position: this.node.position
});
}
this.ent.destroy();
} }
do_atked(damage:number,isCrit:boolean,s_uuid:number){ do_atked(damage:number,isCrit:boolean,s_uuid:number){
if (damage <= 0) return; if (damage <= 0) return;
@@ -426,11 +442,18 @@ export class HeroViewComp extends CCComp {
} }
} }
reset() { reset() {
// 清理碰撞器事件监听
const collider = this.getComponent(Collider2D); const collider = this.getComponent(Collider2D);
if (collider) { if (collider) {
collider.off(Contact2DType.BEGIN_CONTACT); collider.off(Contact2DType.BEGIN_CONTACT);
} }
this.deadTime.reset() this.deadCD=0
// 清理伤害队列
this.damageQueue.length = 0;
this.isProcessingDamage = false;
// 延迟销毁节点
this.scheduleOnce(() => { this.scheduleOnce(() => {
this.node.destroy(); this.node.destroy();
}, 0.1); }, 0.1);