feat(map): 为英雄信息弹窗和卡牌组件添加点击外部关闭交互

1.  全局添加触摸结束监听,实现点击弹窗/卡牌外区域自动关闭/隐藏控件
2.  通过包围盒检测避免误触内部元素,无需额外遮罩节点
3.  统一管理事件的绑定与解绑,防止内存泄漏
This commit is contained in:
panFD
2026-06-20 21:59:29 +08:00
parent 3056b61ced
commit b7388615ed
2 changed files with 51 additions and 2 deletions

View File

@@ -19,7 +19,7 @@
* - Hero —— 英雄 ECS 实体类(用于出售删除)
* - UIID.IBox —— 英雄详情弹窗 ID
*/
import { _decorator, Animation, AnimationClip, Button, Event, Label, Node, NodeEventType, Sprite, resources, CCInteger, SpriteFrame } from "cc";
import { _decorator, Animation, AnimationClip, Button, Event, EventTouch, Input, Label, Node, NodeEventType, Sprite, UITransform, input, resources, CCInteger, SpriteFrame } 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 { HeroInfo } from "../common/config/heroSet";
@@ -532,6 +532,8 @@ export class HInfoComp extends CCComp {
this.sell_node?.on(Button.EventType.CLICK, this.onSellHero, this);
this.close_node?.on(Button.EventType.CLICK, this.onClosePanel, this);
// this.node.on(NodeEventType.TOUCH_END, this.onOpenIBox, this);
// 监听全局触摸结束:点击本体节点以外区域时关闭面板
input.on(Input.EventType.TOUCH_END, this.onGlobalTouchEnd, this);
}
private unbindEvents() {
@@ -544,6 +546,28 @@ export class HInfoComp extends CCComp {
// if (this.node && this.node.isValid) {
// this.node.off(NodeEventType.TOUCH_END, this.onOpenIBox, this);
// }
input.off(Input.EventType.TOUCH_END, this.onGlobalTouchEnd, this);
}
/**
* 全局触摸结束处理:点击落点不在本体节点包围盒内时关闭面板。
* Why: 弹窗常见的"点击空白处关闭"交互,用全局 input + 包围盒命中检测实现,
* 无需额外遮罩节点,也不会误关面板内部(含子按钮)的点击。
* @param event 全局触摸事件
*/
private onGlobalTouchEnd(event: EventTouch) {
if (this.isClosing) return;
const transform = this.node.getComponent(UITransform);
if (!transform) {
// 缺少 UITransform 时保守处理为关闭
this.onClosePanel();
return;
}
const worldRect = transform.getBoundingBoxToWorld();
const uiPos = event.getUILocation();
if (!worldRect.contains(uiPos)) {
this.onClosePanel();
}
}
/**