2014-02-07 53 views
2

我有一個CCNode包含多個CCSprite孩子。CCNode與兒童Cocos2d-iphone v3觸摸事件檢測

我想在我的父母CCNode中接收觸摸事件,如果有任何孩子被觸摸過。

cake

這種行爲好像就應該得到支持,我可能失去了一些東西。

我的解決方案是對所有子女setUserInteractionEnabled = YES,並將事件向上冒泡。

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

我想知道是否有實現相同的行爲更優雅,簡單和通用的方式:

我通過繼承CCSprite類中重寫他們的方法做到這一點?

回答

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
-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event 

{ 

    //Do whatever you like... 

    //Bubble the event up to the next responder... 
    [[[CCDirector sharedDirector] responderManager] discardCurrentEvent]; 


}