iOS如何在Sprite Kit中实现UIButton的节点行为?

时间:2013-12-17 17:08:56

标签: ios objective-c uibutton sprite-kit kobold-kit

我希望我的一些Sprite Kit节点的行为类似于UIButtons 。我尝试了两种方法:

1)使用touchesBegan: - 如果用户小心,但似乎多次启动,比我可以禁用交互更快,这会导致按钮能够被多次激活:

   spriteNode.userInteractionEnabled = YES;

//causes the following to fire when node receives touch
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

        self.userInteractionEnabled = NO;

        DLog(@"Do node action");
        self.userInteractionEnabled = YES;


    }

2)我切换到Kobold-Kit作为iOS Sprite Kit顶部的图层。它允许我做的一件事是将button - like behavior添加到任何节点。但是,我遇到了一个问题,如果我有2个按钮叠在一起,点击顶部按钮激活两者。在这种情况下,布尔标志可以防止重复交互。我在KKScene中跟踪堆叠按钮一起发出此调用的问题:

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];

    for (id observer in _inputObservers)
    {
        if ([observer respondsToSelector:@selector(touchesBegan:withEvent:)])
        {
            [observer touchesBegan:touches withEvent:event];
        }
    }
}

场景只是向场景中的所有节点发送通知。这会导致堆叠在彼此顶部的按钮行为一起发生。

是否有一种方法或示例显示如何正确安排精灵节点以允许类似于UIButton的行为,其中我只能激活顶部按钮,并且每次激活都会禁用该按钮之后的时间?

2 个答案:

答案 0 :(得分:1)

@property (nonatomic, strong) UITapGestureRecognizer *tapGesture;

self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureStateChanged:)];
self.tapGesture.delegate = self;
[self.view addGestureRecognizer:self.tapGesture];


- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer == self.tapGesture) {
        return CGRectContainsPoint(self.neededSprite.frame, [self convertPoint:[sender locationInView:self.view] toNode:self]);
    }
    return YES;
}



 - (void)tapGestureStateChanged:(UITapGestureRecognizer *)sender
    {
        if (sender.state == UIGestureRecognizerStateRecognized) {
/* do stuff here */
    }
    }

答案 1 :(得分:0)

SpriteKit Programming Guide建议使用SKNode名称来控制触摸时要实现的行为。 “使用操作动画场景”一节中的示例会覆盖touchesBegan:withEvent:方法,仅在名称不为nil时运行。完成后,只需重置名称,即可抓住下一步。

- (void)touchesBegan:(NSSet *) touches withEvent:(UIEvent *)event {
    SKNode *helloNode = [self childNodeWithName:@"helloNode"];
    if (helloNode != nil) {
        helloNode.name = nil;
        SKAction *moveUp = [SKAction moveByX: 0 y: 100.0 duration: 0.5];
        SKAction *zoom = [SKAction scaleTo: 2.0 duration: 0.25];
        SKAction *pause = [SKAction waitForDuration: 0.5];
        SKAction *fadeAway = [SKAction fadeOutWithDuration: 0.25];
        SKAction *remove = [SKAction removeFromParent];
        SKAction *moveSequence = [SKAction sequence:@[moveUp, zoom, pause, fadeAway, remove]];
        [helloNode runAction: moveSequence];
    }
}

另一个想法是将用户交互重新启用到touchesEnded。