Menu with MenuItemImage and events bubbling

Menu with MenuItemImage and events bubbling
0.0 0


Dear all,

I’m currently working on a menu using cocos2d-x (Android) and I’m facing this problem.
I would like to have a scrollable menu with big sprites (basically, you can see only one image and a half on the screen). I would like to scroll the menu by swiping (fling?) my finger on the screen, then select a menu item with a tap on the image.

So in my CCLayer I create a CCMenu and I add CCMenuItemImage to the menu.
I implemented

virtual void ccTouchesMoved(NSSet *pTouches, UIEvent *pEvent);
virtual void ccTouchesBegan(NSSet *pTouches, UIEvent *pEvent);

in my CCLayer and I handle the moved-began events to scroll the menu. However I have a problem, if you start to touch (touchesBegan) ON a menu item, that is you touch an image and then try to scroll left or right, the event is not propagated to the CCLayer. I think this is probably wanted by cocos2d-x authors.
However having a look at cocos2d for iphone API, the prototype for ccTouchesMoved or ccTouchesBegan returns a bool instead, and that bool is probably used to propagate the event (bubbling) to parents (so that you can overwrite ccTouchesMoved and return false if you want the event to be propagated). This doesn’t seem to be possible in cocos2d-x as the return type is void.

Did I get this wrong? What’s the correct way of achieving this menu scroll in cocos2d-x?



The return type of ccTouchesBegan and ccTouchesModes are void in cocos2d-iphone. Only ccTouchBegan returns bool, which is reimplemented in CCMenu.


Ops, my bad! I was wrong, I only looked at the ccTouchBegan in cocod2d iphone.

Also found some information on swallow touches (cocos2d iphone) here: , I still have to elaborate on that but seems to be the way to solve my problem.



You can ref to tests/controller.cpp, read the sources of TestController::ccTouchesBegan & ccTouchesMoved
The only difference is label item -> image item.


The “test” project is very useful and contains a lot of samples that really help during development. However in this specific case, the test doesn’t help (at least on my Android 2.2) as it shows the same problem.

In “test”, if you put your finger on a label (don’t release, just keep the finger there), the label will grow bigger (selected) and you can then move the finger down and other labels will be correctly selected; however, the layer won’t scroll if you get to the end of the screen. It’s not easy to notice in “test” because the labels are small and it’s more likely that you’ll put your finger on the background rather than on the MenuItem. Unfortunately I’m trying to achieve a menu with big MenuItems (images) so it’s very likely that your finger will be on the MenuItem rather than on the background. Please notice this only apply if you start your touch on the item, if you start on the layer and then move on the item the layer will scroll correctly (a good indication of whether you started on the item is the label growing bigger).

I think the solution is to set swallow touches, as in CCTargetedTouchHandler::setSwallow(), however I’m still looking in how to access the targeted touch handler of the menu items; I’m currently looking into the source to find it. I’ll post my solution once I found it.

Thanks everyone for the support


Sorry for reply too late.

In cocos2d framework,The effect you want is difficult to achieve.
Because menu always receive the touch event before the layer it’s belongs to.And the touch event will be swallowed if it happened on a menu item.So in the case you described,the layer can’t receive the touch event.

As you think,you can set the menu not swallow the touch event by function CCTargetedTouchHandler::setSwallow(),but you can’t access the targeted touch handler of the menu now.
Even if you succeed,I don’t think it’s the real effect you want to achieve.You can see the effect by modify the code of class CCMenu:

void CCMenu::registerWithTouchDispatcher()
      CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, kCCMenuTouchPriority, true);

Modify the parameter true to false,then you will see the effect you can achieve.

Strongly recommended you don’t achieve it like that.Good luck!