如何点击父节点?

时间:2015-04-03 23:34:09

标签: ios objective-c sprite-kit simulator zposition

我搜索了SO并尝试了几个例子,但我仍然无法理解这种行为。在模拟器7.1上直通工作,但在8.1上不起作用。我之前也问过类似的问题,但不一样,我用nodesAtPoint方法解决了它,然后通过所有节点循环并检查节点名称/类。但是这有所不同,因为现在我使用自定义Button类来实现touchesBegan,我希望它能够检测并且如果可能的话“吞下”触摸。

所以我有一个简单的Button类,它是SKSpriteNode的子类,它有自己的touchesBegan和userInteractionEnabled = YES。在我的视图中,控制器属性ignoreSiblingsOrder设置为YES

这是一个(简化的)示例,它可以产生所描述的行为:

#import "GameScene.h"

@interface Button : SKSpriteNode
-(instancetype)initWithColor:(UIColor *)color size:(CGSize)size;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
@end


@implementation Button
-(instancetype)initWithColor:(UIColor *)color size:(CGSize)size {
    self = [super initWithColor:color size:size];
    self.userInteractionEnabled = YES;
    return self;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"%@ hit", self.name);
}
@end

@implementation GameScene

-(id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]) {

        self.userInteractionEnabled = NO;

        SKNode* root = [SKNode new];
        root.name = @"root";
        SKNode* layer1 = [SKNode new];
        SKNode* layer2 = [SKNode new];

        layer1.zPosition = -1;//layer1 and layer2 are just containers
        layer2.zPosition = -2;


        Button* button = [Button spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(100, 100)];
        button.name = @"yellow button";
        button.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));

        [layer1 addChild:button];

        [root addChild:layer1];
        [root addChild:layer2];

        [self addChild:root];

    }
    return self;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"Touch detected");
}

@end

我只是不明白为什么这在8.1上不起作用...我知道命中测试的顺序与渲染节点相反,但那么实现直接行为的正确方法是什么?所以目前正在发生的事情是当我在7.1上测试时我得到了消息“黄色按钮”,但在8.1上我得到了消息“触摸检测到”(当我打印节点名称时它表示root)。我也因此而pointed to file a radar,但正如我所说,我用nodesAtPoint而不是nodeAtPoint解决了所有问题,所以我没有。因为我认为这不是一个错误,而是我的错误,因为在7.1上一切都很好。这是一个错误,还是其他什么?

1 个答案:

答案 0 :(得分:1)

具有讽刺意味的是,我的数学似乎是7.1而不是8.1的错误。我没有用7.1测试过这个。

首先,我无法让您的任何代码与self.userInteractionEnabled = NO;一起使用,因为没有任何内容可以接受。

在设置ignoreSiblingsOrder时使用zPosition,但它基于其父级。因此,如果parent为-1​​,并且您添加了一个0的子项,则其呈现zPosition仍为-1。触摸也是如此,但顺序相反。用userInteraction渲染的最后一个获取触摸事件。

希望这是有道理的。请参阅添加的注释和调试。

#import "GameScene.h"

@interface Button : SKSpriteNode
-(instancetype)initWithColor:(UIColor *)color size:(CGSize)size;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
@end


@implementation Button
-(instancetype)initWithColor:(UIColor *)color size:(CGSize)size {
    self = [super initWithColor:color size:size];
    self.userInteractionEnabled = YES;
    return self;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"%@ hit", self.name);
}
@end

@implementation GameScene

-(id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]) {

        SKNode* root = [SKNode new];
        root.name = @"root";

        SKNode* layer1 = [SKNode new];
        layer1.name = @"layer1";

        SKNode* layer2 = [SKNode new];
        layer2.name = @"layer2";

        layer1.zPosition = -1;//layer1 and layer2 are just containers
        layer2.zPosition = -2;


        Button* button = [Button spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(100, 100)];
        button.name = @"yellow button";
        button.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));

        //layer1 is at -1 and button does not have a z so it will be -1 in the scene like its parent (-1+0)
        [layer1 addChild:button];

        //root is 0 layer1 is -1 (along with button) root is above layer1 and will recieve any touches
        [root addChild:layer1];

        //root is 0 layer2 is -2 layer1 (and button) are above layer2 and root is above layer1 root gets touch
        [root addChild:layer2];

        //nothing changes except root is added
        [self addChild:root];

        //button needs to be on same zPosition or higher to get touch
        //it is -1 because of parent node + 1 = 0
        //best if you do +2 to ensure it is above

//        button.zPosition = 2;

    }
    return self;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    for (UITouch *touch in touches)
    {
        CGPoint point = [touch locationInNode:self];
        SKNode *node = [self nodeAtPoint:point];
        NSLog(@"Touch detected: %@", node.name);
    }

}

另外,我建议不要使用负数作为zPosition。它确实让事情变得更加混乱。