在 cocos2d 中判断互相重叠的 CCMenuItem
单独窗口打印放大字号缩小字号
cocos2d 提供的 CCMenu、CCMenuItem、CCMenuItemImage、CCMenuItemSprite 等类是构造菜单和按钮的常用工具类。不过 cocos2d 的 CCMenu 在判断互相重叠的 CCMenuItem 时存在一点小问题。
假设有三个按钮,如下图所示:
当玩家点击时,如果点击位置在 PLAY 按钮和另外两个按钮重叠的地方,那么总是 PLAY 按钮生效。出现这种情况的原因是 CCMenu 按照 CCMenuItem 添加的顺序来依次判断,PLAY 是第一个添加到 CCMenu 中的 CCMenuItem 对象,所以会忽略掉重叠区域的其他按钮。
要解决这个问题,需要从 CCMenu 派生一个继承类 CCMenuEx:
CCMenuEx.h
#import "cocos2d.h" @interface CCMenuEx : CCMenu { } @end
CCMenuEx.m
#import "CCMenuEx.h" @implementation CCMenuEx -(CCMenuItem *) itemForTouch: (UITouch *) touch { CGPoint touchLocation = [touch locationInView: [touch view]]; touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation]; CCMenuItem* item = nil; CCMenuItem* hitItem = nil; CCARRAY_FOREACH(children_, item){ if ( [item visible] && [item isEnabled] ) { if (CGRectContainsPoint([item rect], touchLocation)) { if (hitItem) { if ([hitItem zOrder] < item.zOrder) { hitItem = item; } } else { hitItem = item; } } } } return hitItem; } @end
最后在应用程序中将构造 CCMenu 对象的代码改为使用 CCMenuEx 即可。
CCMenuEx 不但判断点击位置是否在按钮上,还会判断按钮的叠放次序。在多个按钮重叠区域点击时,最上面的按钮会被触发。