feat(map): 为英雄信息弹窗和卡牌组件添加点击外部关闭交互
1. 全局添加触摸结束监听,实现点击弹窗/卡牌外区域自动关闭/隐藏控件 2. 通过包围盒检测避免误触内部元素,无需额外遮罩节点 3. 统一管理事件的绑定与解绑,防止内存泄漏
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
* - smc.vmdata.mission_data —— 读写局内金币
|
||||
*/
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { _decorator, Animation, AnimationClip, EventTouch, Label, Node, NodeEventType, Sprite, SpriteAtlas, Tween, tween, UIOpacity, Vec3, resources, Light, UITransform, Widget } from "cc";
|
||||
import { _decorator, Animation, AnimationClip, EventTouch, Input, Label, Node, NodeEventType, Sprite, SpriteAtlas, Tween, tween, UIOpacity, Vec3, input, resources, Light, UITransform, Widget } 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 { CardConfig, CardType, SpecialRefreshCardList, SpecialUpgradeCardList, CKind, CardPoolList } from "../common/config/CardSet";
|
||||
@@ -485,6 +485,8 @@ export class CardComp extends CCComp {
|
||||
this.call_btn.off(NodeEventType.TOUCH_END, this.onCallBtnClick, this);
|
||||
}
|
||||
oops.message.off(GameEvent.CardSelected, this.onOtherCardSelected, this);
|
||||
// 兜底注销全局触摸监听(showCallBtn 后组件销毁的场景)
|
||||
input.off(Input.EventType.TOUCH_END, this.onGlobalTouchEnd, this);
|
||||
}
|
||||
|
||||
// ======================== 触摸交互 ========================
|
||||
@@ -579,6 +581,8 @@ export class CardComp extends CCComp {
|
||||
private showCallBtn() {
|
||||
if (this.call_btn && this.call_btn.isValid) {
|
||||
this.call_btn.active = true;
|
||||
// 按需监听全局触摸:点击本体以外区域时隐藏召唤按钮
|
||||
input.on(Input.EventType.TOUCH_END, this.onGlobalTouchEnd, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,6 +591,27 @@ export class CardComp extends CCComp {
|
||||
if (this.call_btn && this.call_btn.isValid) {
|
||||
this.call_btn.active = false;
|
||||
}
|
||||
// 注销全局监听(无论是否曾注册,off 均安全)
|
||||
input.off(Input.EventType.TOUCH_END, this.onGlobalTouchEnd, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局触摸结束:点击落点不在召唤按钮 / 卡牌本体包围盒内时隐藏召唤按钮。
|
||||
* Why: 复用 HInfoComp 的"点击外部关闭"交互模式,避免 call_btn 长期滞留。
|
||||
* 排除卡牌本体是防止与 onCardTap 的"点击卡牌显示 call_btn"交互相互冲突。
|
||||
* @param event 全局触摸事件
|
||||
*/
|
||||
private onGlobalTouchEnd(event: EventTouch) {
|
||||
if (!this.call_btn || !this.call_btn.active) return;
|
||||
const uiPos = event.getUILocation();
|
||||
// 命中召唤按钮本体 → 保留
|
||||
const btnTrans = this.call_btn.getComponent(UITransform);
|
||||
if (btnTrans && btnTrans.getBoundingBoxToWorld().contains(uiPos)) return;
|
||||
// 命中卡牌本体 → 保留(由 onCardTap 自行管理显隐)
|
||||
const cardTrans = this.node.getComponent(UITransform);
|
||||
if (cardTrans && cardTrans.getBoundingBoxToWorld().contains(uiPos)) return;
|
||||
// 其余区域 → 隐藏
|
||||
this.hideCallBtn();
|
||||
}
|
||||
|
||||
/** 召唤按钮点击回调:阻止冒泡后触发使用卡牌 */
|
||||
|
||||
Reference in New Issue
Block a user