fix: 修复技能节点池逻辑并调整UI显示

- 修复技能节点池获取和回收时的有效性检查,避免无效节点
- 修复技能父节点查找逻辑,增加空值检查
- 调整卡牌UI的文本样式和宽度
- 启用SkillView调试日志以便问题排查
- 修复英雄后撤动画逻辑,取消注释
- 更新加载页面资源引用
This commit is contained in:
panw
2026-03-12 15:58:25 +08:00
parent 01bff64561
commit 9d86be80c7
6 changed files with 2092 additions and 1911 deletions

View File

@@ -2901,7 +2901,7 @@
"a": 255 "a": 255
}, },
"_spriteFrame": { "_spriteFrame": {
"__uuid__": "6165ffc9-a838-4a33-b569-bdbaaab0e6b4@7a4bc", "__uuid__": "6165ffc9-a838-4a33-b569-bdbaaab0e6b4@ec5a5",
"__expectedType__": "cc.SpriteFrame" "__expectedType__": "cc.SpriteFrame"
}, },
"_type": 0, "_type": 0,
@@ -3003,7 +3003,7 @@
}, },
"_contentSize": { "_contentSize": {
"__type__": "cc.Size", "__type__": "cc.Size",
"width": 15.123046875, "width": 17.90380859375,
"height": 35.5 "height": 35.5
}, },
"_anchorPoint": { "_anchorPoint": {
@@ -3042,8 +3042,8 @@
"_string": "3", "_string": "3",
"_horizontalAlign": 1, "_horizontalAlign": 1,
"_verticalAlign": 1, "_verticalAlign": 1,
"_actualFontSize": 20, "_actualFontSize": 25,
"_fontSize": 20, "_fontSize": 25,
"_fontFamily": "Arial", "_fontFamily": "Arial",
"_lineHeight": 25, "_lineHeight": 25,
"_overflow": 0, "_overflow": 0,
@@ -3052,7 +3052,7 @@
"_isSystemFontUsed": true, "_isSystemFontUsed": true,
"_spacingX": 0, "_spacingX": 0,
"_isItalic": false, "_isItalic": false,
"_isBold": false, "_isBold": true,
"_isUnderline": false, "_isUnderline": false,
"_underlineHeight": 2, "_underlineHeight": 2,
"_cacheMode": 0, "_cacheMode": 0,

View File

@@ -172,7 +172,10 @@
"b": 0, "b": 0,
"a": 134 "a": 134
}, },
"_spriteFrame": null, "_spriteFrame": {
"__uuid__": "d7d869bc-06aa-4876-806f-487e68b96780@dc000",
"__expectedType__": "cc.SpriteFrame"
},
"_type": 1, "_type": 1,
"_fillType": 0, "_fillType": 0,
"_sizeMode": 0, "_sizeMode": 0,
@@ -186,7 +189,7 @@
"_isTrimmedMode": true, "_isTrimmedMode": true,
"_useGrayscale": false, "_useGrayscale": false,
"_atlas": { "_atlas": {
"__uuid__": "fbfc0bb3-1ab9-4b38-8173-112c0ac3e4eb", "__uuid__": "d7d869bc-06aa-4876-806f-487e68b96780",
"__expectedType__": "cc.SpriteAtlas" "__expectedType__": "cc.SpriteAtlas"
}, },
"_id": "" "_id": ""

File diff suppressed because it is too large Load Diff

View File

@@ -460,16 +460,16 @@ export class HeroViewComp extends CCComp {
.start() .start()
} }
// if(this.model.fac==FacSet.HERO) { if(this.model.fac==FacSet.HERO) {
// let tx=this.node.position.x-5 let tx=this.node.position.x-5
// if(tx < -320) tx=-320 if(tx < -320) tx=-320
// tween(this.node) tween(this.node)
// .to(0.1, { position:v3(tx,this.node.position.y,0)}) .to(0.1, { position:v3(tx,this.node.position.y,0)})
// .call(() => { .call(() => {
// this.isBackingUp = false; // 🔥 动画完成后重置状态 this.isBackingUp = false; // 🔥 动画完成后重置状态
// }) })
// .start() .start()
// } }
} }
// 伤害计算和战斗逻辑已迁移到 HeroBattleSystem // 伤害计算和战斗逻辑已迁移到 HeroBattleSystem

View File

@@ -22,14 +22,18 @@ export class Skill extends ecs.Entity {
static getFromPool(path: string): Node | null { static getFromPool(path: string): Node | null {
if (this.pools.has(path)) { if (this.pools.has(path)) {
const pool = this.pools.get(path)!; const pool = this.pools.get(path)!;
if (pool.size() > 0) { while (pool.size() > 0) {
return pool.get(); const node = pool.get();
if (node && node.isValid) {
return node;
}
} }
} }
return null; return null;
} }
static putToPool(path: string, node: Node) { static putToPool(path: string, node: Node) {
if (!node || !node.isValid) return;
if (!this.pools.has(path)) { if (!this.pools.has(path)) {
this.pools.set(path, new NodePool()); this.pools.set(path, new NodePool());
} }
@@ -72,10 +76,29 @@ export class Skill extends ecs.Entity {
return; return;
} }
const node: Node = Skill.getFromPool(path) || instantiate(prefab); const node: Node = Skill.getFromPool(path) || instantiate(prefab);
if (!node || !node.isValid) {
mLogger.error(this.debugMode, 'Skill', "[Skill] 节点无效:", path);
return;
}
this.prefabPath = path; this.prefabPath = path;
this.skillNode = node; this.skillNode = node;
var scene = smc.map.MapView.scene;
node.parent = scene.entityLayer!.node!.getChildByName("SKILL") || parent; let skillParent: Node | null = null;
if (smc.map && smc.map.MapView && smc.map.MapView.scene && smc.map.MapView.scene.entityLayer && smc.map.MapView.scene.entityLayer.node) {
skillParent = smc.map.MapView.scene.entityLayer.node.getChildByName("SKILL");
}
if (!skillParent || !skillParent.isValid) {
skillParent = parent;
}
if (!skillParent || !skillParent.isValid) {
mLogger.error(this.debugMode, 'Skill', "[Skill] 父节点无效");
if(node.isValid) node.destroy();
return;
}
node.parent = skillParent;
// 设置节点属性 // 设置节点属性
let face=caster.node.scale.x < 0 ? -1 : 1 let face=caster.node.scale.x < 0 ? -1 : 1
node.setScale(v3(node.scale.x*face,node.scale.y,1)) node.setScale(v3(node.scale.x*face,node.scale.y,1))

View File

@@ -22,7 +22,7 @@ export class SkillView extends CCComp {
atk_y: number = 0 atk_y: number = 0
@property({ tooltip: "是否启用调试日志" }) @property({ tooltip: "是否启用调试日志" })
private debugMode: boolean = false; private debugMode: boolean = true;
anim:Animation=null; anim:Animation=null;
group:number=0; group:number=0;
@@ -105,50 +105,6 @@ export class SkillView extends CCComp {
mLogger.log(this.debugMode, 'SkillView', `[SkillView] [${this.SConf?.name}] 第${this.attackFrameCount}次攻击帧开启碰撞检测`); mLogger.log(this.debugMode, 'SkillView', `[SkillView] [${this.SConf?.name}] 第${this.attackFrameCount}次攻击帧开启碰撞检测`);
} }
// 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){ apply_damage(target:HeroViewComp,is_range:boolean=false){
@@ -156,7 +112,12 @@ export class SkillView extends CCComp {
// 安全检查:如果目标实体已不存在,直接返回 // 安全检查:如果目标实体已不存在,直接返回
if (!target.ent) return; if (!target.ent) return;
if (!this.SConf) return; if (!this.SConf) return;
// 检查技能是否应该销毁
const max_hit_count=this.SConf.hit + this.sData.Attrs[Attrs.puncture]
if ( this.sData.hit_count >= max_hit_count ) {
this.close_collider()
return
}
// 对于非持续碰撞类型的技能,在造成伤害后立即关闭碰撞检测 // 对于非持续碰撞类型的技能,在造成伤害后立即关闭碰撞检测
// 这样可以避免同一帧内的重复伤害 // 这样可以避免同一帧内的重复伤害
if(this.SConf.EType !== EType.collision && this.collider) { if(this.SConf.EType !== EType.collision && this.collider) {
@@ -181,19 +142,23 @@ export class SkillView extends CCComp {
); );
// 更新技能命中次数 // 更新技能命中次数
this.sData.hit_count++ this.sData.hit_count++
// 检查技能是否应该销毁
if ( if (
this.sData.hit_count >= (this.SConf.hit + this.sData.Attrs[Attrs.puncture]) && (this.SConf.DTType != DTType.range) &&
(this.SConf.DTType != DTType.range) && (this.SConf.EType != EType.animationEnd) &&
(this.SConf.EType != EType.animationEnd) && (this.SConf.EType != EType.timeEnd)
(this.SConf.EType != EType.timeEnd) ) {
) { // 修复:物理回调中不能直接销毁刚体,需延迟到下一帧
// 修复:物理回调中不能直接销毁刚体,需延迟到下一帧 this.close_collider();
this.scheduleOnce(() => { this.scheduleOnce(() => {
if (this.ent) { if (this.ent) {
this.ent.destroy(); this.ent.destroy();
} }
}, 0); }, 0);
}
}
close_collider(){
if (this.collider) {
this.collider.enabled = false;
} }
} }
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */ /** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */