触摸机制的不合理

首先说现象:
1,最顶层的对象设置了多点触摸,然后下面的对象设置了单点触摸,同样的设置方式和优先级,结果却是下面的对象触发而不是最顶层的触发。
2,为一个精灵设置了触摸,可结果是不管有没有点中精灵都会触发。

个人点评:
上面这两种现象绝对是不合理的,对于第1种,合理的绝对应该是最顶层的触发,而不是被覆盖的下面那层被触发。
对于第2种,我想人人都可以理解要点中才触发,不点中不触发,不能是不管点没点中都触发。

为什么会出现上面那样的不合理现象:
坑,至于为什么,肯定得去跟源码,通过大概的跟踪我发现触摸的机制大概是这样的(没有跟踪得很仔细,有错误欢迎指正):
当触摸发生时,cocos会把触摸事件用循环发给所有注册了触摸事件的对象,当然在分发时会判断当前对象是否被停用等。
在分发时cocos不会去自动判断这个触摸是不是作用在当前对象上面的,反正活动的都会触发,这就产生了第2种现象。
cocos依据对象的 onTouchBegan 函数返回真或假 来判断这个触摸是不是命中了当前对象,如果这个函数返回假,那么代表没命中,cocos会继续循环分发给下一个注册对象,如果这个对象返回了真,那么代表这个触摸命中了当前对象。
说了这么多,第2种现象就明了,实际上就是cocos并不会判断触摸是命中了哪个对象,它就是一个循环全部发出去,它让你自己在 onTouchBegan 函数中进行判断,并且通过返回值来告诉它是不是命中了当前对象。所以手动解决方法也不用说了,自己在这个函数中进行判断并返回即可。
虽然解决起来并不是非常麻烦,但这个东西暴露出以下几个问题:
第一,如上面所说,这个按常理肯定是不合理的,所以没深入理解,或者没去跟源码的,或者新手,都会以常理来想,这个应该要是命中才触发,不命中不触发的。而当实际情况不如所想那样后,给使用者造成了困惑和麻烦。
第二,其实你们cocos团队内部也是认为这个命中测试是该由引擎来判断而不是由我们用户来判断的,所以你们的cocosstudio控件都把测试代码写在了 Widget::onTouchBegan() 里以实现自动判断而不是用户判断。 但这样也产生了不一致性,有些控件自动判断,有些控件用户判断。同一控件,cocosstudio注册的自动判断,手动代码注册的用户判断。
第三,这个要改成合理的,也就是由cocos来判断而非用户判断,其实并不难,相反很容易,并且你们也早做到了,如上面第二所说。但你们为什么不改得彻底统一一点呢?

接下来再来说造成第1种不合理现象的原因,那是因为cocos在分发触摸事件时,用的是两个循环,单击触摸一个循环,多点触摸一个循环,并且在循环时代码是先进行单击循环,所以结果可想而知,当同时点中两个对象时,cocos会先判断下面的对象的单击触摸是不是命中了,而根本不会去判断对象间有没有覆盖的情况。这个东西要改起来不像第2种那样好解决,但实际上也不难实现。

其实使用中碰到好多这样类似的问题,每次我都懒得打字,这不,两个小小问题一打就是这么多字,希望cocos能引起重视,如果我说的是真的存在的,就改过来,
当然,也有可能是我理解有误,如果是的话也欢迎指正。

光就触摸这一个问题上,我本来还要说第3种不合理现象的,限于篇幅先不说了,

第3种不合理现象:
用同样的方法设置了同样的触摸的两个对象A和B,A在最顶层,B被覆盖在下面,触摸都是不可传递的。
正常情况下,都是A触发,而B因为被覆盖了,所以B不会触发。这个很好理解,也正常。
但是,
如果最上面的A被禁用了,或者A没有注册触摸事件呢?我们先想想win窗体的上的两个重叠按钮,当上面的被禁用后,是不是应该点击上面的没效果,同时也不会穿透触发被覆盖的下面的按钮?而cocos的结果就是,B会被触发。
造成这个原因的上面的源码分析说了,就是因为触摸发生时,cocos就是一股脑的把触摸事件用循环发给所有注册了触摸事件的对象上面,至于有没有被命中我不管,你们对象自己判断自己说了算,你们如果说这个触摸是命中你了,那我就不继续往下传了,如果你们说这个触摸没命中你,我就接着循环往下面传,并且有没有覆盖等情况我也完全不管,所以即使你对象的上面覆盖了一万层对象,但它们没在我这注册对我来说就是不存在的,这个点击只要在你的范围内依然可命中。。。

解决方法,用户不仅要判断点击有没有命中对象,还要判断对象有没有被别的对象所覆盖。。。那么引擎干嘛的?引擎只管一个循环全分发,别的不管。

不认同楼主的观点,原因如下:
1.引擎只提供最简单、最基础的实现,不应该提供复杂的逻辑处理,
因此,引擎只分发触摸事件,至于listener如何处理这个触摸事件是listener的事件。UI控件就是为这个后续的逻辑处理而生的。
就这一点而言,楼主的2、3点纯属吐槽;

2.对于第一点,引擎确实是先处理单点触摸事件,再处理多点触摸事件;其实引擎完全可以把单点触摸事件移除掉,
单点触摸是多点触摸的一个特例。
如果楼主在触摸屏上调试多触摸事件,你会发现多点触摸永远都是先触发单点触摸再触发多点触摸。因为人的手很难同时按下,总会有一个先后的问题。
例如第一个手指按下是在0秒,第二个手指按下是在0.01秒,那么事件的产生顺序是:单点->多点。而人感觉是2个手指同时按下的,其实不然。

1,引擎只提供最简单最基础的实现?这里的命中测试和覆盖测试就是最最基础最简单的实现,拿人人都用过的win来说,鼠标点击的命中测试和覆盖测试都封装到api里,别的系统也是。并且命中测试在官方的cocosstudio控件中也实现了,那按你这么说官方cocosstudio实现了做什么?为什么不还是交由用户来实现?并且命中测试可以说是99%的情况下都要实现的,只是由引擎实现和用户实现的区别,并且实现的方式基本也相同,那么对于99%都会要实现的东西为什么不引擎实现而要用户来实现?因此cocosstudio也是引擎实现的。
2,你所说什么先单点后多点什么的,写过多点的都知道都理解,这个东西不需要科普,我主题所讲的问题是如果A对象在最顶层是多点触摸,B对象被覆盖在下层是单点触摸,都为不可传递(绝大多数情况下都是只触发一个的不可传递方式),那么引擎会只触发被覆盖的在下面的B,而最顶层的A却不会触发,你说说这合理?
3,你说我的2,3点纯属吐槽,我看你完全没看我的主题的吐槽。

补充:归你这个逻辑来的话,在win上编程,当鼠标被按下时,我们程序员还需要根据鼠标的坐标来计算是不是命中了自己的当前窗体,计算到底是命中的窗体上的哪个控件?这才合理?

我觉得这个没不合理啊,是你自己用法不合理,B在A下面,按照你说的A开触摸时只响应A,A没触摸时B也不能响应触摸,那问一句,你干嘛还给B加触摸,反正怎样它都不该响应触摸

我举例只是为了把问题说明显,完全覆盖当然不应该加,你仔细想想不完全覆盖,而是部分覆盖的情况,是不是很常见???
就以精灵来说的话,精灵不是固定的是可移动的,最开始A精灵可能和B完全不重叠,但运行后由于移动产生的全部或者部分重叠不常见???

你就当我没说过

相反的情况也不少见,比如子弹打到人身上,这时候我要点子弹的位置人还响应而不是没反应。
所以这种东西不应该让引擎写死,现在你想遮掉可以给子弹加屏蔽,如果按你那种改,我想不屏蔽的时候都没法处理了

你专挑个别的点来反驳,其实我知道你的现在的思想是,首先完全认为引擎都是正确合理的,而没有去想是不是真的合理,然后你拼命所想的是如何组织语言来反驳,
首先引擎肯定不是都合理的,因此才有这么多人吐槽,因此引擎团队才会不停的更新和完善,没有任何一个程序没bug

然后再回到你的问题上,你所指的这个点确实存在,但我所举的并不只有这一个点,光就你这一个点来说,这属于子弹未注册事件的可穿透行为,确实合理,
但我主题里还举了一个不是未注册,而是禁用。cocosstudio按钮等可禁用,本来这个按钮是注册了事件的,但禁用后不等同于 未注册 ,同样的cocosstudio 里为这两个属性也是提供的两种不同的属性,一是“可交互” 一是 “禁用” , 这点同样可以比较通俗的联想到 win 窗体上的 按钮禁用 难道上面的按钮禁用了,就会穿透到下面?

cocos 优秀的地方大家也知道,不然大家也不会用,
但 cocos 不完善和地方也肯定有,这个没任何人敢否定,cocos每次更新版本和修改bug就是最好的证明
其实cocos 不完善的地方相对来说还是不少的,这个大家应该也看得到,所以经常有修改引擎什么的
我发觉这个论坛的氛围真心不怎么的,引用别的帖子里的人经常说过的,这里大多就是以下几种:
一是纯新手型的提问方式
二是没太研究源码没去仔细研究引擎的纯喷纯吐槽形式
而对于那些有了一定的入门基础的人之后真心很少来论坛,都自己改引擎研究什么的

我这个贴并不是纯喷,我也跟踪并且先了解了引擎到底是怎么做的,为什么会产生那些现象后来发表的关于这种不合理的感想。
确实对于那些已经了解和入门了的人来说,也肯定了解了,并且也知道该怎么做了,比如解决上面的办法是自己添加命中测试代码等,这点我也能办到,也能解决,但我为什么还来发帖呢?
因为我是希望引擎本身变得更完善。
就以命中测试这点来说,我敢说新手,包括现在已经了解的使用者在第一次使用时,肯定都会认为是要 命中才触发 ,而不是不管命不命中都触发,要由自己来测试是不是命中。这一点大家扪心自问是不是?

但这论坛往往的结局都是只要有说引擎不好方面的都会一律被喷,说什么你不会用什么的。如果真是这样,说实话,发一个贴我没任何好处,相反,不发帖我还可以少打N多字,少浪费N多时间。

楼主码字辛苦了…按我个人的理解是,引擎不可能考虑到所有的情况,满足所有人的需求。

既然studio已经做到自动判断了,那么想用自动判断的直接使用studio那套即可。

用户的需求总是各种各样的,我感觉保留一套用户手动判断的并没有什么不好。

关于在论坛说引擎不好,会被喷?这个我真没遇到过。感觉只要喷的有理,下面都是和你讨论的。

除了那些莫名其妙,没有一点原因说明的。

作为版主其实我还是很喜欢楼主这种帖子的。任何东西总是在被喷的过程中成长,如果哪天没有任何人来喷那个东西,那么只能呵呵了…

欢迎楼主多发点这类帖子,只要你喷的有理…都欢迎。:7::7: