Whitepaper: Introduction to Cocos2d iPhone
Recently Monocle Studios LLC released its first product, touchDefense, which is an iPhone game. We feel pretty strongly that the game wouldn't have made it all the way to the AppStore if it hadn't been for Cocos2d iPhone, and we want to give back to the project which has done so much for us. This whitepaper is our first first step in doing so.
Let's get started with Cocos2d iPhone.
You can download the finished XCode project for this tutorial here.
Join the iPhone Development Program.
The very first step to becoming an iPhone developers is to register as an iPhone Developer with Apple. It's free to develop (although you'll have to pay $99 for a developer's certificate before you can deploy your applications to actual devices), and is a lot quicker than the alternatives (because there aren't any).
Afterwards you'll need to download the iPhone SDK which is a somewhat massive download (upwards of one gig), so you'll really want to download it on a fast connection.
Getting Started in XCode.
Next we need to setup a standard iPhone project in XCode. Go to File->New Project.
Then click on Application under the iPhone OS header. Finally, choose the
Window-Based Application and then click the Choose... button.
Then name the project (we named ours SimpleGame, and it may be
less confusing to name yours the same way), and save it somewhere
appropriate. Afterwards a fresh new project will open up, looking
like this:
Now is a great time to setup version control for your project! We like to use Git, which makes creating a new repository for the project very quick:
cd SimpleGame
git init
git commit -a -m "Initial commit."
You might prefer Mercurial or SVN, that's good too, just use something!
Before we move on, go ahead and click the Build and Go
button just to see the iPhone simulator launch and load
a white screen (the humble beginnings of SimpleGame).
Removing the window and nib.
For Cocos2d iPhone projects we don't actually want to use any nibs or standard UI components, so we need to make a few modifications to the default project that XCode generated for us (unfortunately, none of the default projects really fit perfectly with using Cocos2d iPhone).
First, go ahead and delete MainWindow.xib from the project.
Second, in Info.plist remove the Main nib file base name key.
Next we'll also need to make a few modifications to the source files.
Start by replacing the contents of main.m with this code:
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil,
@"SimpleGameAppDelegate");
[pool release];
return retVal;
}
Fourth, modify SimpleGameAppDelegate.h to look like this:
#import <UIKit/UIKit.h>
@interface SimpleGameAppDelegate : NSObject <UIApplicationDelegate> {
}
@end
Finally, modify SimpleGameAppDelegate.m to look like this:
#import "SimpleGameAppDelegate.h"
@implementation SimpleGameAppDelegate
- (void)applicationDidFinishLaunching:(UIApplication *)app {
}
@end
Those changes feel a bit like magic, but fortunately you'll only need to make them once and can forget them afterwards until you start a new project. (Better yet, you can make a Cocos2d iPhone project template and just reuse that, then you'll never have to revisit them.)
Integrating Cocos2d iPhone.
Our next step is to grab the Cocos2d iPhone library from Google Code. Head over to the Cocos2d iPhone download page, and grab the 0.7.2 version. Then untar the download.
tar -xvf cocos2d-iphone-0.7.2.tar
Next in your project go to Project->Add to Project..
and navigate to the unzipped directory, then from within that directory
add the External directory to your project.
Be sure to have a checkmark in the box next to
Copy items into destination group's folder (if needed), and then
click the Add button.
Then, and this is an important step,
delete both the Demo directory and CMakeLists.txt in External\Chipmunk by right-clicking
on each and choosing delete. (You'll want to delete the files, not
just the references.) Deleting these means Xcode won't get confused
about whether its building your project or the Chipmunk demos.
You'll also want to delete Tremors from the External
directory, as the current release does not build as shipped.
Afterwards, it's a good idea to try compiling your project to
make sure that nothing has gone haywire (it's always best to
catch odd compilation issues earlier than later).
Now, go back to Project->Add to Project..
and add the cocos2d-iphone-0.7.2/cocos2d folder
to your project as well.
You can optionally repeat that last step to add the cocos2d-iphone-0.7.2/cocoslive folder to your project.
We're going to exclude adding the experimental folder, as it
is both optional and has caused compilation issues in the past.
The last file to add to your project is
cocos2d-iphone-0.7.2/cocos2d/Resources/images/fps_images.png.
Put it into your Resources group.
We're almost done with setup, but our project won't quite compile
yet. In the outline view for the project go down to Targets,
then within it open SimpleGame, and finally select
Link Binary With Libraries. Right click on it, and in the
popup menu go to Add->Add Existing Frameworks... like
in the screenshot below.
In the screen that opens up, click on the plus sign in the bottom
left corner (beneath the list named Linked Libraries). After
clicking on the plus sign, a list of frameworks will open up, and
from it you will need to add two frameworks: OpenGLES.framework
and QuartzCore.framework.
After you've added the two frameworks, your linked libraries should look like this:
Now when you build the project, it will actually build. Sure, it isn't actually doing anything yet, but it's not actively failing anymore, which is a nice improvement.
Cleaning up the project.
Let's take a quick intermission to clean up the project groups.
Right now it's difficult to get a hold of the SimpleGameAppDelegate
class because it's at the base level of the project.
Let's make two new groups: Support and Classes.
First, let's move Chipmunk and cocos2d into the Support group.
Then look through the base SimpleGame group and move
SimpleGameAppDelegate.h and SimpleGameAppDelegate.m into the
Classes group. Afterwards your project layout should look something like
this:
None of this rearrangement is strictly necessary, but keeping groups organized has a direct correlation with maintaining your sanity as your project grows more complex.
Creating a main menu.
Now we're going to finally get started with Cocos2d iPhone. However, before any code we'll take a few moments for an overview of the classes we'll be using.
In Cocos2d iPhone you'll be dealing with the Scene and
Layer classes frequently. A Scene is what the players
can see at a given time, and is composed of one or more Layers.
To display a specific Scene, you tell the Director
(which is a singleton) to play it.
Right now we're going to create MenuScene, which is a subclass
of Scene, and will also create MenuLayer, which will
contain the details of our menu.
Finally, we'll need to hook up the applicationDidFinishLaunching
method in our application delegate to tell the Director to
run MenuScene.
We also need to add an image to our project. Download this image and add it to the project. We're going to use it as a background for our menu layer.
Now to start writing some code.
Right click on the Classes group and select Add->New File....
From Cocoa Touch Classes create an NSObject subclass file
named MenuScene.m (leave the option to create a corresponding .h
file checked).
Now open up the MenuScene.h file, and update it to look
like this:
#import <UIKit/UIKit.h>
#import "cocos2d.h"
@interface MenuScene : Scene {}
@end
@interface MenuLayer : Layer {}
-(void)startGame: (id)sender;
-(void)help: (id)sender;
@end
Next we need to flesh out MenuScene.m to implement
the MenuScene and MenuLayer classes.
#import "MenuScene.h"
@implementation MenuScene
- (id) init {
self = [super init];
if (self != nil) {
Sprite * bg = [Sprite spriteWithFile:@"menu.png"];
[bg setPosition:ccp(240, 160)];
[self addChild:bg z:0];
[self addChild:[MenuLayer node] z:1];
}
return self;
}
@end
@implementation MenuLayer
- (id) init {
self = [super init];
if (self != nil) {
[MenuItemFont setFontSize:20];
[MenuItemFont setFontName:@"Helvetica"];
MenuItem *start = [MenuItemFont itemFromString:@"Start Game"
target:self
selector:@selector(startGame:)];
MenuItem *help = [MenuItemFont itemFromString:@"Help"
target:self
selector:@selector(help:)];
Menu *menu = [Menu menuWithItems:start, help, nil];
[menu alignItemsVertically];
[self addChild:menu];
}
return self;
}
-(void)startGame: (id)sender {
NSLog(@"start game");
}
-(void)help: (id)sender {
NSLog(@"help");
}
@end
For the time, being we're going to leave the startGame
and help methods as stubs. We'll come back and update
them a bit later.
Now we have our menu implemented, we just need to open up
the two (.h and .m) SimpleGameAppDelegate files
so we can tell the Director to load MenuScene when
the application launches.
In SimpleGameAppDelegate.h at the top add an import for
cocos2d and MenuScene:
#import <UIKit/UIKit.h>
#import "cocos2d.h"
#import "MenuScene.h"
Next, open up the SimpleGameAppDelegate.m file
and add this code:
#import "SimpleGameAppDelegate.h"
@implementation SimpleGameAppDelegate
- (void)applicationDidFinishLaunching:(UIApplication *)application {
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window setUserInteractionEnabled:YES];
[window setMultipleTouchEnabled:YES];
[[Director sharedDirector] setLandscape: YES];
[[Director sharedDirector] attachInWindow:window];
[window makeKeyAndVisible];
MenuScene * ms = [MenuScene node];
[[Director sharedDirector] runWithScene:ms];
}
@end
Now you can go ahead and Build and Go the project, and there
is finally something--albeit something incredibly ugly--to see.
Fortunately we're out of the forest now, and it'll be much simpler from here.
Adding a game scene.
Next we're going to create a simple game scene to display
after clicking the Start Game option in the menu.
Let's begin by adding another background to the project
to make it clear which scene we are in.
Add this image to the project. It'll be the game scene's background.
Then create the GameScene.h and GameScene.m
files and put them in the Classes group.
In the GameScene.h file add this code:
#import <UIKit/UIKit.h>
#import "cocos2d.h"
@interface GameScene : Scene {}
@end
@interface GameLayer : Layer {}
@end
And fill in GameScene.m with this code:
#import "GameScene.h"
#import "MenuScene.h"
@implementation GameScene
- (id) init {
self = [super init];
if (self != nil) {
Sprite * bg = [Sprite spriteWithFile:@"game.png"];
[bg setPosition:ccp(240, 160)];
[self addChild:bg z:0];
[self addChild:[GameLayer node] z:1];
}
return self;
}
@end
@implementation GameLayer
- (id) init {
self = [super init];
if (self != nil) {
isTouchEnabled = YES;
}
return self;
}
- (BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
MenuScene * ms = [MenuScene node];
[[Director sharedDirector] replaceScene:ms];
return kEventHandled;
}
@end
Finally, we need to update the startGame: method in the
MenuLayer class to look like this:
-(void)startGame: (id)sender {
GameScene * gs = [GameScene node];
[[Director sharedDirector] replaceScene:gs];
}
One last edit to the code is required to get a working project. Go back to
MenuScene.m and add #import "GameScene.h" to the top of the file.
Go ahead and build the project and play around with it for a couple of seconds. The best part about Cocos2d iPhone is that it all gets easier from here: the hard part's over.
You'll notice in our screenshots that the iPhone status bar
has been disabled. To do the same for your project, simply open up
Info.plist from the Resources folder and add a new boolean
key to the file--UIStatusBarHidden and mark the checkbox.
And that's all we wrote.
You can download the project we developed in this tutorial right here.
We hope that this has been a helpful introduction to getting started with Cocos2d iPhone, and that you'll spend some of your time getting to know this great project.
Thanks for reading, and please send any comments, corrections or complaints to support@monoclestudios.com. If you have any suggestions for future topics, let us know by filling out our suggestion form. Also, don't forget to check out the game we built, touchDefense.
Special thanks to Jeffrey Vanneste for sending in a list of changes to get everything up-to-date with cocos2d-iphone 0.7.2.