CCMenu won't disappear

I need a way to allow the player to play again. What I did was make a CCMenu with a “Play Again” button, and a “Quit” button. The Play Again button has Game::onClickTrue as its callback, while the Quit button has Game::menuCloseCallback (same as the close button on the bottom righthand part of the screen) as its callback. Game is my HelloWorld layer, btw, and I store the CCMenu in a class attribute Game::playAgainMenu, so I can remove it later. When I make press Play Again, it works normally, and starts the game again, but the CCMenu doesn’t disappear even if I call this->removeChild(playAgainMenu).

It is hard to understand what you mean for me.
Could you give some codes to explain it?

Post several code here would be helpful.
I guess you can try this:
# removeChild(playAgainMenu) isn’t reduce the CCMenu::m_uReference to zero and make it delete it self. Please check the m_uReference count.
# Or you can call playAgainMenu->setIsVisable(false) to hide it before remove it.

class Game {
    CCMenu *playAgainMenu;
}

void Game::startGame() {
    // start game. comes after init.
}

void Game::finished() {
    // called when game finishes
    this->playAgainMenu = createPlayAgainMenu();
    this->addChild(playAgainMenu);
}

void Game::closeMenuCallback() {
    CCDirector::sharedDirector()->end();
}

void Game::onClickTrue() {
    this->removeChild(this->playAgainMenu);
    this->startGame();
}

CCMenu *Game::createPlayAgainMenu() { 
    CCMenuItem *playAgain = CCMenuItemWithLabel(...., menu_selector(Game::onClickTrue),..);
    CCMenuItem *quit = CCMenuItemWithLabel(......, menu_selector(Game::closeMenuCallback),....);
    return CCMenu::menuWithItems(playAgain, quit, NULL);
}

After Game layer is initialized with init, it calls startGame(). When game finishes, it calls finished(), which creates the menu. When I press the playAgain button, it calls startGame() again, but the menu doesn’t disappear.

I have tested in HelloWorld. I removed the menu in the callback method:

void HelloWorld::menuCloseCallback(CCObject* pSender)
{
    this->removeChild(pMenu, true);
    /*CCDirector::sharedDirector()->end();*/

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}

And the menu dispeared.

BTW: Your simple code have logic error, like return m, what’s the m?

Minggo Zhang wrote:

I have tested in HelloWorld. I removed the menu in the callback method:
[…]
And the menu dispeared.
>
BTW: Your simple code have logic error, like return m, what’s the m?
Sorry, I forgot to define m. I fixed my sample code, please read it again.

I think you should retain playAgainMenu for Game, and release it
when you don’t need it. Or it object may be real deleted in other place.

Alright, I’ll initialize it in Game::init (), and let it autorelease (), but I still need to know how to make it invisible.

I don’t know why it is not invisible.
I have told you that, I tested it in HelloWorld, and it works.

May be you should paste your real code, not just a demo.
It is better that I can run an reproduce it.

I’d like to but I don’t know if I’m allowed. Anyway, I managed to fix it by adding the created menu to “Game” at Game::init(), using this->addChild(). Then, I just used m->setIsVisible(0) to make it invisible, and m->setIsVisible(1) to make it visible. It doesn’t feel optimal, as I would have preferred to add it as a child when I needed it, and remove it when I don’t, but it works. After all, KISS (Keep It Simple, Stupid) right?

Yes, you are right.
What I mean is that, there may be something wrong in other place, but I don’t know what, because I can not see the codes.

You can test it in HelloWorld and check the result.

Yeah, you’re using a good practice now: create the children in init phase, hide/show them in the logic, not frequently create/release objects.
I just hack the HelloWorld the same with Minggo, but cannot reproduce your problem yet.
But anyway, the problem is passby in other way…

Hello, I got some problem with using CCMenu, too.
I have an invisible layer with CCMenu (popup window with button), but when I touch an area where must be located my button (layer is invisible), buttonClick code still executes. I have found post about similar problem in cocos2d-iphone. http://code.google.com/p/cocos2d-iphone/issues/detail?id=1064. Is it a bug or feature?

This is my code:

CCLayer* popupLayer = CityChoosenPopUp::node();
popupLayer->setPosition(ccp(300,300));
popupLayer->setTag(POPUP_LAYER);
popupLayer->setIsVisible(false);
hudLayer->addChild(popupLayer);

        ....

bool CityChoosenPopUp::init()
{
    CCLOG("GlobalMap::init");
    //////////////////////////////
    // 1. super init first
    if ( !CCLayer::init() )
    {
        return false;
    }

    CCSprite* bg = CCSprite::spriteWithFile("globalMap/popUp_bg.png");
    bg->setScaleX(2);
    addChild(bg);

    CCMenuItemImage *okButton = cocos2d::CCMenuItemImage::itemFromNormalImage(
                                    "globalMap/button.png",
                                    "globalMap/button.png",
                                    this,
                                    menu_selector(CityChoosenPopUp::confirmedCallback) );


    // create menu, it's an autorelease object
    CCMenu* pMenu = CCMenu::menuWithItems(okButton, NULL);
    pMenu->setTag(MENU_TAG);
    pMenu->setPosition( CCPointZero );
    this->addChild(pMenu);

    return true;
}

It is the feature. cocos2d-iphone also acts like this.
We are considering if we should change it in cocos2d-x.

Ok, but what is the right way to workaround this ‘feature’?
At the moment I overrode CityChoosenPopUp’s setIsVisible method like this:

    CCNode::setIsVisible(var);
    getChildByTag(MENU_TAG)->setIsVisible(var);

It doesn’t look like very comfortable way, IMHO, but it works.