1

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!

Dominique Vial
  • 3,729
  • 2
  • 25
  • 45
Velykovits
  • 223
  • 2
  • 13
  • why don't you use a gesture recognizer. It will allow you to specify how many touches can occur at once – MaxKargin Aug 01 '15 at 21:39
  • I thought that it is used for swipes and pinch. – Velykovits Aug 01 '15 at 21:43
  • yeah, you want the player to swipe or pan his finger over the screen, right? – MaxKargin Aug 01 '15 at 21:44
  • Yes, but not just one swipe, he can drag the sprite to any place of the screen. Is it the same as pan gesture? – Velykovits Aug 01 '15 at 21:45
  • 1
    Yeah. Here, I'll give a more detailed explanation – MaxKargin Aug 01 '15 at 21:46
  • I started with this now: https://spritekitlessons.wordpress.com/2013/10/03/gesture-recognizers-with-sprite-kit/ ...but in my skscene I already have another delegate for the physics collision detection - SKPhysicsContactDelegate... How you use two delegates in one header? – Velykovits Aug 01 '15 at 21:55
  • You can use touchesBegan/touchesMoved to track a single touch – 0x141E Aug 01 '15 at 22:06
  • This is what i do, but still if I use the first touch only, it doesn't work eaither. firstTouch = (UITouch *)[[[event allTouches] allObjects] objectAtIndex: 0]; – Velykovits Aug 01 '15 at 22:09
  • iOS automatically tracks all touch events, so it's easy to determine if a different finger touches the screen. – 0x141E Aug 02 '15 at 00:59

1 Answers1

2

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.

Community
  • 1
  • 1
MaxKargin
  • 1,560
  • 11
  • 13
  • Thanks a lot! My only problem is I already use a delegate for the skscene for the physics collision detection. How can I have the other one for the gestures? – Velykovits Aug 01 '15 at 22:15
  • No problem, the physics "delegation" will have nothing to do with the gesture handling, actually. Physics stuff will be called in `didBeginContact:`, while gesture stuff will be called in another method that you define yourself (the action:@selector(insertyourmethodnamehere)) when you initialize it. Just check out that second link I gave you. It will help a lot. – MaxKargin Aug 01 '15 at 22:20
  • If I have the I cannot put the in the skscene header. It only accepts one delegate, that's my problem. – Velykovits Aug 01 '15 at 22:25
  • Ohh, noo you don't need to do any of that. Its much easier to just initialize with the action selector like in that link I put in. Basically you configure the gesture recognizer to call a method inside of your scene and pass itself in as an argument. – MaxKargin Aug 01 '15 at 22:31