cocos2d-iOS - Gesture recognisers
Asked Answered
L

2

9

Has anyone managed to get the gesture recognition working in cocos-2d?

I have read a post here that claimed to have achieved it, here: http://www.cocos2d-iphone.org/forum/topic/8929

I patched from the git hub here: https://github.com/xemus/cocos2d-GestureRecognizers/blob/master/README

I made a subclass of CCSprite (which is a subclass of CCNode):

-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect {
if( (self=[super initWithTexture:texture rect:rect]) )
{
    CCGestureRecognizer* recognizer;
    recognizer = [CCGestureRecognizer 
        CCRecognizerWithRecognizerTargetAction:[[[UITapGestureRecognizer alloc]init] autorelease] 
                  target:self 
                  action:@selector(tap:node:)];
    [self addGestureRecognizer:recognizer];
}
return self;
}

Delegate method:

- (void) swipe:(UIGestureRecognizer*)recognizer node:(CCNode*)node
{
NSLog(@" I never get called :( ");
}

My tap event never gets called.

Has anyone got this working? How difficult is it to do gesture recognition manually for swipe detection?

Letitialetizia answered 13/2, 2011 at 18:13 Comment(0)
G
24

You need to attach the gesture recognizer to something "up the chain". Don't attach them to the individual nodes; attach them to the UIView (i.e., [[CCDirector sharedDirector] openGLView]).

Here's what I did:

- (UIPanGestureRecognizer *)watchForPan:(SEL)selector number:(int)tapsRequired {
    UIPanGestureRecognizer *recognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:selector] autorelease];
    recognizer.minimumNumberOfTouches = tapsRequired;
    [[[CCDirector sharedDirector] openGLView] addGestureRecognizer:recognizer];
    return recognizer;
}

- (void)unwatch:(UIGestureRecognizer *)gr {
    [[[CCDirector sharedDirector] openGLView] removeGestureRecognizer:gr];
}

This particular code is used in a superclass for scene controllers, so the target for the selector is hard-coded to "self", but you could easily abstract that to a passed-in object. Also, you could extrapolate the above to easily create gesture recognizers for taps, pinches, etc.

In the subclass for the controller, then, I just do this:

- (MyController *)init {
    if ((self = [super init])) {
        [self watchForPan:@selector(panning:) number:1];
    }
    return self;
}

- (void)panning:(UIPanGestureRecognizer *)recognizer {

    CGPoint p;
    CGPoint v;

    switch( recognizer.state ) {
        case UIGestureRecognizerStatePossible:
        case UIGestureRecognizerStateBegan:
            p = [recognizer locationInView:[CCDirector sharedDirector].openGLView];
            (do something when the pan begins)
            break;
        case UIGestureRecognizerStateChanged:
            p = [recognizer locationInView:[CCDirector sharedDirector].openGLView];
            (do something while the pan is in progress)
            break;
        case UIGestureRecognizerStateFailed:
            break;
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled:
            (do something when the pan ends)
            (the below gets the velocity; good for letting player "fling" things)
            v = [recognizer velocityInView:[CCDirector sharedDirector].openGLView];
            break;
    }

}
Gastronome answered 16/2, 2011 at 17:1 Comment(2)
+1 for cc's answer above, this is the correct method. You can use all UIGestureRecognizer subclasses in this way to detect pan, pinch, tap gestures. You can also use the UILongPressGestureRecognizer with state case UIGestureRecognizerStateChanged identified to detect dragging.Washery
Nice and clean, lovely. Two small issues: 1. locationInView returns the coordinates in the UIKit coordinate system, these should be converted to GL coordinates before using, ex: p = [[CCDirector sharedDirector] convertToGL: [recognizer locationInView:[CCDirector sharedDirector].view]]; 2. openGLView is deprecated as of Cocos2D 2.0, it has been replaced by [CCDirector sharedDirector].view.Galloway
S
6

If you don't want to handle everything manually I created a simple category that will add gesture recognizers to any cocos2d version read more at:

http://www.merowing.info/2012/03/using-gesturerecognizers-in-cocos2d/

or grab it from github

https://github.com/krzysztofzablocki/CCNode-SFGestureRecognizers

Skill answered 15/3, 2012 at 9:15 Comment(3)
This is awesome! Just be sure to make the nodes with the gesture recognizers above the nodes using ccTouches methods.Cason
in Cocos2d 3.0 there is no visible interface for [YourCCSprite addGestureRecognizer:YourGestureRecognizer]; So any solution for it?Quattlebaum
Yes, will there be any update on the gestureRecognizer class for Cocos2d 3.0??? That is really essential and a missing part.Premolar

© 2022 - 2024 — McMap. All rights reserved.