一、菜单(CCMenu)
Cocos2d-x提供了菜单功能,学习具体菜单项之前需要先了解一下CCMenu。
CCMenu是Cocos2d-x的菜单类,本身不具备菜单具体属性,将一些具体类型的菜单添加进去达到添加菜单的目的,可以说它是一个容器;在Cocos2d-x中使用菜单功能首先要创建这个容器,之后把我们创建好的菜单项(CCMenuItem)添加到CCMenu容器中,此时才可以使用。
看看它的继承关系:
类中部分代码如下:
class CC_DLL CCMenu : public CCLayerRGBA { public: static CCMenu* create(); static CCMenu* create(CCMenuItem* item,...); static CCMenu* createWithArray(CCArray* pArrayOfItems); static CCMenu* createWithItem(CCMenuItem* item); void alignItemsVertically(); void alignItemsVerticallyWithPadding(float padding); void alignItemsHorizontally(); void alignItemsHorizontallyWithPadding(float padding); };由此可以看出有四种创建CCMenu的方法:
static CCMenu* create():创建一个空的菜单。
static CCMenu* create(CCMenuItem* item,...):通过菜单项创建菜单,参数结尾需要添加NULL。
static CCMenu* createWithArray(CCArray* pArrayOfItems):通过一个CCArray容器来创建菜单,CCArray中包含要添加的菜单项。
static CCMenu* createWithItem(CCMenuItem* item):通过单一的菜单项来创建菜单。
void alignItemsVertically():设置为水平排列。
void alignItemsVerticallyWithPadding(float padding):设置为水平排列,并设置菜单项边框间距。
void alignItemsHorizontally():设置为垂直排列。
void alignItemsHorizontallyWithPadding(float padding):设置为垂直排列,并设置菜单项边框间距。
CCMenu的默认触摸优先级是-128。
无论是菜单CCMenu创建还是使用菜单都需要有菜单项CCMenuItem,下面来看看CCMenuItem。
二、菜单项(CCMenuItem)
菜单CCMenu的使用离不开菜单项CCMenuItem,CCMenu是一个容器,其中包含菜单项CCMenuItem后才能使用。
菜单项CCMenuItem的子类定义各种具体的菜单条目,继承关系如下:
菜单项CCMenuItem一般不直接创建使用,而是使用其子类。
(一)CCMenuItemFont
先来看看创建方式:
class CC_DLL CCMenuItemFont : public CCMenuItemLabel { public: static CCMenuItemFont * create(const char *value); static CCMenuItemFont * create(const char *value,CCObject* target,SEL_MenuHandler selector); };const char *value:要显示在菜单项上的字符串。
SEL_MenuHandler selector:菜单项点击后的响应函数,一个回调函数。
实例:
bool HelloWorld::init() { CCLayer::init(); CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCMenuItemFont *itemFont = CCMenuItemFont::create("gong"); itemFont->setFontSize(100); itemFont->setTag(10); itemFont->setTarget(this,menu_selector(HelloWorld::menuCallBack)); CCMenu* menu = CCMenu::create(); menu->addChild(itemFont); addChild(menu); return true; } void HelloWorld::menuCallBack(CCObject* obj) { CCMenuItemFont* item = (CCMenuItemFont*)getChildByTag(10); CCLog("%s",item->fontName()); CCLog("%d",item->fontSize()); }创建CCMenuItemFont后,通过setTarget给此菜单项添加了一个回调函数。
fontName获取默认字体。
fontSize获取默认字号。
(二)CCMenuItemAtlasFont
先来看看CCMenuItemAtlasFont的create函数:
class CC_DLL CCMenuItemAtlasFont : public CCMenuItemLabel { public: static CCMenuItemAtlasFont* create(const char *value,const char *charMapFile,int itemWidth,int itemHeight,char startCharMap); static CCMenuItemAtlasFont* create(const char *value,char startCharMap,SEL_MenuHandler selector); };const char *value:要在菜单项中显示的字符串。
const char *charMapFile:包含字符集的图片,.png格式。
int itemWidth:图片中,每个字符所占宽度。
int itemHeight:图片中,每个字符所占高度。
char startCharMap:图片中,第一个字符,实际上需要的是ASCII码。
CCObject* target:调用此菜单项的对象的指针。
SEL_MenuHandler selector:回调函数,单击此菜单项调用的函数。
实例:
bool HelloWorld::init() { CCLayer::init(); CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCMenuItemAtlasFont* itemAtlas = CCMenuItemAtlasFont::create("123","Labelatlas.png",24,32,'0',this,menu_selector(HelloWorld::menuCallBack)); CCMenu* menu = CCMenu::createWithItem(itemAtlas); addChild(menu); return true; } void HelloWorld::menuCallBack(CCObject* obj) { CCLog("CCMenuItemAtlasFont"); }
(三)CCMenuItemLabel
此CCMenuItemLabel类派生出CCMenuItemAtlasFont与CCMenuItemFont。
先来看看CCMenuItemLabel的create函数。
class CC_DLL CCMenuItemLabel : public CCMenuItem { public: static CCMenuItemLabel * create(CCNode*label,SEL_MenuHandler selector); static CCMenuItemLabel* create(CCNode *label); }CCNode*label:是一个Label,可以是CCLabelTTF、CCLabelAtlas、CCLabelBMFont三种。
CCObject* target:欲调用此菜单项的对象指针。
SEL_MenuHandler selector:回调函数,菜单项单击后执行。
实例:
bool HelloWorld::init() { CCLayer::init(); CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCLabelTTF* ttf = CCLabelTTF::create("gong","New",30); CCLabelAtlas* atlas = CCLabelAtlas::create("125",'0'); CCLabelBMFont* bmfont = CCLabelBMFont::create("JianYiLiGong","bitmapFontTest.fnt"); CCMenuItemLabel* itemLabelTTF = CCMenuItemLabel::create(ttf,menu_selector(HelloWorld::menuCallBack)); CCMenuItemLabel* itemLabelAtlas = CCMenuItemLabel::create(atlas,menu_selector(HelloWorld::menuCallBack)); CCMenuItemLabel* itemLabelBmfont = CCMenuItemLabel::create(bmfont,menu_selector(HelloWorld::menuCallBack)); CCMenu* menu = CCMenu::create(itemLabelTTF,itemLabelAtlas,itemLabelBmfont,NULL); menu->alignItemsVerticallyWithPadding(50); addChild(menu); return true; } void HelloWorld::menuCallBack(CCObject* obj) { CCLog("CCMenuItemLabel"); }
CCMenuItemLabel通过CCLabel来创建菜单项。
(四)CCMenuItemImage
class CC_DLL CCMenuItemImage : public CCMenuItemSprite { public: static CCMenuItemImage* create(); static CCMenuItemImage* create(const char *normalImage,const char *selectedImage); static CCMenuItemImage* create(const char *normalImage,const char *selectedImage,const char *disabledImage); static CCMenuItemImage* create(const char *normalImage,SEL_MenuHandler selector); static CCMenuItemImage* create(const char *normalImage,const char *disabledImage,SEL_MenuHandler selector); }const char *normalImage:菜单项未选中时候的图片。
const char *selectedImage:菜单项选中后的图片。
const char *disabledImage:菜单项无效的图片。
CCObject* target: 调用此菜单项的对象指针。
SEL_MenuHandler selector:回调函数,点击菜单项后调用。
实例:
bool HelloWorld::init() { CCLayer::init(); CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCMenuItemImage* itemImage = CCMenuItemImage::create("CloseNormal.png","CloseSelected.png","HelloWorld.png",menu_selector(HelloWorld::menuCallBack)); CCMenu* menu = CCMenu::create(); menu->addChild(itemImage); addChild(menu); return true; } void HelloWorld::menuCallBack(CCObject* obj) { CCLog("CCMenuItemImage"); }而如果使用了参数为空的create,这可以使用CCMenuItemImage类中下述方法进行必要的设置。
class CC_DLL CCMenuItemImage : public CCMenuItemSprite { public: /** sets the sprite frame for the normal image */ void setNormalSpriteFrame(CCSpriteFrame* frame); /** sets the sprite frame for the selected image */ void setSelectedSpriteFrame(CCSpriteFrame* frame); /** sets the sprite frame for the disabled image */ void setDisabledSpriteFrame(CCSpriteFrame* frame); }CCMenuItemImage通过三张图片创建菜单项。
(五)CCMenuItemSprite
CCMenuItemSprite派生出CCMenuItemImage,CCMenuItemSprite的create如下:
class CC_DLL CCMenuItemSprite : public CCMenuItem { public: static CCMenuItemSprite * create(CCNode* normalSprite,CCNode* selectedSprite,CCNode* disabledSprite = NULL); static CCMenuItemSprite * create(CCNode* normalSprite,SEL_MenuHandler selector); static CCMenuItemSprite * create(CCNode* normalSprite,CCNode* disabledSprite,SEL_MenuHandler selector); }CCNode* normalSprite:正常状态下的精灵。
CCNode* selectedSprite:被选中后的精灵。
CCNode* disabledSprite:无效时候的精灵。
SEL_MenuHandler selector:回调函数,单击此菜单项后执行。
实例:
bool HelloWorld::init() { CCLayer::init(); CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCSprite* normal = CCSprite::create("CloseNormal.png"); CCSprite* select = CCSprite::create("CloseSelected.png"); CCSprite* disabled = CCSprite::create("HelloWorld.png"); CCMenuItemSprite* itemSprite = CCMenuItemSprite::create(normal,select,disabled); itemSprite->setTarget(this,menu_selector(HelloWorld::menuCallBack)); CCMenu* menu = CCMenu::create(); menu->addChild(itemSprite); addChild(menu); return true; } void HelloWorld::menuCallBack(CCObject* obj) { CCLog("CCMenuItemSprite"); }CCMenuItemSprite通过创建三个精灵来创建菜单项。
(六)CCMenuItemToggle
CCMenuItemToggle用来创建一个滚动的菜单项,创建CCMenuItemToggle需要多个CCMenuItem对象。部分代码如下:
class CC_DLL CCMenuItemToggle : public CCMenuItem { public: /** creates a menu item from a CCArray with a target selector */ static CCMenuItemToggle * createWithTarget(CCObject* target,SEL_MenuHandler selector,CCArray* menuItems); /** creates a menu item from a list of items with a target/selector */ static CCMenuItemToggle* createWithTarget(CCObject* target,CCMenuItem* item,...); /** creates a menu item with no target/selector and no items */ static CCMenuItemToggle* create(); /** creates a menu item with a item */ static CCMenuItemToggle* create(CCMenuItem *item); /** add more menu item */ void addSubItem(CCMenuItem *item); /** return the selected item */ CCMenuItem* selectedItem(); };由上述代码可以看出有四个create来创建CCMenuItemToggle:
static CCMenuItemToggle * createWithTarget(CCObject* target,CCArray* menuItems); static CCMenuItemToggle* createWithTarget(CCObject* target,...); static CCMenuItemToggle* create(); static CCMenuItemToggle* create(CCMenuItem *item);其中:
SEL_MenuHandler selector:响应此菜单项的回调函数。
CCArray* menuItems:包含一些CCMenuItem子对象的CCArray。
CCMenuItem* item:一个CCMenuItem对象。
实例:
bool HelloWorld::init() { CCLayer::init(); CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCMenuItemFont* font1 = CCMenuItemFont::create("0"); CCMenuItemFont* font2 = CCMenuItemFont::create("1"); CCMenuItemFont* font3 = CCMenuItemFont::create("2"); CCMenuItemFont* font4 = CCMenuItemFont::create("3"); CCArray* array = CCArray::create(); array->addObject(font1); array->addObject(font2); array->addObject(font3); array->addObject(font4); CCMenuItemToggle* toggle = CCMenuItemToggle::createWithTarget(this,menu_selector(HelloWorld::menuCallBack),array); CCMenu* menu = CCMenu::createWithItem(toggle); addChild(menu); return true; } void HelloWorld::menuCallBack(CCObject* obj) { CCMenuItemToggle* item = (CCMenuItemToggle*)obj; int index = item->getSelectedIndex(); CCLog("%d",index); }
(六)CCMenu的一些方法
void alignItemsVertically(); void alignItemsVerticallyWithPadding(float padding); void alignItemsHorizontally(); void alignItemsHorizontallyWithPadding(float padding);上面的四个函数可以设置菜单按照水平对齐还是垂直对齐,并且可以设置间隔。
bool HelloWorld::init() { CCLayer::init(); CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCMenuItemFont* font = CCMenuItemFont::create("0"); CCMenu* menu = CCMenu::createWithItem(font); CCSize menuSize = menu->getContentSize(); CCPoint menuPoint = menu->getPosition(); CCPoint anPoint = menu->getAnchorPoint(); CCLog("width = %f,height = %f",menuSize.width,menuSize.height); CCLog("x = %f,y = %f",menuPoint.x,menuPoint.y); CCLog("Anchor x = %f,anPoint.x,anPoint.y); addChild(menu); return true; }
得到的结果:
width = 480.000000,height = 320.000000
x = 240.000000,y = 160.000000
Anchor x = 0.500000,y = 0.500000
由此可知菜单位置设置为屏幕的中点位置,并且菜单的大小与屏幕大小相同,菜单的锚点为0.5与0.5。