带有孩子的CCNode上的Cocos2d-iphone v3触摸事件检测

Tib*_*ari 2 iphone cocos2d-iphone ios

我有一个CCNode包含多个CCSprite孩子的.

如果有任何孩子被触摸过,我想在父母 那里接受触摸事件CCNode.

蛋糕

这种行为似乎应该得到支持,我可能会遗漏一些东西.

我的解决方案是setUserInteractionEnabled = YES对所有孩子进行宣传,并将事件告知父母.

我通过继承CCSprite类重写他们的方法来做到这一点:

- (void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    [super touchBegan:touch withEvent:event];
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有更优雅,简单和通用的方法来完成相同的行为?

Mar*_*ark 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;
}
Run Code Online (Sandbox Code Playgroud)

编辑:只是为了清楚,然后您只需要setUserInteractionEnabled容器,并且只使用包含节点的触摸事件来处理触摸.

edit2:所以,我想了一下,这里有一个你可以添加的快速类别,它可以递归地对节点的所有子节点进行快速命中测试.

CCNode + CCNode_RecursiveTouch.h

#import "CCNode.h"
@interface CCNode (CCNode_RecursiveTouch)
{
}
-(BOOL) hitTestWithWorldPos:(CGPoint)worldPos forNodeTree:(id)parentNode shouldIncludeParentNode:(BOOL)includeParent;

@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

用法只是..在包含类中,覆盖hitTestWithWorldPos,如下所示:

-(BOOL) hitTestWithWorldPos:(CGPoint)pos
{
    BOOL hit = NO;
    hit = [self hitTestWithWorldPos:pos forNodeTree:self shouldIncludeParentNode:NO];
    return hit;
}
Run Code Online (Sandbox Code Playgroud)

当然,不要忘记包含类别标题.