最近在Cocos2dx 2.x版本上实现了一套简单的按层级关系派发Touch消息的功能,改动的代码很少,与大家分享。
Cocos2d 3.0以前的版本没有实现按层派发Touch消息,但是这个功能在界面中被使用到的频率很高。目前网上的实现都需要借助额外的管理类,相当于要维护另外一份Touch层级的树形结构,虽然工作量不是太大,但是实现的方式还是有些怪异,所以我找了一种对不添加额外树形结构的实现方法,虽然有一些缺陷,但是只要按这个潜规则,也不会出问题。
下面简单介绍一下实现的步骤。
1. 当有需要按层级派发的Layer创建时,对该Layer register 一个TargetTouchDelegate,并且将所有的Touch都Return true。即当点击事件派发到这个Layer之后,就会被拦截。因为笔者是使用Lua来开发界面,所以这个功能我之用在showDialog时给Dialog(其实是一个Layer)注册同一个target lua callback就行。但是用C++会比较麻烦,需要继承自CCLayer,并重写registerTouchDispatcher()。
2. 将所有的Touch优先级都设置成一样,目前CCMenu的优先级最高,CCContrl的优先级最低,将这些都改为0,即Layer默认的Touch优先级。
3. 参考我这篇文章http://blog.csdn.net/yuanhong2910/article/details/13297629,不可见的Layer不处理Touch消息。
4. 需要注意的一点限制是,在某个Layer 正在显示时,不要调用setTouchEnable(true/false)来修改。TouchEnable属性在进入界面时就设置好。而且控件使用TargetTouchDelegate,不要使用StandardTouchDelegate。
上面4步之后,就实现了一套按层派发Touch的机制。下面解释一下为什么这么做就已经实现了。
1. 因为Touch派发的顺序时先Target,后Starndard,然后相同类型的先优先级高(数字小的),后优先级低。当优先级一样时,先注册的后调用。
2. 如果在进入界面前设置TouchEnable,对Touch的注册是在onEnter中注册的。所以如果Layer上的其他Children也有Touch事件,则Childer的Touch会比Layer先调用。当然,前提是Touch类型和优先级一样。
3. 当多个Dialog重叠时,原因同2,后显示的会先调用。
4. 因为不可见的精灵不响应,所以在界面上需要来回切换不同的显示时Touch响应不会有问题。
因为本篇文章在公司写的,而公司我没有cocos2d源代码,所以接口写的有问题请见谅。
That's all.