最终效果图:
CCMenu继承自CCLayer,CCLayer继承自CCNode
下面是菜单项的继承结构图
从上面,可以看出,MenuItem是基类,不能使用,
MenuItem的直接子类有3个:MenuItemLabel、MenuItemSprite、MenuItemToggle
其中,MenuItemLabel又有2个子类:MenuItemAtlasFont、MenuItemFont
MenuItemSprite有一个更加方便使用的MenuItemImage,它可以分别定义normal和selected不同状态下的图片
MenuItemToggle,构造时传入一个数组作为参数,效果就是:
每点击一个该菜单项,就顺序切换 参数数组中的【菜单项】
概述cocos2d中的菜单和菜单项
下面是CCMenu的介绍
一行有多少列,下面情况是:第一行为1列,第二行为1列,第3行为2列,第4行为1列
[menu alignItemsInColumnsWithArray:@[@1, @1, @2, @1]];
// 一列有多少行,下面情况是:第一列为1行,第二列为2行,第3列为2行
[menu alignItemsInRowsWithArray:@[@1, @2, @2]];
因为CCMenu这个类在cocos2d v3中没有找到...so -(id) init { if( (self=[super init]) ) { // 1.菜单项(共4种) //------------------------------------ // 文本菜单项 item1_label // 参数用到的CCLabelTTF CCLabelTTF *label = [CCLabelTTF labelWithString:@"Setting" fontName:@"Marker Felt" fontSize:30]; label.color = ccRED; // 创建一个文本菜单项 item1_label CCMenuItemLabel *item1_label = [CCMenuItemLabel itemWithLabel:label block:^(id sender) { CCLOG(@"点击了Setting"); }]; //------------------------------------ // 文本菜单项2 // 类方法设置 MenuItemFont的字体和大小,将会影响到后面所有的 [CCMenuItemFont setFontName:@"Courier New"]; [CCMenuItemFont setFontSize:40]; // 创建一个文本菜单项 item2_Font CCMenuItemFont *item2_Font = [CCMenuItemFont itemWithString:@"Config" block:^(id sender) { CCLOG(@"点击了Config"); }]; //------------------------------------ // 文本菜单项3 CCMenuItemAtlasFont *item3_AtlasFont = [CCMenuItemAtlasFont itemWithString:<#(NSString *)#> charMapFile:<#(NSString *)#> itemWidth:<#(int)#> itemHeight:<#(int)#> startCharMap:<#(char)#>]; //------------------------------------ // 精灵菜单项 CCSprite *normal = [CCSprite spriteWithFile:@"btn-about-normal.png"]; CCSprite *selected = [CCSprite spriteWithFile:@"btn-about-selected.png"]; // 创建一个精灵菜单项 item3_Sprite // 传入一个正常状态下的精灵和选中时的精灵 CCMenuItemSprite *item3_Sprite = [CCMenuItemSprite itemWithNormalSprite:normal selectedSprite:selected block:^(id sender) { CCLOG(@"点击了About"); }]; // 因为是精灵菜单项,所以可以执行动画 CCScaleBy *scale = [CCScaleBy actionWithDuration:1 scale:1.5]; [item3_Sprite runAction:[CCRepeatForever actionWithAction:[CCSequence actions:scale, [scale reverse], nil]]]; //------------------------------------ // 更方便的精灵菜单项的子类 图片菜单项 // 省去了创建精灵的中间步骤(封装到内部去了) CCMenuItemImage *item4_image = [CCMenuItemImage itemWithNormalImage:@"btn-play-normal.png" selectedImage:@"btn-play-selected.png" block:^(id sender) { CCLOG(@"点击了Play"); }]; //------------------------------------ // 开关菜单 在数组中来回切换 高、中、低 // CCMenuItemFont类方法,会影响后面的所有 [CCMenuItemFont setFontName:@"Marker Felt"]; [CCMenuItemFont setFontSize:30]; // 下面是toggle要用到的4个不同的item,每次toggle只会显示其中的一个 CCMenuItemFont *high = [CCMenuItemFont itemWithString:@"High"]; CCMenuItemFont *middle = [CCMenuItemFont itemWithString:@"Middle"]; CCMenuItemFont *low = [CCMenuItemFont itemWithString:@"Low"]; CCMenuItemFont *slient = [CCMenuItemFont itemWithString:@"Slient"]; // toggle菜单项 CCMenuItemToggle *item5_toggle = [CCMenuItemToggle itemWithItems:@[slient, low, middle, high] block:^(id sender) { CCLOG(@"点击了开关"); }]; // 设置第3个为默认选中的 item5_toggle.selectedIndex = 2; //------------------------------------ // 2.整个菜单 CCMenu *menu = [CCMenu menuWithItems:item1_label,item2_Font,item3_Sprite,item4_image,item5_toggle, nil]; // 菜单项垂直排布 // [menu alignItemsVerticallyWithPadding:20]; // [menu alignItemsHorizontally]; // 一行有多少列,下面情况是:第一行为1列,第二行为1列,第3行为2列,第4行为1列 // [menu alignItemsInColumnsWithArray:@[@1, @1, @2, @1]]; // 一列有多少行,下面情况是:第一列为1行,第二列为2行,第3列为2行 [menu alignItemsInRowsWithArray:@[@1, @2, @2]]; [self addChild:menu]; } return self; }
// 类方法设置CCMenuItemFont的默认属性,字体和大小,针对后面所有的均有效 [CCMenuItemFont setFontName:@"Marker Felt"]; [CCMenuItemFont setFontSize:26]; // 生成几个文字标签并指定它们的响应方法 // 1.文本菜单项 CCMenuItemFont* item1_font = [CCMenuItemFont itemFromString:@"Go Back!" target:self selector:@selector(menuItem1Touched:)]; // 2.sprite菜单项 CCSprite* normal = [CCSprite spriteWithFile:@"Icon.png"]; normal.color = ccRED; CCSprite* selected = [CCSprite spriteWithFile:@"Icon.png"]; selected.color = ccGREEN; CCMenuItemSprite* item2_sprite = [CCMenuItemSprite itemFromNormalSprite:normal selectedSprite:selected target:self selector:@selector(menuItem2Touched:)]; // 3.toggle菜单项,就是用其它两个菜单项生成一个切换菜单(图片也可以用于切换) [CCMenuItemFont setFontName:@"Courier New"]; [CCMenuItemFont setFontSize:18]; CCMenuItemFont* toggleOn = [CCMenuItemFont itemFromString:@"I'm ON!"]; CCMenuItemFont* toggleOff = [CCMenuItemFont itemFromString:@"I'm OFF!"]; CCMenuItemToggle* item3_toggle = [CCMenuItemToggle itemWithTarget:self selector:@selector(menuItem3Touched:) items:toggleOn, toggleOff, nil]; // 4.label菜单项 CCMenuItemLabel *item4_label = [CCMenuItemLabel itemWithLabel:label target:self selector:@selector(menuItem1Touched:)]; item4.disabledColor = ccc3(32,32,64); item4.color = ccc3(200,200,255); // 5.用菜单项生成菜单 CCMenu* menu = [CCMenu menuWithItems:item1, item2, item3, item4,nil]; menu.position = CGPointMake(size.width / 2, size.height / 2); [self addChild:menu]; // 排列对齐很重要,这样的话菜单项才不会叠加在同一个位置 [menu alignItemsVerticallyWithPadding:40];
第一个菜单项基于CCMenuItemFont,用于显示一条文字。
当点击此菜单项,它会调用menuItem1Touched方法。
在程序内部,CCMenuItemFont只是简单的生成一个CCLabel。
如果你的场景中已经有一个CCLabel,
你可以把它与CCMenuItemLabel类结合在一起使用。
同样的,有两个使用图片的菜单项;
一个是CCMenuItemImage,它利用图片文件生成菜单项,内部实际上使用了CCSprite来实现。
我在上述代码里使用了另一个类:CCMenuItemSprite。
我认为这个类使用起来更加方便,因为它可以重复利用已有的精灵作为参数。
你可以改变同一个图片的颜色,作为显示触摸后高亮效果的图片
CCMenuItemToggole只接受n个继承自CCMenuItem的对象作为参数,
当用户点击菜单时,菜单将会在n个菜单项之间进行顺序切换。
你可以在CCMenuItemToggle里使用文字标签或者图片。
最后,CCMenu本身被生成和放置在场景中。
因为所有菜单项都是CCMenu的子节点,它们放置的位置都是相对于CCMenu的。
为了不让菜单互相叠加在一起,
你必须调用一个CCMenu的排列对齐方法,
比如alighItemsVerticallyWithPadding