简体   繁体   中英

Sprite Kit only allow one touch

I have looked for a similar question and didn't find one, so I apologize if this has already been asked, but I am having issues with limiting the amount of touches that SKScene will allow me to have. I have implemented the touchesBegan:withEvent: method, and have set up my SKAction(s) for the animation, but what I am wanting is while the sprite node is animating, I don't want it to have the ability of accepting another touch.

I tried to count the amount of touches that is happening, but that didn't work in any way, so I am at a stopping point.

So, my basic question is: How do I create a "one touch, then wait for animation to end before another touch can happen" in my scene?

Here is the code:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */

SKAction *jump = [SKAction moveToY:400 duration:.4];
SKAction *down = [SKAction moveToY:CGRectGetMidY(self.frame) duration:.4];
SKAction *action = [SKAction sequence:@[jump, down]];

for (UITouch *touch in touches) {
    NSInteger touchesMax = 1;
    NSInteger actualTouches = [touches count];
    NSLog(@"%ld", (long)actualTouches);

    actualTouches++;

    if (actualTouches > touchesMax) {
        [farmer removeAllActions];
    }
    else {
        [farmer runAction:action];
    }
}
}

any help is appreciated

I believe this would work. At the start of touchesBegan do

self.userInteractionEnabled = NO;

Then define a new SKAction to enable user interaction:

SKAction *enable = [SKAction runBlock:^{ self.userInteractionEnabled = YES; }];

Add that to your sequence:

SKAction *action = [SKAction sequence:@[jump, down, enable]];

The simplest solution for your case:

How do I create a "one touch, then wait for animation to end before another touch can happen" in my scene?

Is to disable the touch upon starting the animation using [self setUserInteractionEnabled:NO];

And reenabling it once animation is done.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */

    SKAction *jump = [SKAction moveToY:400 duration:.4];
    SKAction *down = [SKAction moveToY:CGRectGetMidY(self.frame) duration:.4];
    SKAction *action = [SKAction sequence:@[jump, down]];

    [self setUserInteractionEnabled:NO];

    [farmer runAction:action completion^{
          [self setUserInteractionEnabled:YES];
    }];
}

Now if you still want to have touch functionality, just not perform action you could do this. Add property to your scene, lets call it animating.

@property (nonatomic,assign)BOOL animating;

Then change your code to take this value into account:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */

    SKAction *jump = [SKAction moveToY:400 duration:.4];
    SKAction *down = [SKAction moveToY:CGRectGetMidY(self.frame) duration:.4];
    SKAction *action = [SKAction sequence:@[jump, down]];

    self.animating = YES;
    [farmer runAction:action completion^{
        self.animating = NO;
    }];

}

This way animating flag will be YES while action is running, upon completion it will be set to NO, and new action can be run.

You don't have to check it that way. You can use runAcrion:forKey on SKSpriteNode and after that you can see if the action is running:

if (![farmer actionForKey:@"ActionKey"])
    [farmer runAction: runAction:action withKey:@"ActionKey"]

Now you just run action if the sprite in not running it.

check this tutorial: http://www.raywenderlich.com/44270/sprite-kit-tutorial-how-to-drag-and-drop-sprites

It is implemented there - once sprite been touched and move, touch again and nothing happen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM