feat(heroList): 升级按钮交互与提示优化
1. 新增升级按钮点击回弹动画与自动绑定逻辑 2. 替换按钮禁用逻辑为气泡提示反馈 3. 重构smalltip预制体并集成到升级按钮 4. 添加完整的调试日志与异常处理
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -22,14 +22,14 @@
|
||||
"__id__": 2
|
||||
}
|
||||
],
|
||||
"_active": false,
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 22
|
||||
"__id__": 30
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 24
|
||||
"__id__": 32
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -74,24 +74,27 @@
|
||||
},
|
||||
{
|
||||
"__id__": 11
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 17
|
||||
},
|
||||
{
|
||||
"__id__": 19
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 25
|
||||
},
|
||||
{
|
||||
"__id__": 27
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 21
|
||||
"__id__": 29
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 63.35300000000001,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -119,7 +122,7 @@
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "Arrow",
|
||||
"_name": "BubbleFrame04_White_Bg",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
@@ -144,7 +147,7 @@
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": -35.679,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -156,8 +159,8 @@
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
@@ -182,6 +185,181 @@
|
||||
"__prefab": {
|
||||
"__id__": 5
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 300,
|
||||
"height": 140
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "5aIVIWevtJH5l+s9IbfCVa"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 3
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 7
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
"_dstBlendFactor": 4,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73@d552a",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
"_type": 1,
|
||||
"_fillType": 0,
|
||||
"_sizeMode": 0,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_useGrayscale": false,
|
||||
"_atlas": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "e3Rmjr7aNLlZ2fsbmMjUHG"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Widget",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 3
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 9
|
||||
},
|
||||
"_alignFlags": 45,
|
||||
"_target": null,
|
||||
"_left": 0,
|
||||
"_right": 0,
|
||||
"_top": 0,
|
||||
"_bottom": 0,
|
||||
"_horizontalCenter": 0,
|
||||
"_verticalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
"_isAbsRight": true,
|
||||
"_isAbsTop": true,
|
||||
"_isAbsBottom": true,
|
||||
"_isAbsHorizontalCenter": true,
|
||||
"_isAbsVerticalCenter": true,
|
||||
"_originalWidth": 64,
|
||||
"_originalHeight": 72,
|
||||
"_alignMode": 2,
|
||||
"_lockFlags": 0,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "d6yD+nfRxBOKOOi1Pr4ztO"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "57iKiUyRJMJ56cQDIrFssC",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "Arrow",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 12
|
||||
},
|
||||
{
|
||||
"__id__": 14
|
||||
},
|
||||
{
|
||||
"__id__": 16
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 18
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": -35.2,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 11
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 13
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 38,
|
||||
@@ -204,11 +382,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 3
|
||||
"__id__": 11
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 7
|
||||
"__id__": 15
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
@@ -249,18 +427,18 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 3
|
||||
"__id__": 11
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 9
|
||||
"__id__": 17
|
||||
},
|
||||
"_alignFlags": 20,
|
||||
"_target": null,
|
||||
"_left": 0,
|
||||
"_right": 0,
|
||||
"_top": 0,
|
||||
"_bottom": -18.179000000000002,
|
||||
"_bottom": -8.950000000000003,
|
||||
"_horizontalCenter": 0,
|
||||
"_verticalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
@@ -304,14 +482,14 @@
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 12
|
||||
"__id__": 20
|
||||
},
|
||||
{
|
||||
"__id__": 14
|
||||
"__id__": 22
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 16
|
||||
"__id__": 24
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -348,11 +526,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 11
|
||||
"__id__": 19
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 13
|
||||
"__id__": 21
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
@@ -376,11 +554,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 11
|
||||
"__id__": 19
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 15
|
||||
"__id__": 23
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
@@ -461,7 +639,7 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 18
|
||||
"__id__": 26
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
@@ -489,7 +667,7 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 20
|
||||
"__id__": 28
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
@@ -501,10 +679,7 @@
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "cb93c900-b440-4571-91d1-7da1636e3d73@d552a",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
"_spriteFrame": null,
|
||||
"_type": 1,
|
||||
"_fillType": 0,
|
||||
"_sizeMode": 0,
|
||||
@@ -550,7 +725,7 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 23
|
||||
"__id__": 31
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* - CardLiteComp —— 轻量卡片组件
|
||||
* - buildSkillDesc(HeroSkillDesc)—— 技能描述生成器
|
||||
*/
|
||||
import { _decorator, Animation, AnimationClip, Label, Node, Prefab, Sprite, UITransform, Widget, instantiate, resources } from "cc";
|
||||
import { _decorator, Animation, AnimationClip, Button, Label, Node, Prefab, Sprite, UITransform, Vec3, Widget, instantiate, resources, tween, Tween } 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 { oops } from "db://oops-framework/core/Oops";
|
||||
@@ -54,7 +54,7 @@ export class HerosListComp extends CCComp {
|
||||
|
||||
/** 卡牌背景底框节点(按卡池等级切换子节点显示) */
|
||||
@property(Node)
|
||||
BG_node=null!
|
||||
BG_node = null!
|
||||
|
||||
@property(Node)
|
||||
info_node = null!
|
||||
@@ -75,7 +75,7 @@ export class HerosListComp extends CCComp {
|
||||
@property(Node)
|
||||
type_node = null!
|
||||
|
||||
/** 升级按钮节点 */
|
||||
/** 升级按钮节点(smalltip 气泡已作为其子节点挂在下面) */
|
||||
@property(Node)
|
||||
upgrade_btn = null!
|
||||
|
||||
@@ -95,12 +95,45 @@ export class HerosListComp extends CCComp {
|
||||
debugMode: boolean = false
|
||||
|
||||
start() {
|
||||
this.bindUpgradeBtn()
|
||||
this.initCardList()
|
||||
if (HeroList.length > 0) {
|
||||
this.onCardSelect(HeroList[0])
|
||||
}
|
||||
}
|
||||
|
||||
protected onLoad(): void {
|
||||
// onLoad 阶段属性可能尚未绑定,延迟到 start 再处理
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定升级按钮点击事件
|
||||
* 在 start 中调用,确保 @property 属性已正确赋值
|
||||
*/
|
||||
private bindUpgradeBtn() {
|
||||
mLogger.log(this.debugMode, "HerosListComp", "bindUpgradeBtn", {
|
||||
hasUpgradeBtn: !!this.upgrade_btn,
|
||||
upgradeBtnName: this.upgrade_btn?.name,
|
||||
upgradeBtnActive: this.upgrade_btn?.active,
|
||||
upgradeBtnValid: this.upgrade_btn?.isValid,
|
||||
})
|
||||
|
||||
if (!this.upgrade_btn) {
|
||||
mLogger.error(this.debugMode, "HerosListComp", "upgrade_btn 未绑定,请检查编辑器属性面板")
|
||||
return
|
||||
}
|
||||
|
||||
// 确保 smalltip 气泡初始隐藏,避免遮挡按钮触摸
|
||||
const tipNode = this.upgrade_btn.getChildByName("smalltip")
|
||||
if (tipNode) tipNode.active = false
|
||||
|
||||
let btn = this.upgrade_btn.getComponent(Button)
|
||||
if (!btn) btn = this.upgrade_btn.addComponent(Button)
|
||||
btn.interactable = true
|
||||
this.upgrade_btn.on(Button.EventType.CLICK, this.onUpgradeClick, this)
|
||||
mLogger.log(this.debugMode, "HerosListComp", "升级按钮点击事件已绑定")
|
||||
}
|
||||
|
||||
protected onEnable(): void {
|
||||
oops.message.on(GameEvent.HERO_GROWTH_UPDATE, this.onGrowthUpdate, this)
|
||||
if (this.cards_node && this.cards_node.children.length > 0) {
|
||||
@@ -127,9 +160,14 @@ export class HerosListComp extends CCComp {
|
||||
* 消耗碎片提升英雄局外等级,成功后刷新详情面板
|
||||
*/
|
||||
onUpgradeClick() {
|
||||
mLogger.log(this.debugMode, "HerosListComp", "onUpgradeClick 被触发", { huuid: this.huuid })
|
||||
|
||||
const uuid = this.huuid
|
||||
if (!uuid) return
|
||||
|
||||
// 点击动画:按压回弹
|
||||
this.playUpgradeBtnAnim()
|
||||
|
||||
const success = smc.upgradeHero(uuid)
|
||||
if (success) {
|
||||
mLogger.log(this.debugMode, "HerosListComp", `英雄 ${uuid} 升级成功`)
|
||||
@@ -142,9 +180,64 @@ export class HerosListComp extends CCComp {
|
||||
fragments: growth.fragments,
|
||||
needFragments: need ?? "MAX",
|
||||
})
|
||||
// 碎片不足 / 已满级:气泡提示
|
||||
const tipText = need === undefined ? "已满级" : "碎片不足"
|
||||
this.showSmallTip(tipText)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放升级按钮按压回弹动画
|
||||
*/
|
||||
private playUpgradeBtnAnim() {
|
||||
if (!this.upgrade_btn) {
|
||||
mLogger.log(this.debugMode, "HerosListComp", "playUpgradeBtnAnim: upgrade_btn 为空")
|
||||
return
|
||||
}
|
||||
mLogger.log(this.debugMode, "HerosListComp", "播放按钮动画")
|
||||
Tween.stopAllByTarget(this.upgrade_btn)
|
||||
this.upgrade_btn.setScale(1, 1, 1)
|
||||
tween(this.upgrade_btn)
|
||||
.to(0.08, { scale: new Vec3(0.9, 0.9, 1) }, { easing: 'quadOut' })
|
||||
.to(0.12, { scale: new Vec3(1.1, 1.1, 1) }, { easing: 'quadOut' })
|
||||
.to(0.08, { scale: new Vec3(1, 1, 1) }, { easing: 'quadIn' })
|
||||
.start()
|
||||
}
|
||||
|
||||
/**
|
||||
* 在升级按钮附近弹出 smalltip 气泡提示
|
||||
* @param text 提示文案
|
||||
*/
|
||||
private showSmallTip(text: string) {
|
||||
// smalltip 作为 upgrade_btn 的子节点挂在下面
|
||||
const tipNode = this.upgrade_btn?.getChildByName("smalltip")
|
||||
if (!tipNode || !tipNode.isValid) {
|
||||
mLogger.log(this.debugMode, "HerosListComp", `未在 upgrade_btn 下找到 smalltip 节点,无法提示:${text}`)
|
||||
return
|
||||
}
|
||||
|
||||
// 覆盖气泡文字
|
||||
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()
|
||||
}
|
||||
|
||||
// ======================== 卡片列表 ========================
|
||||
|
||||
private initCardList() {
|
||||
@@ -326,12 +419,12 @@ export class HerosListComp extends CCComp {
|
||||
chipComp.setHeroByUuid(uuid)
|
||||
}
|
||||
|
||||
// 升级按钮状态:未满级且碎片足够时可用
|
||||
// 升级按钮状态:始终可点击,点击后由 onUpgradeClick 判断碎片是否足够
|
||||
// 碎片不足时按钮保持可点,通过气泡提示用户(而非禁用按钮)
|
||||
if (this.upgrade_btn) {
|
||||
const canUpgrade = !isMaxLv && growth.fragments >= needFragments
|
||||
this.upgrade_btn.active = true
|
||||
const btnComp = this.upgrade_btn.getComponent("cc.Button") as import("cc").Button | null
|
||||
if (btnComp) btnComp.interactable = canUpgrade
|
||||
if (btnComp) btnComp.interactable = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user