首先说现象:
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种不合理现象的,限于篇幅先不说了,
