我有一个CCNode
,其中包含多个CCSprite
个孩子。
如果有任何孩子被触及,我希望在我的父母 CCNode
中接收触摸事件。
这种行为似乎应该得到支持,我可能会遗漏一些东西。
我的解决方案是setUserInteractionEnabled = YES
所有孩子,并将事件冒充到父母。
我这样做是通过继承CCSprite
类来覆盖他们的方法:
- (void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
[super touchBegan:touch withEvent:event];
}
我想知道是否有更优雅,简单和通用的方法来完成相同的行为?
答案 0 :(得分:7)
您可以覆盖'包含'的hitTestWithWorldPos:
节点,在特定子节点上调用hitTestWithWorldPos
,或者按照您认为合适的方式遍历所有子节点。也许是这样的:
-(BOOL) hitTestWithWorldPos:(CGPoint)pos
{
BOOL hit = NO;
hit = [super hitTestWithWorldPos:pos];
for(CCNode *child in self.children)
{
hit |= [child hitTestWithWorldPos:pos];
}
return hit;
}
编辑:只是为了清楚,然后你只需要setUserInteractionEnabled
容器,并且只使用包含节点的触摸事件来处理触摸。
EDIT2: 所以,我想了一下,这里有一个你可以添加的快速类别,可以递归地对节点的所有孩子进行快速命中测试。
<强> CCNode + CCNode_RecursiveTouch.h 强>
#import "CCNode.h"
@interface CCNode (CCNode_RecursiveTouch)
{
}
-(BOOL) hitTestWithWorldPos:(CGPoint)worldPos forNodeTree:(id)parentNode shouldIncludeParentNode:(BOOL)includeParent;
@end
<强> CCNode + CCNode_RecursiveTouch.m 强>
#import "CCNode+CCNode_RecursiveTouch.h"
@implementation CCNode (CCNode_RecursiveTouch)
-(BOOL) hitTestWithWorldPos:(CGPoint)worldPos forNodeTree:(id)parentNode shouldIncludeParentNode:(BOOL)includeParent
{
BOOL hit = NO;
if(includeParent) {hit |= [parentNode hitTestWithWorldPos:worldPos];}
for( CCNode *cnode in [parentNode children] )
{
hit |= [cnode hitTestWithWorldPos:worldPos];
(cnode.children.count)?(hit |= [self hitTestWithWorldPos:worldPos forNodeTree:cnode shouldIncludeParentNode:NO]):NO; // on recurse, don't process parent again
}
return hit;
}
@end
用法只是..在包含类中,覆盖hitTestWithWorldPos如下:
-(BOOL) hitTestWithWorldPos:(CGPoint)pos
{
BOOL hit = NO;
hit = [self hitTestWithWorldPos:pos forNodeTree:self shouldIncludeParentNode:NO];
return hit;
}
当然,不要忘记包含类别标题。
答案 1 :(得分:1)
-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
//Do whatever you like...
//Bubble the event up to the next responder...
[[[CCDirector sharedDirector] responderManager] discardCurrentEvent];
}