Velykovits
Velykovits

Reputation: 223

How to disable second touch in an SpriteKit game?

The player drags a sprite in my game but when accidentally touch the screen with a second finger it screws the movement obviously.

I used the following solutions for disable the second touch, but unfortunately it doesn't work:

//--------------

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

    if (touches.count == 1 && draggedNode == nil) {

        CGPoint pos = [[touches anyObject] locationInNode:self];
        SKNode * touchedNode = [self nodeAtPoint:pos];

        if([touchedNode.name isEqual: @"shooterBall"]){
            draggedNode = touchedNode;
        }
        draggedNodeOffset = CGPointMake(draggedNode.position.x - pos.x, draggedNode.position.y - pos.y);
    }   

}

//--------------

-(void)touchesMoved:(NSSet*) touches withEvent:(UIEvent*) event {    
    if (touches.count <= 1) {    
        CGPoint pos = [[touches anyObject] locationInNode:self];
        draggedNode.position = CGPointMake(pos.x + draggedNodeOffset.x, pos.y+draggedNodeOffset.y);
    }
}

//--------------

-(void)touchesEnded:(NSSet*) touches withEvent:(UIEvent*) event {   
    draggedNode = nil;   
}

//--------------

Do you have any solution for this?

Thanks your help in advance!

Upvotes: 1

Views: 333

Answers (1)

MaxKargin
MaxKargin

Reputation: 1545

You want to implement UIPanGestureRecognizer in your scene. It will allow you to track the location of the user's touch and at the same time control other "stray" touches: UIPanGestureRecognizer Documentation

After you initialize it, you need to implement a method to handle the user's pans. You will have to set flags inside of this method to control when the swipe started/ended. I think this answer on StackOverflow gave a really good explanation of using it (with Swift). BTW, when you initialize it, you should set the gesture recognizer's property maximumNumberOfTouches to 1 (that will cause it to ignore other touches while the user is panning).

The trickier part will be to translate the same code you wrote before to gesture recognizer. The difference is that your handler will be called only once for each "swipe" or "pan", while the touches method you are using now is called each time there is a "touch". There are a few ways to proceed at this point, and you could try whatever you like, but I think that this would be the easiest way to go once you have your gesture recognizer set up (spoiler):

  1. make sure the gesture recognizer is an instance variable so you can access it from all methods.

  2. go to the update: method and make an if statement that checks if gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged

  3. use the same algorithm that you had before in this if statement. To check the location that the touch is at use the method: locationInView:. Use self.view as the parameter.

Hope this helped! good luck.

Upvotes: 2

Related Questions