2 Commits

Author SHA1 Message Date
panFD
b7388615ed feat(map): 为英雄信息弹窗和卡牌组件添加点击外部关闭交互
1.  全局添加触摸结束监听,实现点击弹窗/卡牌外区域自动关闭/隐藏控件
2.  通过包围盒检测避免误触内部元素,无需额外遮罩节点
3.  统一管理事件的绑定与解绑,防止内存泄漏
2026-06-20 21:59:29 +08:00
panFD
3056b61ced fix: 修复战斗相关UI显示与技能配置问题
1. 调整RPG地图预制件与UI元素的激活状态,修复战斗面板显示异常
2. 移除技能卡片多余的t_times配置项,简化技能触发逻辑
3. 优化战斗结束后战斗框的显隐控制
2026-06-20 17:53:04 +08:00
6 changed files with 70 additions and 19 deletions

View File

@@ -12044,6 +12044,8 @@
"__id__": 0
},
"fileId": "8aR4+WXvRJrJfyR9Sp7SqP",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
@@ -21745,7 +21747,7 @@
"__id__": 977
}
],
"_active": true,
"_active": false,
"_components": [
{
"__id__": 1053

View File

@@ -3182,7 +3182,7 @@
"__id__": 1
},
"_children": [],
"_active": true,
"_active": false,
"_components": [
{
"__id__": 141
@@ -3378,9 +3378,7 @@
"bg_node": {
"__id__": 2
},
"info_label": {
"__id__": 143
},
"info_label": null,
"cd_mask": {
"__id__": 132
},

View File

@@ -207,12 +207,12 @@ const SkillCardData: any[] = [
{ uuid: 8758, skill: 0, wave: SKILL_CARD_WAVES[1], name: "风怒加成+", info: "英雄风怒概率+20%", is_inst: false, keep_waves: -1, field: [7208], trigger_type: CardTriggerType.Field },
{ uuid: 8759, skill: 0, wave: SKILL_CARD_WAVES[1], name: "穿刺加成+", info: "英雄穿刺概率+20%", is_inst: false, keep_waves: -1, field: [7209], trigger_type: CardTriggerType.Field },
// --- 范围攻击卡ap 递增,间隔缩短) ---
{ uuid: 8261, skill: 6201, wave: SKILL_CARD_WAVES[1], name: "雷墙+", info: "召唤雷墙阻挡敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8262, skill: 6202, wave: SKILL_CARD_WAVES[1], name: "火墙+", info: "召唤火墙阻挡敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8263, skill: 6203, wave: SKILL_CARD_WAVES[1], name: "飓风+", info: "召唤飓风攻击敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8264, skill: 6204, wave: SKILL_CARD_WAVES[1], name: "水墙+", info: "召唤水墙阻挡敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8265, skill: 6205, wave: SKILL_CARD_WAVES[1], name: "风墙+", info: "召唤风墙困住敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8266, skill: 6206, wave: SKILL_CARD_WAVES[1], name: "陨石术+", info: "召唤陨石范围攻击敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8261, skill: 6201, wave: SKILL_CARD_WAVES[1], name: "雷墙+", info: "召唤雷墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8262, skill: 6202, wave: SKILL_CARD_WAVES[1], name: "火墙+", info: "召唤火墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8263, skill: 6203, wave: SKILL_CARD_WAVES[1], name: "飓风+", info: "召唤飓风攻击敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8264, skill: 6204, wave: SKILL_CARD_WAVES[1], name: "水墙+", info: "召唤水墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8265, skill: 6205, wave: SKILL_CARD_WAVES[1], name: "风墙+", info: "召唤风墙困住敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8266, skill: 6206, wave: SKILL_CARD_WAVES[1], name: "陨石术+", info: "召唤陨石范围攻击敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8760, skill: 0, wave: SKILL_CARD_WAVES[1], name: "金币收益+", info: "每回合金币收益+2", is_inst: false, keep_waves: -1, field: [7210], trigger_type: CardTriggerType.Field },
@@ -232,12 +232,12 @@ const SkillCardData: any[] = [
{ uuid: 8808, skill: 0, wave: SKILL_CARD_WAVES[2], name: "风怒加成++", info: "英雄风怒概率+30%", is_inst: false, keep_waves: -1, field: [7408], trigger_type: CardTriggerType.Field },
{ uuid: 8809, skill: 0, wave: SKILL_CARD_WAVES[2], name: "穿刺加成++", info: "英雄穿刺概率+30%", is_inst: false, keep_waves: -1, field: [7409], trigger_type: CardTriggerType.Field },
{ uuid: 8361, skill: 6201, wave: SKILL_CARD_WAVES[2], name: "雷墙++", info: "召唤雷墙阻挡敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8362, skill: 6202, wave: SKILL_CARD_WAVES[2], name: "火墙++", info: "召唤火墙阻挡敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8363, skill: 6203, wave: SKILL_CARD_WAVES[2], name: "飓风++", info: "召唤飓风攻击敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8364, skill: 6204, wave: SKILL_CARD_WAVES[2], name: "水墙++", info: "召唤水墙阻挡敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8365, skill: 6205, wave: SKILL_CARD_WAVES[2], name: "风墙++", info: "召唤风墙困住敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8366, skill: 6206, wave: SKILL_CARD_WAVES[2], name: "陨石术++", info: "召唤陨石范围攻击敌人,有概率击晕", is_inst: false, t_times: 999, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8361, skill: 6201, wave: SKILL_CARD_WAVES[2], name: "雷墙++", info: "召唤雷墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8362, skill: 6202, wave: SKILL_CARD_WAVES[2], name: "火墙++", info: "召唤火墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8363, skill: 6203, wave: SKILL_CARD_WAVES[2], name: "飓风++", info: "召唤飓风攻击敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8364, skill: 6204, wave: SKILL_CARD_WAVES[2], name: "水墙++", info: "召唤水墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8365, skill: 6205, wave: SKILL_CARD_WAVES[2], name: "风墙++", info: "召唤风墙困住敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8366, skill: 6206, wave: SKILL_CARD_WAVES[2], name: "陨石术++", info: "召唤陨石范围攻击敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8810, skill: 0, wave: SKILL_CARD_WAVES[2], name: "金币收益++", info: "每回合金币收益+3", is_inst: false, keep_waves: -1, field: [7410], trigger_type: CardTriggerType.Field },

View File

@@ -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();
}
/** 召唤按钮点击回调:阻止冒泡后触发使用卡牌 */

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();
}
}
/**

View File

@@ -196,10 +196,12 @@ export class MissionComp extends CCComp {
this.mission_start();
}, 0);
smc.map.MapView.scene.mapLayer.stopAnimations();
smc.map.MapView.scene.mapLayer.node.getChildByName("fight").getChildByName("fbox").active = true;
}
onDestroy() {
smc.map.MapView.scene.mapLayer.playAnimations()
smc.map.MapView.scene.mapLayer.node.getChildByName("fight").getChildByName("fbox").active = false;
super.onDestroy();
if (this.start_btn && this.start_btn.isValid) {
this.start_btn.off(NodeEventType.TOUCH_END, this.onStartFightBtnClick, this);