refactor(gui, talent): 调整天赋卡片UI布局与边框参数
feat(talent): 新增天赋面板经验数值与点数统计显示 refactor(hero): 重构英雄列表与详情弹窗排序逻辑 fix(window): 修复弹窗默认激活状态与位置偏移问题
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
* 1. 展示单个英雄的详情:idle 动画、名称、AP / DEF / HP / CD、技能描述、
|
||||
* 稀有度底框、局外等级、职业、碎片数量、升级按钮、技能图标列表。
|
||||
* 2. 提供升级操作(消耗碎片提升局外等级,成功后播放升级特效)。
|
||||
* 3. 提供前后英雄切换按钮,按图鉴排序顺序循环切换(getSortedHeroList)。
|
||||
* 3. 提供前后英雄切换按钮,按图鉴排序顺序循环切换(品质降序 → uuid 升序)。
|
||||
* 4. 提供关闭按钮 / 遮罩点击关闭弹窗。
|
||||
*
|
||||
* 使用(oops.gui 模块):
|
||||
@@ -15,12 +15,11 @@
|
||||
* 关键设计:
|
||||
* - 详情渲染逻辑与原 HerosListComp 详情面板同源(已迁移至此),
|
||||
* HerosListComp 仅保留卡片列表,点击卡片改为打开本弹窗。
|
||||
* - 前后切换按 getSortedHeroList 计算的顺序循环(与图鉴页面卡片顺序一致)。
|
||||
* - 前后切换按品质降序 → uuid 升序循环(与图鉴页面卡片顺序一致)。
|
||||
* - hero_icon 使用 Animation + iconVisualToken 机制防止异步加载竞态。
|
||||
*
|
||||
* 依赖:
|
||||
* - HeroInfo / heroSet —— 英雄静态配置
|
||||
* - getSortedHeroList(heroUpSet)—— 图鉴排序
|
||||
* - HeroInfo / HeroList(heroSet)—— 英雄静态配置与全量 UUID 列表
|
||||
* - smc.getHeroGrowth / smc.getHeroOuterLv / smc.upgradeHero —— 成长数据
|
||||
* - buildHeroSkillDesc(HeroSkillText)—— 技能描述生成器
|
||||
* - SSkillBoxComp / ChipComp / SmallTipComp —— 子组件
|
||||
@@ -30,12 +29,11 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
|
||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||
import { oops } from "db://oops-framework/core/Oops";
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { HeroInfo, SkillTriggerType, LvFieldEntry, LvTriggerEntry, TriggerGrouped, HSkillInfo, getHeroDisplayStats, LvBonusAttrsEntry } from "../common/config/heroSet";
|
||||
import { HeroInfo, HeroList, SkillTriggerType, LvFieldEntry, LvTriggerEntry, TriggerGrouped, HSkillInfo, getHeroDisplayStats, LvBonusAttrsEntry } from "../common/config/heroSet";
|
||||
import { buildHeroSkillDesc } from "../common/HeroSkillText";
|
||||
import { outlineRich } from "../common/RichOutline";
|
||||
import { GameEvent } from "../common/config/GameEvent";
|
||||
import { HERO_UPGRADE_NEED_FRAGMENTS, RARITY_BG_COLORS } from "../common/config/GameSet";
|
||||
import { getSortedHeroList } from "../common/config/heroUpSet";
|
||||
import { ChipComp } from "./ChipComp";
|
||||
import { SmallTipComp } from "./SmallTipComp";
|
||||
import { SSkillBoxComp } from "./SSkillBoxComp";
|
||||
@@ -249,7 +247,13 @@ export class HeroInfoComp extends CCComp {
|
||||
* @param delta 1 下一个,-1 上一个
|
||||
*/
|
||||
private switchHero(delta: 1 | -1) {
|
||||
const sorted = getSortedHeroList(uuid => smc.getHeroGrowth(uuid));
|
||||
// 与图鉴页面排序同源:仅按品质降序 → uuid 升序
|
||||
const sorted = [...HeroList].sort((a, b) => {
|
||||
const ra = HeroInfo[a]?.rarity ?? 1;
|
||||
const rb = HeroInfo[b]?.rarity ?? 1;
|
||||
if (ra !== rb) return rb - ra;
|
||||
return a - b;
|
||||
});
|
||||
if (sorted.length === 0) return;
|
||||
const idx = sorted.indexOf(this.huuid);
|
||||
// 当前 uuid 不在列表中(异常)时回退到第一个
|
||||
|
||||
@@ -5,15 +5,16 @@
|
||||
* 职责:
|
||||
* 1. 以卡片列表形式展示所有可用英雄(使用 CardLiteComp 预制体)。
|
||||
* 2. 点击卡片打开英雄详情弹窗(UIID.HeroInfo),详情/升级在 HeroInfoComp 中处理。
|
||||
* 3. 卡片排序:可升级优先 → 现有等级降序 → 品质降序(getSortedHeroList)。
|
||||
* 3. 卡片排序:仅按品质降序 → uuid 升序(与养成进度解耦,保持展示稳定)。
|
||||
*
|
||||
* 关键设计:
|
||||
* - cards_node 为卡片容器,通过 instantiate(card_lite_prefab) 动态生成卡片。
|
||||
* - 升级/碎片变动后通过 HERO_GROWTH_UPDATE 事件统一刷新所有卡片的可升级标识。
|
||||
* - 详情面板已从本组件剥离,由 HeroInfoComp 承载。
|
||||
* - 排序不依赖 smc,仅读取静态配置(HeroInfo.rarity)。
|
||||
*
|
||||
* 依赖:
|
||||
* - getSortedHeroList(heroUpSet)—— 图鉴排序
|
||||
* - HeroInfo / HeroList(heroSet)—— 英雄静态配置与全量 UUID 列表
|
||||
* - CardLiteComp —— 轻量卡片组件
|
||||
* - UIID.HeroInfo(oops.gui)—— 英雄详情弹窗
|
||||
*/
|
||||
@@ -24,10 +25,8 @@ import { oops } from "db://oops-framework/core/Oops";
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { HeroInfo, HeroList } from "../common/config/heroSet";
|
||||
import { GameEvent } from "../common/config/GameEvent";
|
||||
import { getSortedHeroList } from "../common/config/heroUpSet";
|
||||
import { UIID } from "../common/config/GameUIConfig";
|
||||
import { CardLiteComp } from "./CardLiteComp";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
|
||||
const { property, ccclass } = _decorator;
|
||||
|
||||
@@ -46,14 +45,30 @@ export class HerosListComp extends CCComp {
|
||||
@property
|
||||
card_w = 120
|
||||
|
||||
/** 卡片高度 */
|
||||
@property
|
||||
card_h = 200
|
||||
|
||||
/** 卡片横向间隔 */
|
||||
@property
|
||||
spacing_x = 10
|
||||
|
||||
/** 卡片纵向间隔 */
|
||||
@property
|
||||
spacing_y = 10
|
||||
|
||||
/** 每行卡片数(竖向滚动时按列排列) */
|
||||
@property
|
||||
cols = 4
|
||||
|
||||
/** 卡片左右边距 */
|
||||
@property
|
||||
margin_x = 15
|
||||
|
||||
/** 卡片上下边距 */
|
||||
@property
|
||||
margin_y = 50
|
||||
|
||||
// ======================== 运行时状态 ========================
|
||||
|
||||
debugMode: boolean = false
|
||||
@@ -95,8 +110,13 @@ export class HerosListComp extends CCComp {
|
||||
|
||||
this.cards_node.removeAllChildren()
|
||||
|
||||
// 排序与详情面板"前后切换"同源(getSortedHeroList),保证两个入口顺序一致
|
||||
const sorted = getSortedHeroList(uuid => smc.getHeroGrowth(uuid))
|
||||
// 图鉴排序:仅按品质降序 → uuid 升序(与养成进度解耦,保持展示稳定)
|
||||
const sorted = [...HeroList].sort((a, b) => {
|
||||
const ra = HeroInfo[a]?.rarity ?? 1;
|
||||
const rb = HeroInfo[b]?.rarity ?? 1;
|
||||
if (ra !== rb) return rb - ra;
|
||||
return a - b;
|
||||
})
|
||||
|
||||
for (const uuid of sorted) {
|
||||
const hero = HeroInfo[uuid]
|
||||
@@ -127,16 +147,18 @@ export class HerosListComp extends CCComp {
|
||||
const total = this.cards_node.children.length
|
||||
if (total === 0) return
|
||||
|
||||
// 宽度 = 卡片总宽 + 卡片间隔 + 左右边距
|
||||
const contentW = total * this.card_w
|
||||
+ (total - 1) * this.spacing_x
|
||||
// 竖向滚动:宽度固定(每行 cols 列),高度按行数累计
|
||||
const rows = Math.ceil(total / this.cols)
|
||||
|
||||
// 宽度 = 每行卡片总宽 + 横向间隔 + 左右边距
|
||||
const contentW = this.cols * this.card_w
|
||||
+ (this.cols - 1) * this.spacing_x
|
||||
+ this.margin_x * 2
|
||||
|
||||
const cols = 4
|
||||
const rows = Math.ceil(total / cols)
|
||||
const cardH = 200
|
||||
const spacingY = 10
|
||||
const contentH = Math.max(1000, rows * (cardH + spacingY) + 50)
|
||||
// 高度 = 行数 × 卡片高 + 纵向间隔 + 上下边距
|
||||
const contentH = rows * this.card_h
|
||||
+ (rows - 1) * this.spacing_y
|
||||
+ this.margin_y * 2
|
||||
|
||||
const uiTrans = this.cards_node.getComponent(UITransform)
|
||||
if (uiTrans) {
|
||||
|
||||
@@ -69,6 +69,9 @@ export class TalentsComp extends CCComp {
|
||||
@property({ type: ProgressBar, tooltip: "当前等级经验进度条" })
|
||||
progress_exp: ProgressBar = null!;
|
||||
|
||||
@property({ type: Label, tooltip: "当前等级经验数值(当前经验/升级所需经验)" })
|
||||
lbl_exp: Label = null!;
|
||||
|
||||
@property({ type: Node, tooltip: "一阶页签节点" })
|
||||
tab_basic: Node = null!;
|
||||
|
||||
@@ -148,7 +151,14 @@ export class TalentsComp extends CCComp {
|
||||
if (!this.talents_content || !this.prefab_talent_item) return;
|
||||
const levels = smc.getTalentLevels();
|
||||
|
||||
if (this.lbl_points) this.lbl_points.string = `${smc.getTalentPoints()}`;
|
||||
if (this.lbl_points) {
|
||||
// 剩余/总点数:总点数 = 剩余 + 各阶已投入
|
||||
const remaining = smc.getTalentPoints();
|
||||
const invested = getTalentTierInvestedPoints(levels, TalentTier.Basic)
|
||||
+ getTalentTierInvestedPoints(levels, TalentTier.Specialized)
|
||||
+ getTalentTierInvestedPoints(levels, TalentTier.Super);
|
||||
this.lbl_points.string = `${remaining}/${remaining + invested}`;
|
||||
}
|
||||
|
||||
// 天赋等级(Lv.x)与当前等级经验进度
|
||||
const talentLv = smc.getTalentLevel();
|
||||
@@ -160,6 +170,13 @@ export class TalentsComp extends CCComp {
|
||||
? Math.min(1, smc.getTalentExp() / needExp)
|
||||
: 1;
|
||||
}
|
||||
if (this.lbl_exp) {
|
||||
const needExp = getTalentLevelExp(talentLv);
|
||||
// 满级后显示为 0/0,避免分母为 0
|
||||
this.lbl_exp.string = needExp > 0
|
||||
? `${smc.getTalentExp()}/${needExp}`
|
||||
: `0/0`;
|
||||
}
|
||||
|
||||
// 仅首次进入时默认选中已解锁的最高阶,后续刷新保持玩家当前选择
|
||||
if (!this.inited) {
|
||||
|
||||
Reference in New Issue
Block a user