refactor(map): 重构小气泡提示逻辑,统一组件管理

1. 新增SmallTipComp组件封装气泡提示动画逻辑
2. 移除TalentsComp中切换阶位的解锁提示弹窗
3. 重构HerosListComp的小提示逻辑,复用通用组件
4. 修改顶部UI的资源监听路径为钻石数据
This commit is contained in:
pan
2026-09-01 16:26:41 +08:00
parent 2d13427d7d
commit 8e1c81adb0
5 changed files with 735 additions and 302 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1628,7 +1628,7 @@
"watchPath": "data.data.gold", "watchPath": "data.data.gold",
"labelType": "cc.Label", "labelType": "cc.Label",
"watchPathArr": [ "watchPathArr": [
"data.gold" "data.diamond"
], ],
"_id": "" "_id": ""
}, },

View File

@@ -28,6 +28,7 @@ import { GameEvent } from "../common/config/GameEvent";
import { HERO_UPGRADE_NEED_FRAGMENTS, CARD_LV_BG_COLORS } from "../common/config/GameSet"; import { HERO_UPGRADE_NEED_FRAGMENTS, CARD_LV_BG_COLORS } from "../common/config/GameSet";
import { CardLiteComp } from "./CardLiteComp"; import { CardLiteComp } from "./CardLiteComp";
import { ChipComp } from "./ChipComp"; import { ChipComp } from "./ChipComp";
import { SmallTipComp } from "./SmallTipComp";
import { SSkillBoxComp } from "./SSkillBoxComp"; import { SSkillBoxComp } from "./SSkillBoxComp";
import { smc } from "../common/SingletonModuleComp"; import { smc } from "../common/SingletonModuleComp";
@@ -142,9 +143,12 @@ export class HerosListComp extends CCComp {
return return
} }
// 确保 smalltip 气泡初始隐藏,避免遮挡按钮触摸 // 确保 smalltip 气泡初始隐藏,避免遮挡按钮触摸(组件缺失时兜底补挂)
const tipNode = this.upgrade_btn.getChildByName("smalltip") const tipNode = this.upgrade_btn.getChildByName("smalltip")
if (tipNode) tipNode.active = false if (tipNode) {
const tip = tipNode.getComponent(SmallTipComp) ?? tipNode.addComponent(SmallTipComp)
tipNode.active = false
}
let btn = this.upgrade_btn.getComponent(Button) let btn = this.upgrade_btn.getComponent(Button)
if (!btn) btn = this.upgrade_btn.addComponent(Button) if (!btn) btn = this.upgrade_btn.addComponent(Button)
@@ -276,33 +280,14 @@ export class HerosListComp extends CCComp {
* @param text 提示文案 * @param text 提示文案
*/ */
private showSmallTip(text: string) { private showSmallTip(text: string) {
// smalltip 作为 upgrade_btn 的子节点挂在下面 // smalltip 作为 upgrade_btn 的子节点挂在下面,统一走 SmallTipComp 播动画
const tipNode = this.upgrade_btn?.getChildByName("smalltip") const tipNode = this.upgrade_btn?.getChildByName("smalltip")
if (!tipNode || !tipNode.isValid) { if (!tipNode || !tipNode.isValid) {
mLogger.log(this.debugMode, "HerosListComp", `未在 upgrade_btn 下找到 smalltip 节点,无法提示:${text}`) mLogger.log(this.debugMode, "HerosListComp", `未在 upgrade_btn 下找到 smalltip 节点,无法提示:${text}`)
return return
} }
const tip = tipNode.getComponent(SmallTipComp) ?? tipNode.addComponent(SmallTipComp)
// 覆盖气泡文字 tip.show(text)
const label = tipNode.getComponentInChildren(Label)
if (label) label.string = text
tipNode.active = true
Tween.stopAllByTarget(tipNode)
tipNode.setScale(0, 0, 1)
tween(tipNode)
// 弹出动画(微放大再回弹)
.to(0.15, { scale: new Vec3(1.1, 1.1, 1) }, { easing: 'quadOut' })
.to(0.05, { scale: new Vec3(1, 1, 1) })
// 停留 1 秒
.delay(1)
// 缩小消失
.to(0.15, { scale: new Vec3(0, 0, 1) }, { easing: 'quadIn' })
.call(() => {
if (tipNode && tipNode.isValid) tipNode.active = false
})
.start()
} }
// ======================== 卡片列表 ======================== // ======================== 卡片列表 ========================

View File

@@ -0,0 +1,61 @@
/**
* @file SmallTipComp.ts
* @description smalltip 气泡提示组件(UI 通用层)
*
* 职责:
* 封装 smalltip.prefab 气泡的弹出/消失动画与文案填充,供各页面复用。
* 调用方通过 getComponent(SmallTipComp) 获取实例后调 show(text) 即可,
* 无需关心节点显隐与 Tween 生命周期。
*
* 用法:
* 1. 编辑器侧将本组件挂在 smalltip 节点上(或运行时 addComponent 兜底)。
* 2. 默认隐藏节点(active = false),调用 show() 自动弹出并在停留后缩小隐藏。
*/
import { _decorator, Component, Label, Tween, Vec3, tween } from "cc";
const { ccclass } = _decorator;
/** 气泡停留时长(秒) */
const STAY_DURATION = 1;
/** SmallTipComp —— smalltip 气泡提示(弹出 → 停留 → 缩小隐藏) */
@ccclass('SmallTipComp')
export class SmallTipComp extends Component {
protected onLoad(): void {
// 初始隐藏,避免遮挡挂载点的触摸事件
this.node.active = false;
}
/**
* 弹出气泡提示(重复调用时打断当前动画,从头播放)
* @param text 提示文案
* @param stay 停留时长(秒),默认 1 秒
*/
public show(text: string, stay: number = STAY_DURATION): void {
// 覆盖气泡文字
const label = this.getComponentInChildren(Label);
if (label) label.string = text;
this.node.active = true;
Tween.stopAllByTarget(this.node);
this.node.setScale(0, 0, 1);
tween(this.node)
// 弹出动画(微放大再回弹)
.to(0.15, { scale: new Vec3(1.1, 1.1, 1) }, { easing: 'quadOut' })
.to(0.05, { scale: new Vec3(1, 1, 1) })
// 停留
.delay(stay)
// 缩小消失
.to(0.15, { scale: new Vec3(0, 0, 1) }, { easing: 'quadIn' })
.call(() => {
if (this.node && this.node.isValid) this.node.active = false;
})
.start();
}
protected onDestroy(): void {
Tween.stopAllByTarget(this.node);
}
}

View File

@@ -123,16 +123,10 @@ export class TalentsComp extends CCComp {
this.btn_reset?.targetOff(this); this.btn_reset?.targetOff(this);
} }
/** 切换阶位页签:锁定阶允许查看(卡片呈锁定态),并提示解锁条件 */ /** 切换阶位页签:锁定阶允许查看(卡片呈锁定态),不弹解锁提示 */
private selectTier(tier: TalentTier): void { private selectTier(tier: TalentTier): void {
if (tier === this.curTier) return; if (tier === this.curTier) return;
this.curTier = tier; this.curTier = tier;
const levels = smc.getTalentLevels();
if (!isTalentTierUnlocked(levels, tier)) {
const prev = tier - 1;
const invested = getTalentTierInvestedPoints(levels, prev);
oops.gui.toast(`${TIER_TAB_TEXT[tier].lockName}投入 ${invested}/${TALENT_TIER_UNLOCK_THRESHOLD} 点解锁本阶`);
}
this.refreshUI(); this.refreshUI();
} }