From 781e88e2d70b4306c1c867a580782915ea46e192 Mon Sep 17 00:00:00 2001 From: panw Date: Thu, 2 Apr 2026 16:40:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=8D=A1=E7=89=8C?= =?UTF-8?q?=E7=AD=89=E7=BA=A7=E7=B3=BB=E7=BB=9F=E5=B9=B6=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E8=8B=B1=E9=9B=84=E5=90=88=E6=88=90=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 HeroAttrsComp 中添加 card_lv 属性,用于独立记录卡牌等级 - 修改 Hero 加载逻辑,支持传入 card_lv 参数 - 更新 HInfoComp 的 UI 刷新逻辑,根据英雄等级和卡牌等级显示不同的边框和等级图标 - 调整 MissionHeroComp 的合成规则:所需合成数量从 2 改为 3,最高合成等级从 3 改为 2 - 在召唤队列和合成流程中传递并处理 card_lv 数据,确保卡牌等级在合成过程中得以保留 --- assets/script/game/hero/Hero.ts | 3 +- assets/script/game/hero/HeroAttrsComp.ts | 1 + assets/script/game/map/CardComp.ts | 3 +- assets/script/game/map/HInfoComp.ts | 25 +++++++------- assets/script/game/map/MissionCardComp.ts | 1 + assets/script/game/map/MissionHeroComp.ts | 40 ++++++++++++----------- 6 files changed, 41 insertions(+), 32 deletions(-) diff --git a/assets/script/game/hero/Hero.ts b/assets/script/game/hero/Hero.ts index 1221ec3f..a74f4582 100644 --- a/assets/script/game/hero/Hero.ts +++ b/assets/script/game/hero/Hero.ts @@ -63,7 +63,7 @@ export class Hero extends ecs.Entity { * 2) 初始化表现与属性数据 * 3) 播放下落入场并在落地后启用碰撞与移动 */ - load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001, dropToY:number = pos.y,hero_lv:number=1) { + load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001, dropToY:number = pos.y,hero_lv:number=1, card_lv:number=1) { // 英雄始终朝右,表现缩放固定为正向 scale = 1 // 英雄等级在当前规则下上限为 3,避免超配表范围 @@ -98,6 +98,7 @@ export class Hero extends ecs.Entity { model.hero_uuid = uuid; model.hero_name = hero.name; model.lv = hero_lv; + model.card_lv = card_lv; model.type = hero.type; model.fac = FacSet.HERO; diff --git a/assets/script/game/hero/HeroAttrsComp.ts b/assets/script/game/hero/HeroAttrsComp.ts index ee95232c..2efddcac 100644 --- a/assets/script/game/hero/HeroAttrsComp.ts +++ b/assets/script/game/hero/HeroAttrsComp.ts @@ -14,6 +14,7 @@ export class HeroAttrsComp extends ecs.Comp { hero_uuid: number = 1001; hero_name: string = "hero"; lv: number = 1; + card_lv: number = 1; type: number = 0; // 0近战 1远程 2辅助 fac: number = 0; // 0:hero 1:monster // ==================== 基础属性(有初始值) ==================== diff --git a/assets/script/game/map/CardComp.ts b/assets/script/game/map/CardComp.ts index e9d9cf47..6655673f 100644 --- a/assets/script/game/map/CardComp.ts +++ b/assets/script/game/map/CardComp.ts @@ -192,7 +192,8 @@ export class CardComp extends CCComp { cancel: false, reason: "", uuid: this.cardData.uuid, - hero_lv: this.cardData.hero_lv + hero_lv: this.cardData.hero_lv, + card_lv: this.cardData.card_lv }; oops.message.dispatchEvent(GameEvent.UseHeroCard, guard); if (guard.cancel) { diff --git a/assets/script/game/map/HInfoComp.ts b/assets/script/game/map/HInfoComp.ts index 3ab0a489..8ce1d824 100644 --- a/assets/script/game/map/HInfoComp.ts +++ b/assets/script/game/map/HInfoComp.ts @@ -50,7 +50,19 @@ export class HInfoComp extends CCComp { refresh() { if (!this.model) return; - this.updateLevelUI(); + + const isHighLevel = (this.model.lv ?? 0) > 1; + if (this.HF_node) this.HF_node.active = isHighLevel; + if (this.NF_node) this.NF_node.active = !isHighLevel; + + const activeFrameNode = isHighLevel ? this.HF_node : this.NF_node; + if (activeFrameNode) { + const cardLvStr = `lv${this.model.card_lv ?? 1}`; + activeFrameNode.children.forEach(child => { + child.active = (child.name === cardLvStr); + }); + } + const heroUuid = this.model.hero_uuid ?? 0; if (heroUuid !== this.iconHeroUuid) { this.iconHeroUuid = heroUuid; @@ -87,16 +99,7 @@ export class HInfoComp extends CCComp { return current.getComponent(Label) || current.getComponentInChildren(Label); } - private updateLevelUI() { - if (!this.model) return; - const lvNode = this.node.getChildByName("lv"); - if (!lvNode) return; - lvNode.active = true - const lv2 = lvNode.getChildByName("lv2"); - if (lv2) lv2.active = this.model.lv >= 2; - const lv3 = lvNode.getChildByName("lv3"); - if (lv3) lv3.active = this.model.lv >= 3; - } + private updateHeroAnimation(node: Node, uuid: number, token: number) { if (!node) return; diff --git a/assets/script/game/map/MissionCardComp.ts b/assets/script/game/map/MissionCardComp.ts index 6e6e7ab8..77de7d03 100644 --- a/assets/script/game/map/MissionCardComp.ts +++ b/assets/script/game/map/MissionCardComp.ts @@ -234,6 +234,7 @@ export class MissionCardComp extends CCComp { if (current >= heroMax) { const heroUuid = Number(payload?.uuid ?? 0); const heroLv = Math.max(1, Math.floor(Number(payload?.hero_lv ?? 1))); + const cardLv = Math.max(1, Math.floor(Number(payload?.card_lv ?? 1))); if (this.canUseHeroCardByMerge(heroUuid, heroLv)) { payload.cancel = false; payload.reason = ""; diff --git a/assets/script/game/map/MissionHeroComp.ts b/assets/script/game/map/MissionHeroComp.ts index ab264c15..9fd65918 100644 --- a/assets/script/game/map/MissionHeroComp.ts +++ b/assets/script/game/map/MissionHeroComp.ts @@ -31,15 +31,15 @@ export class MissionHeroCompComp extends CCComp { /** 当前英雄数量缓存 */ current_hero_num:number=-1 /** 合成规则:2 合 1 或 3 合 1 */ - merge_need_count:number=2 + merge_need_count:number=3 /** 允许合成的最高等级 */ - merge_max_lv:number=3 + merge_max_lv:number=2 /** 是否正在执行一次合成流程 */ is_merging:boolean=false /** 是否正在消费召唤队列,防止并发处理 */ is_processing_queue:boolean=false /** 召唤请求队列,保证召唤与合成串行 */ - summon_queue:{ uuid: number; hero_lv: number }[]=[] + summon_queue:{ uuid: number; hero_lv: number; card_lv: number }[]=[] /** 预留英雄列表 */ heros:any=[] onLoad(){ @@ -84,19 +84,21 @@ export class MissionHeroCompComp extends CCComp { /** 召唤请求入口:归一化参数并进入串行队列 */ private async call_hero(event: string, args: any){ - const uuid = Number(args?.uuid ?? 1001); - const hero_lv = Math.max(1, Number(args?.hero_lv ?? 1)); - this.summon_queue.push({ uuid, hero_lv }); + const payload = args ?? event; + const uuid = Number(payload?.uuid ?? 1001); + const hero_lv = Math.max(1, Number(payload?.hero_lv ?? 1)); + const card_lv = Math.max(1, Number(payload?.card_lv ?? 1)); + this.summon_queue.push({ uuid, hero_lv, card_lv }); this.processSummonQueue(); } /** 添加英雄:固定出生点上方生成,再落至落点 */ - private addHero(uuid:number=1001,hero_lv:number=1) { + private addHero(uuid:number=1001,hero_lv:number=1, card_lv:number=1) { console.log("addHero uuid:",uuid) let hero = ecs.getEntity(Hero); let scale = 1 const landingPos = this.resolveHeroLandingPos(uuid); let spawnPos:Vec3 = v3(landingPos.x, landingPos.y + MissionHeroCompComp.HERO_DROP_HEIGHT, 0); - hero.load(spawnPos,scale,uuid,landingPos.y,hero_lv); + hero.load(spawnPos,scale,uuid,landingPos.y,hero_lv,card_lv); return hero; } @@ -115,8 +117,8 @@ export class MissionHeroCompComp extends CCComp { } /** 添加合成后的新英雄,并覆盖为聚合后的属性 */ - private addMergedHero(uuid:number, hero_lv:number, ap:number, hp_max:number): number { - const hero = this.addHero(uuid, hero_lv); + private addMergedHero(uuid:number, hero_lv:number, card_lv:number, ap:number, hp_max:number): number { + const hero = this.addHero(uuid, hero_lv, card_lv); const model = hero.get(HeroAttrsComp); if (!model) return hero_lv; model.ap = Math.max(0, ap); @@ -184,7 +186,7 @@ export class MissionHeroCompComp extends CCComp { while (this.summon_queue.length > 0) { const payload = this.summon_queue.shift(); if (!payload) continue; - await this.handleSingleSummon(payload.uuid, payload.hero_lv); + await this.handleSingleSummon(payload.uuid, payload.hero_lv, payload.card_lv); } } finally { this.is_processing_queue = false; @@ -192,8 +194,8 @@ export class MissionHeroCompComp extends CCComp { } /** 处理单次召唤:先生成,再检测是否触发合成,再尝试链式合成 */ - private async handleSingleSummon(uuid: number, hero_lv: number) { - this.addHero(uuid, hero_lv); + private async handleSingleSummon(uuid: number, hero_lv: number, card_lv: number = 1) { + this.addHero(uuid, hero_lv, card_lv); if (!this.canMergeLevel(hero_lv)) return; const needCount = this.getMergeNeedCount(); const aliveHeroes = this.getAliveHeroes(); @@ -201,8 +203,8 @@ export class MissionHeroCompComp extends CCComp { if (mergeHeroes.length !== needCount) return; this.is_merging = true; try { - const mergedLv = await this.mergeGroupHeroes(mergeHeroes, uuid, hero_lv); - await this.tryChainMerge(uuid, mergedLv); + const mergedLv = await this.mergeGroupHeroes(mergeHeroes, uuid, hero_lv, card_lv); + await this.tryChainMerge(uuid, mergedLv, card_lv); } finally { this.is_merging = false; } @@ -256,7 +258,7 @@ export class MissionHeroCompComp extends CCComp { } /** 执行一次完整合成:聚合属性、销毁素材、播放特效、生成高一级英雄 */ - private async mergeGroupHeroes(mergeHeroes: Hero[], uuid: number, hero_lv: number): Promise { + private async mergeGroupHeroes(mergeHeroes: Hero[], uuid: number, hero_lv: number, card_lv: number): Promise { let sumAp = 0; let sumHpMax = 0; for (let i = 0; i < mergeHeroes.length; i++) { @@ -269,11 +271,11 @@ export class MissionHeroCompComp extends CCComp { const spawnPos:Vec3 = v3(landingPos.x, landingPos.y + MissionHeroCompComp.HERO_DROP_HEIGHT, 0); await this.mergeDestroyAtBirth(mergeHeroes, spawnPos); await this.playMergeBoomFx(spawnPos); - return this.addMergedHero(uuid, Math.min(this.merge_max_lv, hero_lv + 1), sumAp, sumHpMax); + return this.addMergedHero(uuid, Math.min(this.merge_max_lv, hero_lv + 1), card_lv, sumAp, sumHpMax); } /** 链式合成:当前等级合成完成后,继续尝试更高等级,直到条件不满足 */ - private async tryChainMerge(uuid: number, startLv: number) { + private async tryChainMerge(uuid: number, startLv: number, card_lv: number) { let checkLv = Math.max(1, startLv); const needCount = this.getMergeNeedCount(); let guard = 0; @@ -291,7 +293,7 @@ export class MissionHeroCompComp extends CCComp { if (mergeHeroes.length < needCount) { break; } - checkLv = await this.mergeGroupHeroes(mergeHeroes, uuid, checkLv); + checkLv = await this.mergeGroupHeroes(mergeHeroes, uuid, checkLv, card_lv); } }