Cocos2d-x中有一个Menu菜单系统,你可以在游戏开发中创建菜单。菜单是什么呢?我们使用各种软件都会接触到菜单,比如VS上的菜单栏:
我对菜单的理解是:菜单由一系列菜单项组成(当然也可以只有一个),每个菜单项都可以显示文字,并且像按钮一样具备交互性,点击可以触发其相关功能。就拿上面的VS的菜单栏来说,这个菜单栏就是一个菜单,FILE、EDIT、VIEW这些都是菜单上的菜单项,我们点击它们就会触发其各自的相关逻辑功能。
在cocos中,菜单类CCMenu是CCLayer的子类,但其本身并不具备菜单属性,而是作为一个容器,将一些具体类型的MenuItem菜单项添加进去来实现菜单功能的。在开发中,如果我们想要使用菜单,一般的步骤是:
- 创建Menu,设置Menu的位置等属性;
- 创建MenuItem,设置MenuItem的位置等属性;
- MenuItem加入到Menu;
- Menu加入到层。
关系图如下:
MenuItem一共有4种创建方式:
- 通过Label创建MenuItem
- 通过文字创建MenuItem
- 通过Sprite创建MenuItem
- 通过图片名称创建MenuItem
我们分别来实现这几种创建MenuItem的方式:
一.通过Label创建MenuItem
此方法我们要先创建出个Label,然后在通过Label来创建MenuItemLabel。
新建一个cocos工程,还是在HelloWorldScene类init()方法中进行修改:
//创建Menu
auto _menu = Menu::create( );
//设置Menu位置属性
_menu->setPosition(Vec2::ZERO);
//创建Label
auto _label = Label::createWithSystemFont("MenuItemLabel","Arial",30);
//通过Label创建MenuItem
//参数:1.label 2.回调函数
auto _menuItemLabel = MenuItemLabel::create(_label,CC_CALLBACK_1(HelloWorld::menuItemCallback,this));
//设置MenuItem位置属性
_menuItemLabel->setPosition(Vec2(480,320));
//将MenuItem添加到Menu上
_menu->addChild(_menuItemLabel);
//将Menu添加到父节点层上
this->addChild(_menu);
此外,我们需要声明和实现MenuItem的回调函数,这里只做个打印:
//声明 menuItem回调函数
//void menuItemCallback(cocos2d::Ref * ref);
//实现 menuItem回调函数
void HelloWorld::menuItemCallback(cocos2d::Ref * ref)
{
log("menuItemCallback!");
}
运行效果:
当我们点击菜单项时,会执行其绑定的回调函数,可以看到以下打印输出:
二.通过文字创建MenuItem
我们在以上工程中修改代码:
我们直接调用MenuItemFont类的create()方法即可:
//创建Menu
auto _menu = Menu::create( );
//设置Menu位置属性
_menu->setPosition(Vec2::ZERO);
//创建menuItemFont
//参数:1.文字 2.回调函数
*auto _menuItemFont = MenuItemFont::create("MenuItemFont", CC_CALLBACK_1(HelloWorld::menuItemCallback, this));
//设置menuItemFont位置属性
_menuItemFont->setPosition(Vec2(480, 200));
//将menuItemFont添加到Menu上
_menu->addChild(_menuItemFont);
//将Menu添加到父节点层上
this->addChild(_menu);
运行效果:
点击菜单项同样会调用回调函数有打印输出。
三.通过Sprite创建MenuItem
此方法需要先创建2个精灵,分别为菜单项点击态和非点击态,然后通过创建的精灵来创建MenuItemSprite。
代码如下:
//创建Menu
auto _menu = Menu::create();
//设置Menu位置属性
_menu->setPosition(Vec2::ZERO);
//创建精灵,分别为正常和按下时显示
auto _spriteNormal = Sprite::create("Button_Normal.png");
auto _spritePress = Sprite::create("Button_Press.png");
//创建menuItemSprite
auto _menuItemSprite = MenuItemSprite::create(_spriteNormal, _spritePress, CC_CALLBACK_1(HelloWorld::menuItemCallback, this));
//设置menuItemSprite位置属性
_menuItemSprite->setPosition(Vec2(300, 320));
//将menuItemSprite添加到Menu上
_menu->addChild(_menuItemSprite);
//将Menu添加到父节点层上
this->addChild(_menu);
运行效果:
非点击态:
点击态(此时执行回调函数有打印输出):
四.通过图片名称创建MenuItem
此方法同样需要两张图片分别用于菜单项的正常和按下时显示,与前一种方法的不同之处在于不用创建精灵,而是通过图片名称直接创建menuItemImage。
//创建Menu
auto _menu = Menu::create();
//设置Menu位置属性
_menu->setPosition(Vec2::ZERO);
///通过图片名直接创建MenuItem
auto _menuItemImage = MenuItemImage::create("Button_Normal.png", "Button_Press.png", CC_CALLBACK_1(HelloWorld::menuItemCallback, this));
_menuItemImage->setPosition(Vec2(700, 320));
//将menuItemImage添加到Menu上
_menu->addChild(_menuItemImage);
//将Menu添加到父节点层上
this->addChild(_menu);
运行效果与前一种一样,这里就不赘述了。
好了,以上便是MenuItem的4种创建方法,我们需要注意的是这里分别调用了MenuItemLabel、MenuItemFont、MenuItemSprite和MenuItemImage4个类的create()方法来创建的menuItem。
以上。