Files
pixelheros/assets/script/game/map/TalentItemComp.ts
pan 84337897e7 refactor(talentItem): 优化天赋道具的状态逻辑与UI布局
1. 调整天赋道具的状态判断逻辑,将阶位未解锁和未加点状态合并为未激活状态
2. 移除整卡透明度遮罩,改为仅显示左上角锁图标
3. 更新锁节点提示文案,明确未激活的两种场景
4. 调整锁、加号、满级角标的位置与资源配置
5. 扩展点击交互范围,支持锁角标点击触发升级
2026-08-25 16:32:12 +08:00

124 lines
5.1 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.
/**
* @file TalentItemComp.ts
* @description 天赋迷你升级卡组件(UI 视图层)
*
* 职责:
* 1. 接收 TalentsComp 下发的天赋配置 + 当前等级 + 阶位解锁态,渲染迷你点选卡。
* 2. 卡面自包含:图标 / 名称 / 当前已生效数值(Lv0 显示每级数值引导)/ 右下「当前/满级」角标。
* 3. 状态机:可升级(右上 + 徽标)/ 满级(MAX 金角标)/ 未激活(左上锁角标,点击锁/卡体可升级激活)。
* 4. 点击回调上抛(含 + 徽标与卡体),升级校验与 toast 统一由 TalentsComp 处理(单一决策点)。
*
* 依赖:
* - TalentSet.TalentConfig / TalentTier / getTalentDisplayText —— 配置与卡面文案
* - CardBgComp —— 阶位品质底框(Ⅰ蓝 / Ⅱ紫 / Ⅲ金)
* - smc.uiconsAtlas —— 图标解析(缺省回退资源目录)
*/
import { _decorator, Label, Node, NodeEventType, Sprite, SpriteFrame } 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 { TalentConfig, TalentTier, getTalentDisplayText } from "../common/config/TalentSet";
import { CardBgComp } from "./CardBgComp";
import { smc } from "../common/SingletonModuleComp";
import { oops } from "db://oops-framework/core/Oops";
const { ccclass, property } = _decorator;
/** 阶位 → 品质底框 card_lv(CARD_LV_BG_COLORS:2=blue、3=purple、4=yellow) */
const TIER_TO_BG_LV: Record<number, number> = {
[TalentTier.Basic]: 2,
[TalentTier.Specialized]: 3,
[TalentTier.Super]: 4,
};
/** TalentItemComp —— 天赋迷你升级卡组件 */
@ccclass('TalentItemComp')
@ecs.register('TalentItem', false)
export class TalentItemComp extends CCComp {
@property({ type: Label, tooltip: "天赋名称" })
lbl_name: Label = null!;
@property({ type: Label, tooltip: "当前已生效数值(Lv0 显示每级引导)" })
lbl_info: Label = null!;
@property({ type: Label, tooltip: "等级角标(当前/满级)" })
lbl_lv: Label = null!;
@property({ type: Sprite, tooltip: "天赋图标" })
icon: Sprite = null!;
@property({ type: CardBgComp, tooltip: "卡牌背景组件(阶位品质色)" })
bg: CardBgComp = null!;
@property({ type: Node, tooltip: "右上 + 升级徽标(可升级时显示)" })
node_plus: Node = null!;
@property({ type: Node, tooltip: "MAX 满级角标" })
node_max: Node = null!;
@property({ type: Node, tooltip: "未激活锁遮罩/锁图标(未加点或阶位未解锁)" })
node_lock: Node = null!;
/** 点击回调(卡体与 + 徽标同源上抛),由父级统一校验升级 */
public onTalentTap: ((uuid: number) => void) | null = null;
/** 当前展示的天赋 uuid(回调携带) */
private curUuid: number = 0;
protected onLoad(): void {
this.node.on(NodeEventType.TOUCH_END, this.onTap, this);
}
protected onDestroy(): void {
this.node.off(NodeEventType.TOUCH_END, this.onTap, this);
}
/**
* 刷新迷你卡展示
* @param cfg 天赋配置(TalentSet 条目)
* @param lv 当前等级
* @param tierUnlocked 所属阶位是否已解锁
* @param canUp 父级预判的"可升级"(阶位解锁 + 未满级 + 点数足够)
*/
public updateItem(cfg: TalentConfig, lv: number, tierUnlocked: boolean, canUp: boolean): void {
if (!cfg) return;
this.curUuid = cfg.uuid;
if (this.lbl_name) this.lbl_name.string = cfg.name;
// 卡面自包含:已加点显示当前生效数值,未加点显示每级数值引导
if (this.lbl_info) this.lbl_info.string = getTalentDisplayText(cfg, lv);
if (this.lbl_lv) this.lbl_lv.string = `${lv}/${cfg.max_lv}`;
// 阶位品质底框:Ⅰ蓝 / Ⅱ紫 / Ⅲ金
if (this.bg) this.bg.apply(TIER_TO_BG_LV[cfg.tier] ?? 1);
// 图标:uiconsAtlas 优先,资源目录回退(与 TalentItemComp 旧版/SCardComp 口径一致)
if (this.icon && cfg.icon) {
let frame: SpriteFrame | null = null;
if (smc.uiconsAtlas) {
frame = smc.uiconsAtlas.getSpriteFrame(cfg.icon);
}
if (!frame) {
frame = oops.res.get("game/heros/cards/" + cfg.icon, SpriteFrame) as SpriteFrame;
}
if (frame) this.icon.spriteFrame = frame;
}
// 状态徽标:满级 MAX / 可升级 + / 未激活锁角标(未加点或阶位未解锁,置于左上角)
const maxed = lv >= cfg.max_lv;
if (this.node_max) this.node_max.active = maxed;
if (this.node_plus) this.node_plus.active = !maxed && tierUnlocked && canUp;
if (this.node_lock) this.node_lock.active = lv <= 0 || !tierUnlocked;
}
/** 卡体/+ 徽标/锁角标点击:触摸事件冒泡至卡体统一上抛 uuid,升级校验与提示由 TalentsComp 处理 */
private onTap(): void {
this.onTalentTap?.(this.curUuid);
}
/** ECS 组件移除时销毁节点(CCComp 抽象方法实现) */
reset() {
this.node.destroy();
}
}