Files
pixelheros/assets/script/game/map/TalentItemComp.ts
walkpan 336d7d03db perf(天赋面板): 优化天赋面板加载性能,减少重复资源加载
调整天赋面板预制体的UI布局参数,优化间距、内边距与容器尺寸。将天赋子项的图集加载改为父组件统一预加载并缓存,避免重复加载同一资源。面板添加时先立即刷新UI以保证秒开,后续异步更新所有子项的图标。
2026-05-11 16:05:59 +08:00

130 lines
4.3 KiB
TypeScript

/**
* @file TalentItemComp.ts
* @description 单个天赋项组件
*/
import { _decorator, Node, Label, Button, resources, SpriteAtlas, Sprite } 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 { TalentInfo, TalentType } from "../common/config/TalentSet";
import { smc } from "../common/SingletonModuleComp";
const { ccclass, property } = _decorator;
@ccclass('TalentItemComp')
@ecs.register('TalentItem', false)
export class TalentItemComp extends CCComp {
@property({ type: Label, tooltip: "天赋名称" })
lbl_name: Label = null!;
@property({ type: Node, tooltip: "图标节点" })
icon_node: Node = null!;
@property({ type: Label, tooltip: "描述" })
lbl_desc: Label = null!;
@property({ type: Label, tooltip: "等级进度" })
lbl_level: Label = null!;
@property({ type: Label, tooltip: "升级消耗" })
lbl_cost: Label = null!;
@property({ type: Button, tooltip: "升级按钮" })
btn_upgrade: Button = null!;
@property({ type: Node, tooltip: "背景" })
item_bg: Node = null!;
@property({ type: Node, tooltip: "图标背景" })
icon_bg: Node = null!;
private _talentId: TalentType = TalentType.DeadTrigger;
private _onClickCallback: ((talentId: TalentType, currentLevel: number) => void) | null = null;
private _currentLevel: number = 0;
private static _cachedAtlas: SpriteAtlas | null = null;
public static setAtlas(atlas: SpriteAtlas) {
TalentItemComp._cachedAtlas = atlas;
}
private _talentInfo: TalentInfo | null = null;
protected onLoad(): void {
if (this.btn_upgrade && this.btn_upgrade.node) {
this.btn_upgrade.node.on(Button.EventType.CLICK, this.onUpgradeClicked, this);
}
}
/**
* 更新天赋项显示
* @param talentInfo 天赋配置数据
* @param currentLevel 当前等级
* @param onClickCallback 点击升级按钮的回调
*/
public updateItem(talentInfo: TalentInfo, currentLevel: number, onClickCallback: (talentId: TalentType, currentLevel: number) => void) {
this._talentInfo = talentInfo;
this._talentId = talentInfo.id;
this._currentLevel = currentLevel;
this._onClickCallback = onClickCallback;
if (this.lbl_name) {
this.lbl_name.string = talentInfo.name;
}
// 同步尝试刷新一次图标(如果图集已经缓存过,比如重新打开界面时)
this.refreshIcon();
if (this.lbl_desc) {
let currentVal = currentLevel === 0 ? 0 : talentInfo.values[currentLevel - 1];
this.lbl_desc.string = talentInfo.desc.replace('{value}', currentVal.toString());
}
if (this.lbl_level) {
this.lbl_level.string = `${currentLevel}/${talentInfo.maxLevel}`;
}
let isMax = currentLevel >= talentInfo.maxLevel;
let cost = isMax ? 0 : (talentInfo.costs[currentLevel] ?? 0);
let canUpgrade = !isMax && smc.vmdata.gold >= cost;
if (this.lbl_cost) {
this.lbl_cost.string = isMax ? "已满级" : `${cost}`;
}
if (this.btn_upgrade) {
this.btn_upgrade.interactable = canUpgrade;
}
}
/** 单独更新图标,供父节点加载完图集后回调 */
public refreshIcon() {
if (!this._talentInfo || !this.icon_node || !this._talentInfo.icon) return;
if (TalentItemComp._cachedAtlas) {
const frame = TalentItemComp._cachedAtlas.getSpriteFrame(this._talentInfo.icon);
if (frame && this.icon_node.isValid) {
const sprite = this.icon_node.getComponent(Sprite) || this.icon_node.addComponent(Sprite);
sprite.spriteFrame = frame;
}
}
}
private onUpgradeClicked() {
if (this._onClickCallback) {
this._onClickCallback(this._talentId, this._currentLevel);
}
}
protected onDestroy(): void {
if (this.btn_upgrade && this.btn_upgrade.node && this.btn_upgrade.node.isValid) {
this.btn_upgrade.node.off(Button.EventType.CLICK, this.onUpgradeClicked, this);
}
}
/** ECS 组件移除时销毁节点 */
reset() {
this.node.destroy();
}
}