Files
pixelheros/assets/script/game/map/SSkillBoxComp.ts
pan 0ccf8abcf4 feat(herolist&skillbox): 新增英雄图鉴技能图标展示功能
1. 为SSkillBoxComp新增英雄图鉴专用初始化方法,支持区分技能/驻场光环图标来源
2. 扩展技能背景色适配,支持5档英雄技能等级配色
3. 在HerosListComp中实现英雄技能图标列表刷新逻辑,支持大招和各类触发技能展示
4. 按英雄等级动态显示技能解锁状态和对应等级图标
2026-08-25 10:55:31 +08:00

174 lines
6.7 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.
import { _decorator, Node, Sprite, Label } 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 { CardTriggerType } from "../common/config/CardSet";
import { EquipPoolList } from "../common/config/EquipSet";
import { SkillSet, FieldSkillSet } from "../common/config/SkillSet";
import { FieldEntry } from "../common/config/heroSet";
import { smc } from "../common/SingletonModuleComp";
const { ccclass, property } = _decorator;
/**
* 技能小图标组件
*
* 由 MissSkillsComp.addSkill() 实例化并初始化。
* 在战场上以图标 + 剩余次数的形式呈现。
*/
@ccclass('SSkillBoxComp')
@ecs.register('SSkillBoxComp', false)
export class SSkillBoxComp extends CCComp {
/** 技能图标节点 */
@property({ type: Node })
private icon_node: Node = null;
/** 技能图标节点:下面有 green blue purple red yellow 5个不同颜色节点*/
@property({ type: Node })
private bg_node: Node = null;
/** 技能等级标签 */
@property(Label)
private lv_label: Label = null;
/** 锁定遮罩节点(active 时表示技能未激活) */
@property({ type: Node })
private locked: Node = null;
/** 技能 UUID */
private s_uuid: number = 0;
/** 卡牌等级 */
private card_lv: number = 1;
/** 卡牌自定义图标ID(优先级最高,未定义则按 trigger_type 自动取) */
private card_icon?: string;
/** 触发类型(默认即时,保持向后兼容) */
private trigger_type: CardTriggerType = CardTriggerType.Instant;
/** 驻场技能词条列表(uuid 指向 FieldSkillSet 底座,value 为生效数值) */
public field: FieldEntry[] = [];
/** 英雄图鉴模式下的图标来源:skill=SkillSet,field=FieldSkillSet;undefined 表示装备卡模式 */
private hero_icon_source?: "skill" | "field";
/**
* 初始化技能卡效果:
* 1. 从 EquipPoolList 查询装备卡的触发配置(含 trigger_type)。
* 2. 更新 UI 显示(图标 + 次数)。
*
* @param uuid 卡牌 UUID
* @param card_lv 技能卡等级
*/
init(uuid: number, card_lv: number) {
this.card_lv = card_lv;
// 装备卡配置已迁移至 EquipPoolList
const config = EquipPoolList.find(c => c.uuid === uuid);
if (config) {
this.s_uuid = config.skill ?? uuid; // 获取实际的技能 UUID
this.card_icon = config.icon; // 保存卡牌自定义图标(优先级最高)
this.trigger_type = config.trigger_type ?? CardTriggerType.Instant;
} else {
this.s_uuid = uuid;
}
this.updateUI();
}
/**
* 初始化英雄技能图标(英雄图鉴面板专用):
* 图标按 s_uuid 直接取 SkillSet / FieldSkillSet 配置,不走 EquipPoolList。
* @param s_uuid 技能 UUID(大招/触发技能指向 SkillSet,光环词条指向 FieldSkillSet)
* @param s_lv 当前英雄等级下生效的技能等级(显示在等级标签)
* @param locked 当前等级未激活时显示锁定遮罩
* @param isField true 时图标取 FieldSkillSet(驻场光环词条)
*/
initHeroSkill(s_uuid: number, s_lv: number, locked: boolean, isField: boolean = false) {
this.s_uuid = s_uuid;
this.card_lv = s_lv;
this.hero_icon_source = isField ? "field" : "skill";
this.updateUI();
this.setLocked(locked);
}
/**
* 设置技能激活状态:
* - locked = true → 显示锁定遮罩,技能未激活
* - locked = false → 隐藏锁定遮罩,技能已激活
*/
setLocked(locked: boolean) {
if (this.locked) {
this.locked.active = locked;
}
}
/**
* 根据技能等级切换 bg_node 下的颜色子节点显示。
* 等级与颜色对应关系:
* 技能卡档位:card_lv 1 (wave 1) → green,2 (wave 5) → blue,3 (wave 8) → purple
* 英雄技能等级:s_lv 1~5 → green / blue / purple / red / yellow
*/
private updateBgNode() {
if (!this.bg_node) return;
const lvToColor: Record<number, string> = {
1: "green",
2: "blue",
3: "purple",
4: "red",
5: "yellow",
};
const targetColor = lvToColor[this.card_lv];
this.bg_node.children.forEach(child => {
child.active = (child.name === targetColor);
});
}
/**
* 更新 UI:
* - 背景:根据技能等级切换对应颜色子节点显示
* - 图标:从 uicons 图集获取
* - 等级标签:显示技能卡等级
*/
updateUI() {
// 按技能等级切换背景颜色节点(与 getLvColor 等级配色一致)
this.updateBgNode();
// 加载技能图标
if (this.icon_node) {
// 优先使用卡牌自定义 icon;未定义则按图鉴模式 / 装备卡 trigger_type 自动取
let iconId: string | undefined = this.card_icon;
if (!iconId) {
if (this.hero_icon_source === "field") {
// 英雄图鉴:驻场光环词条图标取 FieldSkillSet
iconId = this.s_uuid ? FieldSkillSet[this.s_uuid]?.icon : undefined;
} else if (this.hero_icon_source === "skill") {
// 英雄图鉴:大招/触发技能图标取 SkillSet
iconId = this.s_uuid ? SkillSet[this.s_uuid]?.icon : undefined;
} else if (this.trigger_type === CardTriggerType.Interval) {
iconId = this.s_uuid ? SkillSet[this.s_uuid]?.icon : undefined;
} else if (this.trigger_type === CardTriggerType.Field) {
const fieldUuid = this.field?.[0]?.uuid;
iconId = fieldUuid ? FieldSkillSet[fieldUuid]?.icon : undefined;
}
}
if (this.icon_node && this.icon_node.isValid) {
let sprite = this.icon_node.getComponent(Sprite) || this.icon_node.addComponent(Sprite);
if (smc.uiconsAtlas && iconId) {
const frame = smc.uiconsAtlas.getSpriteFrame(iconId);
sprite.spriteFrame = frame || null; // 取不到时清空,避免残留
} else {
sprite.spriteFrame = null;
}
}
}
// 显示技能等级
if (this.lv_label) {
this.lv_label.string = `${this.card_lv}`;
}
}
/** ECS 组件移除时销毁节点 */
reset() {
if (this.node && this.node.isValid) {
this.node.destroy();
}
}
}