Extension: Gesture Recognizers for cocos2d-x

Hello everybody,
First of all thanks to all the contributors of this great community.
This is my favorite framework and since I started using it I loved it.
I recently started to write some extensions for this great framework and I will start to share them with you.
At this time I bring you a CCTouchRecognizer class with 5 subclasses for recognizing touch gestures without using native code.
The following gestures can be recognized: tap, long press, swipe, pinch and pan.
I haven’t tested in any android devices yet, but they must work the same way that they do in iOS devices.

Here is the link of the repository in GitHub where also you can find documentation:

I hope you find them useful!

Special Regards,
Artavazd Barseghyan

I am unable to get the tap gesture to fire.

I created a default project w/ box2d and added the following code

HelloWorldScene.h

#include “CCTapGestureRecognizer.h”

unsigned int numberOfTapsRequired;

void didTap(CCObject * obj);

HelloWorldScene.cpp

void HelloWorld::initGestures()
{
CCLOG (“initGestures”);
CCTapGestureRecognizer * tap = CCTapGestureRecognizer::create();
tap~~>setTarget);
tap~~>setNumberOfTapsRequired(1);
tap~~>setCancelsTouchesInView;
this~~>addChild(tap);
CCLOG( “taps”,tap->getNumberOfTapsRequired() );
}

void HelloWorld::didTap(cocos2d::CCPoint location){
//the location of the gesture; if there are multiple taps, this location is the last tap
//CCPoint location;
CCLOG( “tap” );
}

My output is:
Cocos2d: initGestures
Cocos2d: taps

Update

I tracked it into:
CCGestureRecognizer::isPositionBetweenBounds which is returning false due to the frame.containsPoint returning false. I’m not sure why my HelloWorldScene has no width and height.

Thanks!

doug mckay wrote:

I am unable to get the tap gesture to fire.
>
I created a default project w/ box2d and added the following code
>
HelloWorldScene.h
>
#include “CCTapGestureRecognizer.h”
>
unsigned int numberOfTapsRequired;
>
void didTap(CCObject * obj);
>
>
>
HelloWorldScene.cpp
>
void HelloWorld::initGestures()
{
CCLOG (“initGestures”);
CCTapGestureRecognizer * tap = CCTapGestureRecognizer::create();
tap~~>setTarget);
tap~~>setNumberOfTapsRequired(1);
tap~~>setCancelsTouchesInView;
this~~>addChild(tap);
CCLOG( “taps”,tap~~>getNumberOfTapsRequired );
}
>
void HelloWorld::didTap{
//the location of the gesture; if there are multiple taps, this location is the last tap
//CCPoint location;
CCLOG;
}
>
>
My output is:
Cocos2d: initGestures
Cocos2d: taps
>
Update

I tracked it into:
CCGestureRecognizer::isPositionBetweenBounds which is returning false due to the frame.containsPoint returning false. I’m not sure why my HelloWorldScene has no width and height.
>
Thanks!
You have to add the recognizer on another layer and not over itself, so change the following line of code and it should work fine:
this~~>addChild(tap);

Also, instead of
void HelloWorld::didTap(cocos2d::CCPoint location)
You must have
void HelloWorld::didTap(cocos2d::CCObject * obj)
I know that’s not the problem, but just for letting you know.

If the problem persists please let me know when and where are you adding the gesture recognizer, because I just tried to add it inside bool init() method of my scene and it works fine.

And thanks for trying out my extension!

Regards,
Artavazd Barseghyan

I’m taking a look at the swipe gesture and it looks like I always get a reverse up/down swipe.

Left/right is point toward the direction you end up.
Up/down is point away from the direction you end up.

I updated CCSwipeGestureRecognizer and switched the up / down calculation and it seems to work as expected now.

bool up = p2.y - p1.y >= kSwipeMinDistance;
bool down = p1.y - p2.y >= kSwipeMinDistance;

doug mckay wrote:

I’m taking a look at the swipe gesture and it looks like I always get a reverse up/down swipe.
>
Left/right is point toward the direction you end up.
Up/down is point away from the direction you end up.
>
I updated CCSwipeGestureRecognizer and switched the up / down calculation and it seems to work as expected now.
>
bool up = p2.y - p1.y >= kSwipeMinDistance;
bool down = p1.y - p2.y >= kSwipeMinDistance;

Ohh I see, you are right. I’ve already made the change :slight_smile:
Thank you again!

One last thing (hopefully) I have been trying to use the pinch gesture however it never seems to detect beyond the first touch so it never increments touchNumber. Am I missing something that could be obvious to you?

CCPinchGestureRecognizer::ccTouchBegan - fires on first touch but not afterwards. I am testing on an iPhone

if (touchNumber==2) {
isRecognizing = true;
}

Thanks!

doug mckay wrote:

One last thing (hopefully) I have been trying to use the pinch gesture however it never seems to detect beyond the first touch so it never increments touchNumber. Am I missing something that could be obvious to you?
>
CCPinchGestureRecognizer::ccTouchBegan - fires on first touch but not afterwards. I am testing on an iPhone
>
if (touchNumber==2) {
isRecognizing = true;
}
>
>
Thanks!

I’m sorry but I couldn’t find the problem, it’s working fine on my iPad

Does the tap recognizer support having multiple recognizers active for different numbers of taps?

Yes of course, you can have them in different places or on the same place.
Try it :wink:

(if you experiment any problems let me know please)

Fantastic, this is awesome!

Can you please tell me where can i find “rotation” gestures. I desperately need them in a game. If I can’t find them anywhere, can you give me a few pointers on how to implement it?

Mohammad Adil wrote:

Can you please tell me where can i find “rotation” gestures. I desperately need them in a game. If I can’t find them anywhere, can you give me a few pointers on how to implement it?

I think that you have 2 options: first, you can use native rotation gestures both in iOS and android, or second you can create your own recognizer as I did. Soon I will have that recognizer too, but if you need it right now, it’ll be better to create your own class.

I would recommend you to create it over my CCPinchGestureRecognizer class, because it’s almost the same. You only have to modify a little bit the ccTouchMoved method and you are done.

Thanks. I’ll try to write my own gesture recognizer for rotations. But if I want to integrate iOS and android native gesture recognizers with cocos2d-x, how can I do that (i’m sure they will be more accurate)?

Artavazd Barseghyan wrote:

Mohammad Adil wrote:
> Can you please tell me where can i find “rotation” gestures. I desperately need them in a game. If I can’t find them anywhere, can you give me a few pointers on how to implement it?
>
I think that you have 2 options: first, you can use native rotation gestures both in iOS and android, or second you can create your own recognizer as I did. Soon I will have that recognizer too, but if you need it right now, it’ll be better to create your own class.
>
I would recommend you to create it over my CCPinchGestureRecognizer class, because it’s almost the same. You only have to modify a little bit the ccTouchMoved method and you are done.

It’s just fantastic simple! Thank you for good extension, I think it should be included into cocos2d-x.

Hello,
I have extended the CCGestureRecognizer to create a CCRotateGestureRecognizer which detects two-finger rotation gestures. I am currently doing extensive testing to ensure that the accuracy is as good as android or ios native gestures. I’ll be happy to provide my contributions to this ‘noble’ cause. Please tell me how I can add my code to your repository.

Regards,
Adil

Artavazd Barseghyan wrote:

Hello everybody,
First of all thanks to all the contributors of this great community.
This is my favorite framework and since I started using it I loved it.
I recently started to write some extensions for this great framework and I will start to share them with you.
At this time I bring you a CCTouchRecognizer class with 5 subclasses for recognizing touch gestures without using native code.
The following gestures can be recognized: tap, long press, swipe, pinch and pan.
I haven’t tested in any android devices yet, but they must work the same way that they do in iOS devices.
>
Here is the link of the repository in GitHub where also you can find documentation:
https://github.com/spalx/cocos2d-x-extensions
>
I hope you find them useful!
>
Special Regards,
Artavazd Barseghyan

Is it possible to move the feature to main cocos2d-x?
The features mentioned are very useful for any modern apps.

Exactly. I think there should be a whole gesture recognition module with support for adding custom gestures. Many other competing game engines have this functionality but I like cocos2d-x too much. Also, given the number of extensions for gesture recognition present (some of which don’t work at all), there is good demand for this feature too and it won’t take much time to implement this either.

winipcfg winipcfg wrote:

Is it possible to move the feature to main cocos2d-x?
The features mentioned are very useful for any modern apps.

Oh… I’m looking forward to update CCRotateGestureRecognition. I need rotate and zoom in/out features asap. T_T. Thanks

Mohammad Adil wrote:

Hello,
I have extended the CCGestureRecognizer to create a CCRotateGestureRecognizer which detects two-finger rotation gestures. I am currently doing extensive testing to ensure that the accuracy is as good as android or ios native gestures. I’ll be happy to provide my contributions to this ‘noble’ cause. Please tell me how I can add my code to your repository.
>
Regards,
Adil
>
Artavazd Barseghyan wrote:
> Hello everybody,
> First of all thanks to all the contributors of this great community.
> This is my favorite framework and since I started using it I loved it.
> I recently started to write some extensions for this great framework and I will start to share them with you.
> At this time I bring you a CCTouchRecognizer class with 5 subclasses for recognizing touch gestures without using native code.
> The following gestures can be recognized: tap, long press, swipe, pinch and pan.
> I haven’t tested in any android devices yet, but they must work the same way that they do in iOS devices.
>
> Here is the link of the repository in GitHub where also you can find documentation:
> https://github.com/spalx/cocos2d-x-extensions
>
> I hope you find them useful!
>
> Special Regards,
> Artavazd Barseghyan

I think that following Git repository is public so you can just fork and update your code.
I’m looking forward to your update.
Thanks.

Mohammad Adil wrote:

Hello,
I have extended the CCGestureRecognizer to create a CCRotateGestureRecognizer which detects two-finger rotation gestures. I am currently doing extensive testing to ensure that the accuracy is as good as android or ios native gestures. I’ll be happy to provide my contributions to this ‘noble’ cause. Please tell me how I can add my code to your repository.
>
Regards,
Adil
>
Artavazd Barseghyan wrote:
> Hello everybody,
> First of all thanks to all the contributors of this great community.
> This is my favorite framework and since I started using it I loved it.
> I recently started to write some extensions for this great framework and I will start to share them with you.
> At this time I bring you a CCTouchRecognizer class with 5 subclasses for recognizing touch gestures without using native code.
> The following gestures can be recognized: tap, long press, swipe, pinch and pan.
> I haven’t tested in any android devices yet, but they must work the same way that they do in iOS devices.
>
> Here is the link of the repository in GitHub where also you can find documentation:
> https://github.com/spalx/cocos2d-x-extensions
>
> I hope you find them useful!
>
> Special Regards,
> Artavazd Barseghyan

I can get the swipe gestures to be recognized when I add the CCSwipeGestureRecognizer to my CCLayer in the init().

SwipeGesture = CCSwipeGestureRecognizer::create(); SwipeGesture->setTarget(this, callfuncO_selector(baseRoom::handleSwipe)); SwipeGesture->setDirection(kSwipeGestureRecognizerDirectionDown | kSwipeGestureRecognizerDirectionUp); SwipeGesture->setCancelsTouchesInView(true); this->addChild(SwipeGesture);

My issue is when I call try to remove all children from my CCLayer before replacing the scene.

this->removeAllChildren(); CCDirector::sharedDirector()->replaceScene(upRoom->scene(upRoom));

I get a SIGARBT saying “reference count should be greater than 0” when SwipeGesture is being removed.

I’m not sure what I’m doing wrong. Should I be using a different method for removing CCSwipeGestureRecognizer?