Cocos2d-X: Menús y botones


En Cocos la manera más sencilla de crear botones es a través de las clases CCMenu y CCMenuItem. Es decir se crea un menú (CCMenu) y se le añaden los botones (CCMenuItem).
Lo primero y más importante es como recibir el evento de botón pulsado:

// Dentro del método init() de vuestro CCLayer
// CCMenuItem *button;
button->setTarget(this, menu_selector(TuClase::buttonCallback));

Donde el callback lo podéis definir como:

// pSender es la instancia del botón
void buttonCallback(cocos::CCObject* pSender);

Para crear un botón a partir de imagen

// CCSprite *normalSprite; --> Botón sin pulsar
// CCSprite *selectedSprite; --> Botón pulsado
CCMenuItemSprite::create(normalSprite, selectedSprite);

Y para crear un botón a partir de texto (los dos últimos parámetros son para el evento de botón pulsado):

CCMenuItemFont* pCreditsButton = CCMenuItemFont::create("Jugar", this, menu_selector(TuClase::botonJugarCallback) );

Menús

Normalmente en la pantalla de inicio de juego, suele haber un menú con botones para jugar, ver la ayuda, los créditos, la tienda... Para crear un menú, se crean los ítems que va a albergar (heredan todos de CCMenuItem), se crea el menú, se le añaden los items y se añade el menú a la capa (CCLayer).

La manera más sencilla es crear un array con todos los botones y añadírselos al menú al crear este último:

// Dentro del método init() de vuestro CCLayer
// CCArray* arrayOfCCMenuItems
CCMenu *menu = CCMenu::createWithArray(arrayOfCCMenuItems);

// O también
CCMenu::create(pButton0, pButton1, pButton2, NULL);

this->addChild(menu);

Si es un menú como el descrito, querréis alinear automáticamente los botones:

// Alineación vertical
menu->alignItemsVertically();

// Alineación horizontal
menu->alignItemsHorizontally()

Ejemplo de pantalla de menú completo (a partir de un proyecto recien creado, en el archivo HelloWorld.cpp):

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
  if ( !CCLayer::init() )
  {
    return false;
  }
  
    // ask director the window size
  CCSize size = CCDirector::sharedDirector()->getWinSize();

  CCMenuItemFont* pPlayButton = CCMenuItemFont::create("Jugar", this, menu_selector(HelloWorld::playCallback) );
  CCMenuItemFont* pHelpButton = CCMenuItemFont::create("Ayuda", this, menu_selector(HelloWorld::helpCallback) );
  CCMenuItemFont* pCreditsButton = CCMenuItemFont::create("Créditos", this, menu_selector(HelloWorld::creditsCallback) );

  // create menu, it's an autorelease object
  CCMenu* pMenu = CCMenu::create(pPlayButton, pHelpButton, pCreditsButton, NULL);
  pMenu->setPosition( ccp(size.width / 2, size.height / 2) );
  pMenu->alignItemsVertically();
  this->addChild(pMenu);
  return true;
}

void HelloWorld::playCallback(CCObject *) {
  // TODO
}
...

Y el resultado: