cocos ceater 如何实现显示 Tip 的 同时能响应点击其他功能?
迪丽瓦拉
2024-06-02 06:16:17
0

前言

这篇文章主要是想记录一下,解决一个很常遇见通用型的问题,并且自己一直在这个问题上做了很多尝试,之前一直没有比较好的解决方案,这里分享一下,这其中的过程:


一、问题场景

首先我们先来看看这个问题的场景吧!(图片来自市面的一款游戏截图,有任何侵权,联系马上删除)
在这里插入图片描述

如上图,我们经常在游戏中会由一些宝箱或者排名,需要点击显示奖励内容的 Tip,同时我们还需要点击空白处隐藏宝箱的 Tip 的。那么你会如何实现呢?

二、解决方案

下面我是根据需求的变化来,不断讲述围绕上述问题的解决过程

1、阶段一

我先说说最初的解决,就是实现上述的问题,其实这里是很简单的,简单来说,我们有一个 Tip 的节点,这个节点默认 activefalse 的,当我们需要显示的时候,让他的 activetrue 就好了,但是我们需要开启之后,点击任意地方都会关闭这个 Tip ,这个要怎么实现呢?我这里开始的做法是,在 Tip 节点里面有一个 长宽都比活动界面大的节点,我这里把它称之为 back 节点,在 Tip 打开的时候,这个节点也会为 true ,然后我们监听这个节点,那么我们的任何点击都会被它监听到,那就能实现我们的操作了。具体我们来看下面的摆图和代码,就能一目了然了。

我们的图层就如下图摆放:
在这里插入图片描述

然后我们来看一看代码是如何运作的:
在这里插入图片描述

代码的实现就是如上图,前面的部分是设置 Tip 的显示奖励内容,和设置 位置的 ,而我们要实现点击空白处隐藏 Tip 是在后面获取到节点 back 开始的。我们给节点 back 添加事件监听,当我们点击任何地方,就会关闭 tip 。这时候算是完成我们的需求了

2、阶段二

但是我们的需求肯定不是到这里就为止了,后面我们的策划又提出新的想法,他 希望点击第一个宝箱之后,他点击第二个宝箱会马上出现第二个宝箱的 Tip ,这时候我就犯愁了,按照我们上面的写法,这里无论如何,显示了第一个 Tip 之后就会就出现一个 覆盖整个画面的 back 来拦截掉所有的点击,所以是没发点击马上显示第二个礼盒的 Tip ,必须关闭了第一个,再点击才会显示第二个。

但是策划的需求嘛,我们肯定得实现的,在时间紧急之下,所以我用了种很蠢的办法,我在 back 上面按照宝箱的位置有摆了一层透明的按键,那么就能点击这些按键就显示相应的 Tip ,然后还能保证点击空白处,也能隐藏 Tip,但是这种方式很蠢耶,这样我们点击按键的 过渡动画就不能用,还奇奇怪怪的。但赶时间嘛,能用就行了,不管了~~

3、阶段三

然后你以为这就完了?不,不可能的,策划嘛,就是不断给程序出难题的存在嘛,这天策划和我说,能不能显示 Tip 的同时,点击其他功能按键,也能关闭 Tip 同时响应功能按键 呀!天,我就知道这一天迟早会来的了!那么上面那种偷懒的方式就不行了,我总不能界面上所有的按键都摆上一层吧,而且这样还有可能存在的奇奇怪怪的问题。人嘛,被逼了总会有办法的,这时候才整出了我的最终解法。

我们回想一下 cocos 的事件传递,我们一般在使用中都是使用事件冒泡,事件一级级的往根节点传递(如果节点身上带有 Button、Toggle 或者 BlockInputEvents 这几个组件的话,是会停止事件冒泡),也是因为这里的事件拦截所以我们之前开启了 back 节点之后就没发点击其他节点了。那么,从下往上冒泡会被拦截,那么如果从上往下呢?灵机一动,这就成了我们解决问题的关键了!也就是我们的猪脚,事件捕捉,要启用事件铺抓很简单,只需要添加一个参数

// 给 node 注册触摸或鼠标事件时,传入第四个参数 true,表示 useCapture。例如:
this.node.on(Node.EventType.TOUCH_START, this.onTouchStartCallback, this, true);

当节点触发 touch-start 事件时,会先将 touch-start 事件派发给所有注册在捕获阶段的父节点监听器,然后派发给节点自身的监听器,最后才到了事件冒泡阶段。

所以解决我们这次的问题的思路就变为,我们在根节点的地方监听点击事件,然后判断 Tip 是否有打开,如果打开了的话就把它关了,事件依然是会继续传递,如果没有打开,那就也没问题呀。这里我们就能同时实现,不仅点击任何地方都能隐藏 Tip ,同时点击其他功能按键也能响应功能,同时隐藏 Tip 了。

但这里还有一个小问题,如显示 Tip 了,还去点击显示 Tip 的礼盒呢?这里就会出现 Tip 隐藏然后显示了,也就是会闪一下,因为我们的捕获阶段 监听到 Tip 打开了,所以把它关了,然后响应点击事件,又打开了,这里我们在点击显示 Tip 的函数上加个标签 ,保存点击显示 Tip 的 Node 节点,然后在捕获阶段判断这次点击的节点是否为同一个节点,是的话就跳过。这次摆图上我们不需要处理,就是代码上的处理:

下图就是在根节点加上捕获监听:
在这里插入图片描述
然后响应显示 Tip 的函数:

在这里插入图片描述

到此我们基本比较完美的解决显示 TIp 的问题啦!我们可以在显示 Tip 的同时响应其他功能,也能保证点击空白的地方也能关闭 Tip !

总结

对于我一个刚入职大半年来说,解决问题是非常有趣的,特别是想到更好的方法,很多时候我们没发一步就是最好的,往往是不断改进,这个过程,不仅是学习,也是经验积累的过程,我们解决一个问题也不应该有一种解决方案的放弃别的探索,因为实现某个东西是很简单的,但往往是有很多很多种方式去实现,那种是更适合的,才是关键,因为就像工具,没有最好的工具,只有最适合的哦~

相关内容