From 17452167c3b4653277c43ddbd7961cab347c5da5 Mon Sep 17 00:00:00 2001 From: panFD Date: Fri, 19 Jun 2026 15:51:17 +0800 Subject: [PATCH] =?UTF-8?q?refactor(card):=20=E9=87=8D=E6=9E=84=E5=8D=A1?= =?UTF-8?q?=E7=89=8C=E8=A7=A6=E6=91=B8=E4=BA=A4=E4=BA=92=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E6=9B=BF=E6=8D=A2=E9=95=BF=E6=8C=89=E4=B8=BA=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E8=A7=A6=E5=8F=91=E4=BF=A1=E6=81=AF=E9=9D=A2=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 移除长按相关逻辑,改用点击触发英雄卡信息面板 2. 新增卡牌点击选中联动机制,统一管理召唤按钮显示 3. 调整触摸位移阈值,优化点击和拖拽的判定逻辑 4. 新增卡牌选中事件,实现多卡牌间的UI联动 5. 修复预制体默认激活状态,统一初始UI状态 --- assets/resources/gui/element/card.prefab | 2 +- assets/script/game/common/config/GameEvent.ts | 2 + assets/script/game/map/CardComp.ts | 111 +++++++++++------- 3 files changed, 73 insertions(+), 42 deletions(-) diff --git a/assets/resources/gui/element/card.prefab b/assets/resources/gui/element/card.prefab index 9222226c..f4fe153c 100644 --- a/assets/resources/gui/element/card.prefab +++ b/assets/resources/gui/element/card.prefab @@ -5686,7 +5686,7 @@ "__id__": 314 } ], - "_active": true, + "_active": false, "_components": [ { "__id__": 320 diff --git a/assets/script/game/common/config/GameEvent.ts b/assets/script/game/common/config/GameEvent.ts index 601cc955..030aae79 100644 --- a/assets/script/game/common/config/GameEvent.ts +++ b/assets/script/game/common/config/GameEvent.ts @@ -20,6 +20,8 @@ export enum GameEvent { CastSkill = "CastSkill", CardsClose = "CardsClose", CardRefresh = "CardRefresh", + /** 单张卡牌被点击选中(payload 为被点击的 CardComp 实例,用于其他卡牌联动隐藏 call_btn) */ + CardSelected = "CardSelected", UseHeroCard = "UseHeroCard", UseSkillCard = "UseSkillCard", UseSpecialCard = "UseSpecialCard", diff --git a/assets/script/game/map/CardComp.ts b/assets/script/game/map/CardComp.ts index 5195956c..85d80f93 100644 --- a/assets/script/game/map/CardComp.ts +++ b/assets/script/game/map/CardComp.ts @@ -135,10 +135,8 @@ export class CardComp extends CCComp { * 防止快速切卡时旧回调错误覆盖新图标。 */ private iconVisualToken: number = 0; - /** 是否触发了长按 */ - private isLongPressed: boolean = false; - /** 长按触发时间(秒) */ - private readonly LONG_PRESS_DURATION: number = 0.5; + /** 视为"点击"的最大位移阈值(像素),小于该值视为点击而非拖拽 */ + private readonly tapMoveThreshold: number = 10; // ======================== 生命周期 ======================== @@ -154,7 +152,8 @@ export class CardComp extends CCComp { this.opacityComp.opacity = 255; this.updateLockUI(); this.applyEmptyUI(); - + // call_btn 默认隐藏,仅在点击本卡时显示 + this.hideCallBtn(); } /** 组件销毁时解绑所有事件,防止残留回调 */ @@ -448,6 +447,7 @@ export class CardComp extends CCComp { this.node.setScale(new Vec3(1, 1, 1)); this.updateLockUI(); this.applyEmptyUI(); + this.hideCallBtn(); this.node.active = false; } @@ -461,6 +461,10 @@ export class CardComp extends CCComp { this.node.on(NodeEventType.TOUCH_CANCEL, this.onCardTouchCancel, this); this.Lock?.on(NodeEventType.TOUCH_END, this.onToggleLock, this); this.unLock?.on(NodeEventType.TOUCH_END, this.onToggleLock, this); + // 召唤按钮点击 = 使用卡牌 + this.call_btn?.on(NodeEventType.TOUCH_END, this.onCallBtnClick, this); + // 监听跨卡联动:其他卡牌被点击时隐藏本卡 call_btn + oops.message.on(GameEvent.CardSelected, this.onOtherCardSelected, this); } /** 解绑触控,防止节点销毁后残留回调 */ @@ -477,19 +481,20 @@ export class CardComp extends CCComp { if (this.unLock && this.unLock.isValid) { this.unLock.off(NodeEventType.TOUCH_END, this.onToggleLock, this); } + if (this.call_btn && this.call_btn.isValid) { + this.call_btn.off(NodeEventType.TOUCH_END, this.onCallBtnClick, this); + } + oops.message.off(GameEvent.CardSelected, this.onOtherCardSelected, this); } // ======================== 触摸交互 ======================== - /** 触摸开始:记录起点 Y,进入拖拽状态 */ + /** 触摸开始:记录起点坐标,进入拖拽状态 */ private onCardTouchStart(event: EventTouch) { if (!this.cardData || this.isUsing) return; this.touchStartY = event.getUILocation().y; this.touchStartX = event.getUILocation().x; this.isDragging = true; - this.isLongPressed = false; - this.unschedule(this.onLongPress); - this.scheduleOnce(this.onLongPress, this.LONG_PRESS_DURATION); } /** @@ -499,25 +504,15 @@ export class CardComp extends CCComp { if (!this.isDragging || !this.cardData || this.isUsing) return; const currentY = event.getUILocation().y; const deltaY = Math.max(0, currentY - this.touchStartY); - if (deltaY > 10) { - this.unschedule(this.onLongPress); - if (this.isLongPressed) { - this.isLongPressed = false; - oops.gui.remove(UIID.HInfo); - } - } - this.node.setPosition(this.restPosition.x, this.restPosition.y + deltaY, this.restPosition.z); } /** * 触摸结束: - * - 技能卡:点击即可使用 - * - 英雄卡/其他:上拉距离 >= dragUseThreshold → 视为"使用卡牌" - * - 否则视为"点击"或者"长按结束" + * - 上拉距离 >= dragUseThreshold → 视为"使用卡牌" + * - 位移很小(点击)→ 触发 onCardTap:显示 call_btn / 打开信息面板 / 通知其他卡牌联动 */ private onCardTouchEnd(event: EventTouch) { - this.unschedule(this.onLongPress); if (!this.isDragging || !this.cardData || this.isUsing) return; const endY = event.getUILocation().y; const endX = event.getUILocation().x; @@ -525,11 +520,6 @@ export class CardComp extends CCComp { const deltaX = endX - this.touchStartX; this.isDragging = false; - if (this.isLongPressed) { - this.isLongPressed = false; - oops.gui.remove(UIID.HInfo); - } - // 英雄卡保持上划使用 if (deltaY >= this.dragUseThreshold) { const used = this.useCard(); @@ -539,31 +529,70 @@ export class CardComp extends CCComp { return; } + // 位移小于阈值视为"点击" + if (Math.abs(deltaY) < this.tapMoveThreshold && Math.abs(deltaX) < this.tapMoveThreshold) { + this.onCardTap(); + return; + } + this.playReboundAnim(); } /** 触摸取消:回弹至原位 */ private onCardTouchCancel() { - this.unschedule(this.onLongPress); if (!this.isDragging || this.isUsing) return; this.isDragging = false; - if (this.isLongPressed) { - this.isLongPressed = false; - oops.gui.remove(UIID.HInfo); - } this.playReboundAnim(); } - /** 长按触发:英雄卡打开英雄信息预览面板 */ - private onLongPress() { - if (!this.isDragging || this.isUsing) return; - if (!this.cardData || this.card_type !== CardType.Hero) return; - this.isLongPressed = true; - const heroUuid = this.card_uuid; - const heroLv = Math.max(1, this.cardData.hero_lv ?? 1); - const poolLv = Math.max(1, this.cardData.base_pool_lv ?? this.cardData.pool_lv ?? 1); - oops.gui.remove(UIID.HInfo); - oops.gui.open(UIID.HInfo, { heroUuid, heroLv, poolLv }); + /** + * 卡牌被点击(非拖拽): + * 1. 显示本卡的召唤按钮 call_btn。 + * 2. 派发 CardSelected 事件,其他卡牌收到后隐藏各自的 call_btn。 + * 3. 英雄卡打开 HInfo 信息面板(点击查看,替代原长按)。 + */ + private onCardTap() { + this.playReboundAnim(); + this.showCallBtn(); + oops.message.dispatchEvent(GameEvent.CardSelected, this); + // 英雄卡打开信息面板(点击替代长按) + if (this.card_type === CardType.Hero) { + const heroUuid = this.card_uuid; + const heroLv = Math.max(1, this.cardData?.hero_lv ?? 1); + const poolLv = Math.max(1, this.cardData?.base_pool_lv ?? this.cardData?.pool_lv ?? 1); + oops.gui.remove(UIID.HInfo); + oops.gui.open(UIID.HInfo, { heroUuid, heroLv, poolLv }); + } + } + + /** + * 其他卡牌被点击时联动隐藏本卡 call_btn。 + * @param event 事件名(ListenerFunc 约定的第一个参数) + * @param source 被点击的 CardComp 实例 + */ + private onOtherCardSelected(event: string, source: CardComp) { + if (source === this) return; + this.hideCallBtn(); + } + + /** 显示召唤按钮 */ + private showCallBtn() { + if (this.call_btn && this.call_btn.isValid) { + this.call_btn.active = true; + } + } + + /** 隐藏召唤按钮 */ + private hideCallBtn() { + if (this.call_btn && this.call_btn.isValid) { + this.call_btn.active = false; + } + } + + /** 召唤按钮点击回调:阻止冒泡后触发使用卡牌 */ + private onCallBtnClick(event: EventTouch) { + event.propagationStopped = true; + this.useCard(); } /**