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

时间:2014-02-07 13:16:33

标签: ios iphone cocos2d-iphone

我有一个CCNode,其中包含多个CCSprite个孩子。

如果有任何孩子被触及,我希望在我的父母 CCNode中接收触摸事件。

cake

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

我的解决方案是setUserInteractionEnabled = YES所有孩子,并将事件冒充到父母。

我这样做是通过继承CCSprite类来覆盖他们的方法:

- (void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    [super touchBegan:touch withEvent:event];
}

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

2 个答案:

答案 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];


}