2 Commits

Author SHA1 Message Date
panFD
124bb19005 refactor(common): 调整弹窗预制体尺寸与文本样式
1. 调整弹窗内容区域高度与文本行高、字号
2. 为通用弹窗标题添加描边支持
3. 优化英雄列表排序逻辑

首先调整了通用弹窗预制体的文本样式参数,修复Cocos 3.8+的Label描边适配,同时重构英雄列表排序规则,将可升级英雄优先展示并按等级、品质降序排列。
2026-09-08 22:53:52 +08:00
panFD
214231d64f refactor(map): 调整英雄列表布局参数与添加页签红点逻辑
1. 新增英雄列表卡片宽度、间距、边距可配置属性,修正列表内容宽度计算
2. 为任务主页添加英雄成长和天赋更新事件监听,实现页签红点自动刷新
3. 补充全英雄可升级状态检测与红点显示逻辑
2026-09-08 22:20:22 +08:00
6 changed files with 1213 additions and 743 deletions

View File

@@ -787,7 +787,7 @@
"_contentSize": {
"__type__": "cc.Size",
"width": 540,
"height": 26.46
"height": 44.1
},
"_anchorPoint": {
"__type__": "cc.Vec2",
@@ -812,11 +812,11 @@
"__prefab": {
"__id__": 44
},
"_lineHeight": 21,
"_lineHeight": 35,
"_string": "<color=#00ff00>Rich</color><color=#0fffff>Text</color>",
"_horizontalAlign": 0,
"_verticalAlign": 1,
"_fontSize": 20,
"_fontSize": 30,
"_fontColor": {
"__type__": "cc.Color",
"r": 255,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -21,6 +21,7 @@
*/
import { _decorator, Button, Color, Component, EventTouch, Label, Node, NodeEventType, RichText, Tween, tween, Vec3 } from "cc";
import { oops } from "db://oops-framework/core/Oops";
import { RICH_OUTLINE_COLOR, RICH_OUTLINE_WIDTH } from "./RichOutline";
const { ccclass, property } = _decorator;
@@ -181,6 +182,14 @@ export class CommonPrompt extends Component {
if (this.config.titleColor) {
this.lab_title.color = new Color().fromHEX(this.config.titleColor);
}
this.ensureTitleOutline();
}
/** 标题描边:Cocos 3.8+ 废弃 LabelOutline 组件,改用 Label 内建 outlineColor/outlineWidth */
private ensureTitleOutline() {
if (!this.lab_title || !this.lab_title.isValid) return;
this.lab_title.outlineColor = new Color().fromHEX(RICH_OUTLINE_COLOR);
this.lab_title.outlineWidth = RICH_OUTLINE_WIDTH;
}
private setContent() {

View File

@@ -27,6 +27,7 @@ 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 { canHeroUpgrade } from "../common/config/heroUpSet";
import { CardLiteComp } from "./CardLiteComp";
import { ChipComp } from "./ChipComp";
import { SmallTipComp } from "./SmallTipComp";
@@ -114,6 +115,18 @@ export class HerosListComp extends CCComp {
@property(RichText)
upgrade_info_label = null!
/** 卡片宽度 */
@property
card_w = 120
/** 卡片横向间隔 */
@property
spacing_x = 10
/** 卡片左右边距 */
@property
margin_x = 15
// ======================== 运行时状态 ========================
huuid: number = 0
@@ -324,7 +337,16 @@ export class HerosListComp extends CCComp {
this.cards_node.removeAllChildren()
const sorted = [...HeroList].sort((a, b) => {
return (HeroInfo[a]?.rarity ?? 1) - (HeroInfo[b]?.rarity ?? 1);
const ga = smc.getHeroGrowth(a)
const gb = smc.getHeroGrowth(b)
// 可升级的一批排在最左
const ca = canHeroUpgrade(ga.lv, ga.fragments) ? 0 : 1
const cb = canHeroUpgrade(gb.lv, gb.fragments) ? 0 : 1
if (ca !== cb) return ca - cb
// 同批内:现有等级降序优先
if (ga.lv !== gb.lv) return gb.lv - ga.lv
// 等级相同:品质降序(rarity 越大品质越高)
return (HeroInfo[b]?.rarity ?? 1) - (HeroInfo[a]?.rarity ?? 1)
});
for (const uuid of sorted) {
@@ -364,6 +386,11 @@ 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
+ this.margin_x * 2
const cols = 4
const rows = Math.ceil(total / cols)
const cardH = 200
@@ -372,11 +399,11 @@ export class HerosListComp extends CCComp {
const uiTrans = this.cards_node.getComponent(UITransform)
if (uiTrans) {
uiTrans.setContentSize(uiTrans.width, contentH)
uiTrans.setContentSize(contentW, contentH)
}
mLogger.log(this.debugMode, "HerosListComp", "updateContentSize", {
total, cols, rows, contentH,
total, cols, rows, contentW, contentH,
})
}

View File

@@ -26,6 +26,8 @@ import { GameEvent } from "../common/config/GameEvent";
import { Timer } from "db://oops-framework/core/common/timer/Timer";
import { mLogger } from "../common/Logger";
import { UIID } from "../common/config/GameUIConfig";
import { HeroList } from "../common/config/heroSet";
import { canHeroUpgrade } from "../common/config/heroUpSet";
const { ccclass, property } = _decorator;
@@ -84,6 +86,14 @@ export class MissionHomeComp extends CCComp {
/** 注册任务结束事件 */
protected onLoad(): void {
this.on(GameEvent.MissionEnd, this.mission_end, this)
// oops.message 事件总线:成长/天赋数据变化时刷新页签红点
oops.message.on(GameEvent.HERO_GROWTH_UPDATE, this.refreshRedDots, this)
oops.message.on(GameEvent.TALENT_UPDATE, this.refreshRedDots, this)
}
protected onDestroy(): void {
oops.message.off(GameEvent.HERO_GROWTH_UPDATE, this.refreshRedDots, this)
oops.message.off(GameEvent.TALENT_UPDATE, this.refreshRedDots, this)
}
/** 启动时显示主页 */
@@ -97,6 +107,8 @@ export class MissionHomeComp extends CCComp {
}
onEnable() {
// 节点重新激活时补刷一次红点(事件分发期间本节点可能处于隐藏态)
this.refreshRedDots()
}
update(dt: number) {
@@ -233,6 +245,32 @@ export class MissionHomeComp extends CCComp {
if (child) child.active = active
}
/**
* 刷新页签按钮红点:
* - hero_btn/red_dot:任意英雄碎片满足升级条件(canHeroUpgrade)时显示
* - tals_btn/red_dot:存在未分配的天赋点(talent_points > 0)时显示
*/
private refreshRedDots() {
this.setRedDot(this.hero_btn, this.hasUpgradableHero())
this.setRedDot(this.tals_btn, smc.getTalentPoints() > 0)
}
/** 遍历全量英雄,判定是否存在可升级者(未满级且碎片充足) */
private hasUpgradableHero(): boolean {
for (const uuid of HeroList) {
const growth = smc.getHeroGrowth(uuid);
if (canHeroUpgrade(growth.lv, growth.fragments)) return true;
}
return false;
}
/** 切换按钮下 red_dot 子节点的显示 */
private setRedDot(btn: Node, active: boolean) {
if (!btn || !btn.isValid) return
const dot = btn.getChildByName("red_dot")
if (dot) dot.active = active
}
openRanks() {
this.showPage(this.ranks_page)
}
@@ -254,6 +292,7 @@ export class MissionHomeComp extends CCComp {
this.stopStartGuide();
this.uodate_data()
this.hideAllPages()
this.refreshRedDots()
this.node.active = true
// 播放主页背景音乐,恢复默认音量
oops.audio.volumeMusic = 1.0;