So I imagine you’re already coming from the “Getting Started with Cocos2d” tutorial previously posted here, therefore, I’m assuming you’re all squared away with getting the iPhone sdk and XCode setup. For those who might just need a refresher course, the instructions are fairly straightforward to get started with Cocos2d.
Today, we’re going to tackle the wonderful world of menus. You can’t make a game without menus and Cocos2d makes it super easy to do it. But even before we begin we need to make sure we have a system in place so that our game can easily expand so we’re going to also create a Scene Manager.
Source code after the break!
Source code to this tutorial can be downloaded here: MenuTutorial Source Code Download Link
http://www.cocos2d-iphone.org/download
I recommend you stick with the stable releases, unless there is a specific feature you require from a new version. Unzip the folder and the template installation script:
$ sudo ./install_template.sh
This will make a series of cocos-2d templates available from XCode. Launch/restart XCode and choose File->New Project->cocos2d Application.
Try to build the file through the simulator – you can do that by going to Build -> Build and Debug – Breakpoints on – If it doesn’t compile right away, make sure that you’re building to the simulator AND that you have the correct base sdk – I still default my system to 3.1.3 so I can test on my 2nd generation iTouch. Apple is going to be phasing out support for all operating system up to 3.2, however, I still like to make sure my apps are backwards compatible with older operating systems.
Once you run it in the simulator it should look like this:
Side Note: You should test older and newer devices when you can. I’ve made games where I’ve put instruction screens on the loading screen to give the player some helpful hints before the game started and make the loading screen feel faster. However, what may have taken 10 seconds on a gen 1 device was barely noticeable on a newer iPhone. To solve the problem I had to put in a “Continue” button after the loading was complete. Just an interesting item to note!
We’re going to be building a simple menu with a background layer to start with! As we continue these tutorials we’ll be building on top of the foundations we lay out here so it’s important to get a good handling of the ground work from the start. First things first – we don’t want to keep around those HelloWorldScene .h and .m files. So lets start by deleting them!
Now we’re going to create a simple scene manager – we’ll do this so we can have more control over the transition from one layer to the next. Just right click or Ctrl click on the “Class” folder and choose “Add” and “New File”.
We’re going to add a new “New Objective-C” file called “SceneManager” and you should make sure the option is checked to create both a .m and .h file
So what’s the code going in to this file?
#import "cocos2d.h"
#import "MenuLayer.h"
@interface SceneManager : NSObject {
}
+(void) goMenu;
@end
Then add the following to the .m file:
#import "SceneManager.h"
@interface SceneManager ()
+(void) go: (CCLayer *) layer;
+(CCScene *) wrap: (CCLayer *) layer;
@end
@implementation SceneManager
+(void) goMenu{
CCLayer *layer = [MenuLayer node];
[SceneManager go: layer];
}
+(void) go: (CCLayer *) layer{
CCDirector *director = [CCDirector sharedDirector];
CCScene *newScene = [SceneManager wrap:layer];
if ([director runningScene]) {
[director replaceScene: newScene];
}else {
[director runWithScene:newScene];
}
}
+(CCScene *) wrap: (CCLayer *) layer{
CCScene *newScene = [CCScene node];
[newScene addChild: layer];
return newScene;
}
@end
You may have noticed that there was a call for “MenuLayer.h” and a function called “goMenu”. We’re going to add an additional class- you guessed it- MenuLayer.h, much like we added the Scene Manager.
#import "cocos2d.h"
#import "SceneManager.h"
@interface MenuLayer : CCLayer {
}
- (void)onNewGame:(id)sender;
- (void)onCredits:(id)sender;
@end
#import "MenuLayer.h"
@implementation MenuLayer
-(id) init{
self = [super init];
CCLabel *titleLeft = [CCLabel labelWithString:@"Menu " fontName:@"Marker Felt" fontSize:48];
CCLabel *titleRight = [CCLabel labelWithString:@" System" fontName:@"Marker Felt" fontSize:48];
CCLabel *titleQuotes = [CCLabel labelWithString:@"\" \"" fontName:@"Marker Felt" fontSize:48];
CCLabel *titleCenterTop = [CCLabel labelWithString:@"How to build a..." fontName:@"Marker Felt" fontSize:26];
CCLabel *titleCenterBottom = [CCLabel labelWithString:@"Part 1" fontName:@"Marker Felt" fontSize:48];
CCMenuItemFont *startNew = [CCMenuItemFont itemFromString:@"New Game" target:self selector: @selector(onNewGame:)];
CCMenuItemFont *credits = [CCMenuItemFont itemFromString:@"Credits" target:self selector: @selector(onCredits:)];
CCMenu *menu = [CCMenu menuWithItems:startNew, credits, nil];
titleCenterTop.position = ccp(160, 380);
[self addChild: titleCenterTop];
titleCenterBottom.position = ccp(160, 300);
[self addChild: titleCenterBottom];
titleQuotes.position = ccp(160, 345);
[self addChild: titleQuotes];
titleLeft.position = ccp(80, 345);
[self addChild: titleLeft];
titleRight.position = ccp(220, 345);
[self addChild: titleRight];
menu.position = ccp(160, 200);
[menu alignItemsVerticallyWithPadding: 40.0f];
[self addChild:menu z: 2];
return self;
}
- (void)onNewGame:(id)sender{
[SceneManager goMenu];
}
- (void)onCredits:(id)sender{
[SceneManager goMenu];
}
@end
Finally modify the app delegate (MenuTutorialAppDelegate.m) to include SceneManager.h
#import "SceneManager.h"
and remove
#import "HelloWorldScene.h"
While we’re here we also need to make a few additional modifications as well. Since all the “runWithScene” logic is now in the SceneManager class we should go ahead and change it up:
[[CCDirector sharedDirector] runWithScene: [HelloWorld scene]];
with:
[SceneManager goMenu];
We’re also going to run our examples for now in Portrait Mode – so that means we need to comment out or remove the following line that tells Cocos2d that we want it in landscape mode.
// Obtain the shared director in order to... CCDirector *director = [CCDirector sharedDirector]; // Sets landscape mode //[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
When you compile and run the project and you should end up with a menu with two buttons like the picture above! Granted they go to the same location, but you’re well on your way to having a great foundation and we’ll make the menus do some more interesting things in part 2.
Source code to this tutorial can be downloaded here: MenuTutorial Source Code Download Link






sending...
Your post is very interesting. I’ve read your blog for few days now and I trully enjoy your blog. Thank you for your great work!
Hi:
I was looking at this tutorial to get what this classes do in your logic. I read the code and though I get almost everything I have a question:
You have a class named SceneManayer that imports MenuLayer, then when you create MenuLayer it also imports SceneManayer; so the thing here is that I don’t get that circular reference in your classes, why do you do that? what am I thinking wrong?
Thanks!
Please change CCLabel to CCLabelTTF everywhere in MenuLayout.m, otherwise it does not want to compile.
Thank you for the wonderful arcticle!
In 0.99.5 the orientation changes to portrait another way:
In RootViewController.m find
return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );
and replace it with
return ( UIInterfaceOrientationIsPortrait( interfaceOrientation ) );
Thanks for letting everyone know Sunlight!
[[CCDirector sharedDirector] runWithScene: SceneManager goMenu];
…throws a invalid use of void expression. Can anyone let me know how to fix this?
Same problem. Do you found solution?
Delete that whole statement, and add :
[SceneManager goMenu];
Happy coding.
Totally great tutorial! I am starting on game development and was looking for something simple about menus on cocos2d…
Thanx.
Awesome tutorial, thanks a bunch! Very helpful! One question though:
I’m new at programming, so maybe this is something dumb that I’m overlooking, but when I replace the icons with my own in the “Resources” folder for the build, it always keeps the default Cocos2D icons. It’s strange since the Cocos2D icons have been replaced with mine and the originals are long gone, yet somehow the app still holds onto the Cocos2D default icons. It only does this with the code implemented in this tutorial. I can swap icons for any other Xcode project of mine just fine. Maybe something in the code? Any ideas? Help would be greatly appreciated! I intend to use this for my game menu but need my icon to work. Thanks in advance!
P.S. I even tried swapping icons in the source code provided and running it just to see if I messed something up with my own project, but still had no luck getting my app icons to appear in the simulator :-/
Hey make sure that your images have the same name, then go Product->Clean, then rebuild it, maybe that will work.
thank u, sceneManager is cool
hey it keeps saying that my titleTop, titleLeft, etc.. is undeclared. i keep looking for what the problem may be but i can’t find it. Any ideas?
The reason you are getting those error “Noob” is because in the current version of Cocos2d does not have a CCLabel anymore. It was split into three different CCLabel classes. If you replace the CCLable with CCLableTTF it should work as is. Had the same problem until I started looking into the cocos2d classes themself to find the error.
I am getting the same error. I am brand new to objective-c programming. I only have a small background in Java. Could you let me know where I’m suppose to declare *titleLeft, *titleRight, etc.? Thanks
Never mind, I see that they are being declared on the same line.
I’m using Xcode 4.3.1 on Lion. When I go to add a new ‘Objective – C’ Class it also asks what subclass we should place the scene manager. What should we choose?
I think I might have figured it out, is it supposed to be CCLabelTTF?
MenuLayer.m:
‘itemFromString:target:selector:’ is deprecated error for:
CCMenuItemFont *startNew = [CCMenuItemFont itemFromString:@"New Game" target:self selector: @selector(onNewGame:)];
CCMenuItemFont *credits = [CCMenuItemFont itemFromString:@"Credits" target:self selector: @selector(onCredits:)];
Using cocos2d v2.0-rc1. Builds and Runs fine.