From 1871551fca5ec3a1545a71e29851a0729c24bef6 Mon Sep 17 00:00:00 2001 From: pan Date: Wed, 3 Jun 2026 15:12:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(ui,card):=20=E6=B7=BB=E5=8A=A0=E6=8A=80?= =?UTF-8?q?=E8=83=BD=E5=8D=A1=E7=89=8C=E7=B3=BB=E7=BB=9FUI=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E4=B8=8E=E6=98=BE=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增SkillBox UI界面配置到GameUIConfig 2. 为CardComp组件添加技能描述文本渲染功能 3. 实现卡牌节点标签缓存与统一UI样式配置 4. 修复不同类型卡牌切换时的文本残留问题 --- .../script/game/common/config/GameUIConfig.ts | 3 ++ assets/script/game/map/CardComp.ts | 40 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/assets/script/game/common/config/GameUIConfig.ts b/assets/script/game/common/config/GameUIConfig.ts index fe29c7e2..8037b5c2 100644 --- a/assets/script/game/common/config/GameUIConfig.ts +++ b/assets/script/game/common/config/GameUIConfig.ts @@ -22,6 +22,8 @@ export enum UIID { // Talents, Mission, HInfo, + /** 技能卡牌系统核心控制器 */ + SkillBox, } /** 打开界面方式的配置数据 */ @@ -37,4 +39,5 @@ export var UIConfigData: { [key: number]: UIConfig } = { // [UIID.Talents]: { layer: LayerType.UI, prefab: "gui/element/talents" }, [UIID.Mission]: { layer: LayerType.UI, prefab: "gui/element/mission" }, [UIID.HInfo]: { layer: LayerType.UI, prefab: "gui/element/hnode" }, + [UIID.SkillBox]: { layer: LayerType.UI, prefab: "gui/element/skillbox" }, } \ No newline at end of file diff --git a/assets/script/game/map/CardComp.ts b/assets/script/game/map/CardComp.ts index 148d9e44..89c987ce 100644 --- a/assets/script/game/map/CardComp.ts +++ b/assets/script/game/map/CardComp.ts @@ -37,6 +37,7 @@ import { FieldSkillType } from "../common/config/SkillSet"; import { FieldSkillHelper } from "../hero/FieldSkillHelper"; import { getLvColor } from "../common/config/GameSet"; import { MissionEconomy } from "./MissionEconomy"; +import { buildSkillDesc } from "../common/config/HeroSkillDesc"; @@ -94,6 +95,9 @@ export class CardComp extends CCComp { @property(Node) hp_node = null! + /** 技能信息标签缓存引用(由 cacheLabels 在 onLoad 时初始化) */ + private infoLabel: Label | null = null; + // ======================== 运行时状态 ======================== /** 当前卡牌的金币费用 */ @@ -144,6 +148,7 @@ export class CardComp extends CCComp { onLoad() { /** 初始阶段只做UI状态准备,不触发业务逻辑 */ this.bindEvents(); + this.cacheLabels(); this.restPosition = this.node.position.clone(); this.opacityComp = this.node.getComponent(UIOpacity) || this.node.addComponent(UIOpacity); this.opacityComp.opacity = 255; @@ -700,6 +705,8 @@ export class CardComp extends CCComp { this.hp_node.active = true; // 英雄卡:隐藏技能信息节点 if (this.info_node) this.info_node.active = false; + // 英雄卡:清空技能描述文本,避免切回时残留上一次的技能信息 + if (this.infoLabel) this.infoLabel.string = ""; } else if (this.card_type === CardType.Skill) { if (this.lvl_node) this.lvl_node.node.active = false; // 技能卡:显示技能名 + 品质后缀 + 描述 @@ -713,6 +720,18 @@ export class CardComp extends CCComp { this.hp_node.active = false; // 技能卡:显示技能信息节点 if (this.info_node) this.info_node.active = true; + // 技能卡:填充技能描述文本(沿用 HInfoComp.buildSkillDesc 模式) + // 注意:技能卡 uuid 来自 SkillSet 而非 HeroInfo,故以 SkillConfig 作为数据源; + // 用 buildSkillDesc 兼容调用,结果为空时回退到 SkillConfig.info 字段 + if (this.infoLabel) { + const skill = SkillSet[this.card_uuid]; + if (skill) { + const desc = buildSkillDesc(skill as any) || skill.info || ""; + this.infoLabel.string = desc; + } else { + this.infoLabel.string = ""; + } + } } else { if (this.lvl_node) this.lvl_node.node.active = false; // 特殊卡(升级 / 刷新):显示卡名 + 品质后缀 + 描述 @@ -725,6 +744,8 @@ export class CardComp extends CCComp { this.ap_node.active = false; this.hp_node.active = false; + // 特殊卡:清空技能描述文本,避免切到特殊卡时残留上一次的技能信息 + if (this.infoLabel) this.infoLabel.string = ""; } // ---- 费用标签 ---- @@ -906,6 +927,25 @@ export class CardComp extends CCComp { if (label) label.string = value; } + /** + * 缓存 info_node 子树中的 Label 引用。 + * 与 HInfoComp.cacheLabels() 同源实现:若 info_node 下没有 Label 则动态创建, + * 并设置与 HInfoComp 一致的字号 / 行高 / 对齐 / 溢出策略。 + */ + private cacheLabels() { + if (this.infoLabel || !this.info_node) return; + this.infoLabel = this.info_node.getComponentInChildren(Label); + if (!this.infoLabel) { + const child = this.info_node.children[0] || this.info_node; + this.infoLabel = child.getComponent(Label) || child.addComponent(Label); + this.infoLabel.fontSize = 20; + this.infoLabel.lineHeight = 28; + this.infoLabel.overflow = Label.Overflow.SHRINK; + this.infoLabel.horizontalAlign = Label.HorizontalAlign.LEFT; + this.infoLabel.verticalAlign = Label.VerticalAlign.TOP; + } + } + /** * 根据卡牌类型和 UUID 解析出图标 ID(在 SpriteAtlas 中的帧名)。