Put CCObject over others still activate objects that are below


#1

Hi,
I create a screen that have many CCControlButton(s), and another biggest CCLayer over this CCControlButton(s).
The biggest CCControlButton shows a hint to the player and the user click and the CCControlbutton is gone(I attach the big CCCOntrolButton to an extra layer).
The problem is: even the smaller CCControlButton(s) are below the big CCControlButton, if the user clicks in it, the correspondent action of a CCCOntrolButton runs, even if the smaller CCControlButton is not visible(the big CCControlButton is over the smaller).
I don`t want this to happen, how I could do this?


#2

If you do not want the CCControlButton to receive a touch event then you can use setDisabled method to disable it. You could also try changing touch priorities.


#3

The problem is that I want CCControlButtons to have a touch event but this event must be enabled only when the big CCControlButton is hide(or clicked).
I think to disable the smaller CCCOntrolButton and when the big CCControlButton was touched, enable all smaller CCControlButtons and hide the big CCControlButton.
But to do that I’ll need to write lots of code, I think to use something simple.
Like use 2 CCLyaer(s) put one CCLayer above other CCLayer.
Block the CCLayer that is behind, allowing only the front CCLayer to work, but I don’t know how to do that.


#4

If you want to set a CCLayer in a way that it will block all touch events so they will not occur in controls that are behind this layer then in this layer you should:

  1. enable touch with setTouchEnabled(true);
  2. in registerWithTouchDispatcher method register using swallow touches option and low priority for this layer something like CCDirector::sharedDirector()->getTouchDispatcher()~~>addTargetedDelegate;
  3. in ccTouchBegan method of this layer always return true to swallow all touches
  4. set lower priority value for you CCControlButton that should work for example priarioty =~~20000
    Then your CCControlButton with this priority should work and the layer will block everything else.

#5

Thanks for the help ‘Leszek X’.
I try to implement the solution that you say, but it’s hard for me, I can’t make it work.
I’ll use the first method, using the setEnable(false), using the getChildbyTag method, thanks for help.


#6

Here’s something I would like to try:

// When you want to show the tutorial layer, disable game controls and make the current game "listen" to notifications.
void MainGame::showTutorialLayer() {
   // Show tutorial layer
   mTutorialLayer -> setVisible( true );

   // Disable controls
   mGameControls -> setEnabled( false );

   // Make this layer "listen" to notifications.
   // When this layer "hears" the notification "tutorialDidFinish", it will invoke MainGame::tutorialDidFinish
   CCNotificationCenter::sharedNotificationCenter() -> addObserver( this, callfuncO_selector( MainGame::tutorialDidFinish ), "tutorialDidFinish", NULL );
}

// This will be called when the layer "hears" the notification "tutorialDidFinish"
void MainGame::tutorialDidFinish( cocos2d::CCObject * sent_data ) {
   // Log to console
   CCLOG( "Tutorial end." );

   // Re-enable controls
   mGameControls -> setEnabled( true );
}

// Then when the Tutorial Layer has been closed, send the notification "tutorialDidFinish"
void TutorialLayer::doCloseLayer( cocos2d::CCObject * sender ) {
   // Hide this layer
   this -> setVisible( false );

   // Send notification "tutorialDidFinish:
   CCNotificationCenter::sharedNotificationCenter() -> postNotification( "tutorialDidFinish", NULL );
}

Hope this helps. I have yet to try this myself, though, but it should work.


#7

I try to do something similar that you want to do.
But I have 2 problems.
The first is:

mGameControls -> setEnabled( false );

I suppose the mGameControls is a CCLayer, but if you setEnable(false), all CCControlButtons continue to work, is necessary to setEnable(false) the specific CCControlButtons, even you have all CCControlButton added to that CCLayer, it will contiune to work unless you disable every one of them.
The other probvlem is the

CCNotificationCenter::sharedNotificationCenter() -> postNotification( "tutorialDidFinish", NULL );

I try to use CCNotificationCenter, it work, but when I try to enable or disabled anything using a method passed by a CCNotificationCenter that changes something inside the CCLayer, i got a crash in my app, I try this thing yesterday, I try many times, but I give up to use the CCNotificationCenter.
The only alternative left is to setEnable(false) ALL CCControlButton(s) and setEnable(true) all again when click on the biggest button


#8

Fabio Cunha wrote:

I suppose the mGameControls is a CCLayer, but if you setEnable(false), all CCControlButtons continue to work, is necessary to setEnable(false) the specific CCControlButtons, even you have all CCControlButton added to that CCLayer, it will contiune to work unless you disable every one of them.
mGameControls is a CCMenu object. I haven’t use CCControlButtons before. I prefer to use CCMenuItem object as I can simply put them inside a CCMenu object and use CCMenu::setEnabled( false ) to disable all objects in the menu. I assumed CCControlButton have that functionality.

I try to use CCNotificationCenter, it work, but when I try to enable or disabled anything using a method passed by a CCNotificationCenter that changes something inside the CCLayer, i got a crash in my app, I try this thing yesterday, I try many times, but I give up to use the CCNotificationCenter.
I haven’t really tried it on a machine. Some syntax might be wrong. Try reading more about this here: http://www.plungeinteractive.com/blog/notification-center-extension-for-cocos2d-x/
Could you tell me the what happens when it crashes? Does it have any logs? Does it point to a certain part of the code?

The only alternative left is to setEnable(false) ALL CCControlButton(s) and setEnable(true) all again when click on the biggest button
What you could do is put all your CCControlButtons in an array and loop through it all and use setEnabled( false) on them.
This will ease the pain of turning them off one-by-one.


#9

Fabio Cunha wrote:

I suppose the mGameControls is a CCLayer, but if you setEnable(false), all CCControlButtons continue to work, is necessary to setEnable(false) the specific CCControlButtons, even you have all CCControlButton added to that CCLayer, it will contiune to work unless you disable every one of them.

Yes that is a little strange but it is how cocos2d-x nodes works. However you could write yourself some recursive methods to disable/enable with all childrens similar to those in this thread: http://www.cocos2d-x.org/boards/6/topics/6887?r=17740#message-17740


#10

Leszek X wrote:

However you could write yourself some recursive methods to disable/enable with all childrens similar to those in this thread: http://www.cocos2d-x.org/boards/6/topics/6887?r=17740#message-17740
>
I try to use the recursive methos from the link, but it not stopped the CCControlButton to activate. It not work.
But I’ll try to use it in my game later to try to pause the game.

Lance Gray wrote:

Could you tell me the what happens when it crashes? Does it have any logs? Does it point to a certain part of the code?

Simple show a gdc error and nothing more on the console.

I’ll use a for loop to enable/disable the CCControlButtons, it’s probably a better idea to use the CCMenu, it’ll be more easy to enable and disable buttons, but I use a CCControlButton because I can create a button without use an image for each element, I only use one image for all buttons.

Everything has advantages and disavantages.

This is for ‘Lance Gray’, I see that you create a blog and your first post, it’s important that you show your published games too.


#11

I solved the problem using the following static method

void Utils::activateButtons( CCNode * node , bool activate) {
    CCObject* cbt = NULL;    
    CCARRAY_FOREACH(node -> getChildren(), cbt) {
        CCControlButton * n = (CCControlButton *)cbt;
        n->setEnabled(activate);
    }
}

Since all my CCControlButtons are added to a CCNode, this code works perfect, create it using the same code use in the recursive methods.
Thanks Leszek X and Lance Gray for the help.


#12

Fabio Cunha wrote:

This is for ‘Lance Gray’, I see that you create a blog and your first post, it’s important that you show your published games too.
I have an old blog which was acting funky and switched to WordPress. I still don’t have any published games as I’m stuffed with work.