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

Posted

技术标签:

【中文标题】带有子节点的 CCNode 上的 Cocos2d-iphone v3 触摸事件检测【英文标题】:Cocos2d-iphone v3 touch event detection on CCNode with children 【发布时间】:2014-02-07 13:16:32 【问题描述】:

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

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

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

我的解决方案是在所有孩子setUserInteractionEnabled = YES,然后将事件冒泡给父母。

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

- (void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event

    [super touchBegan:touch withEvent:event];

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

【问题讨论】:

【参考方案1】:

您可以覆盖您的“包含”节点的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,并且只使用包含节点的触摸事件处理触摸。

编辑2: 所以,我想了更多,这里有一个快速类别,你可以添加它,它可以递归地对节点的所有子节点进行快速命中测试。

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;

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

【讨论】:

【参考方案2】:
-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event



    //Do whatever you like...

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



【讨论】:

以上是关于带有子节点的 CCNode 上的 Cocos2d-iphone v3 触摸事件检测的主要内容,如果未能解决你的问题,请参考以下文章

无法检测到 CCNode 上的触摸 - cocos2d v3.0

CCNode删除不起作用的Cocos2d

用另一个 CCSprite/CCNode 剪辑 CCSprite/CCNode - Cocos2D

可拖动 CCNode Cocos2d

CCNode 内部元素的定位

CCNode递归getChildByTag