Hello, world! Today's post is going to be the first installment in a multi-part series on Cocos2D, the library that we're using to power our games. That means it will probably be relevant only to developers or those who wish to become developers.
As I've mentioned before, there are already LOTS of awesome tutorials out there for learning Cocos2D. In fact, I taught myself everything I know about Cocos2D just from reading great tutorials like this one. It's certainly possible to learn everything you need to know about iOS game development from tutorials, but they don't always go into detail about how exactly the various components of Cocos2D are supposed to work. To gain a useful understanding, you have to experiment on your own. A lot. And it seems to me that the process could be accelerated if more complete references existed on some certain Cocos2D topics. So with this series, rather than try to reinvent the wheel, I'm going to focus specifically on explaining the areas of the library that I found challenging when I myself was learning. I really wish somebody had been there to explain it to me, so now I'm going to explain it to all of you. You're welcome. ;-)
Many Cocos2D tutorials start you out by walking you through the creation of an actual playable game. This can be a great approach, but I've found that it tends to shift some of the focus away from understanding how Cocos2D actually operates in order to concentrate instead on mechanics associated with the specific game that you're building. So today we're not going to build a real game. Sorry. Instead, I'm going to give you a more complete explanation of the thing you actually want to learn--COCOS! I promise as soon as you wrap your head around this stuff, you'll be building your own real fun games in no time! And that's a lot cooler than writing the stupid game I might want to write anyway.
This tutorial assumes that you know how to program regular Objective-C apps for the iPhone. It also assumes that you have the latest stable version (1.0.1 as of this writing) of Cocos2D installed on your machine. It would be a great idea to read at least the first few paragraphs of another tutorial (again, try Ray's) before attempting to tackle this stuff, as they cover questions (such as "How do I install Cocos2D?") that I'm too lazy to address.
So... without further delay...
Let's start a project.
Fire up Xcode and create a new project. Select the plain Cocos2D one--we don't want any extra physics engines for these tutorials. 
You can name it whatever you want, but if you call it "Cocos2DBasics", it might be easier to follow along. Call me Ishmael. Or "Cocos2DBasics". Whatever. 
One last thing before we really dive in. If you're using Cocos2D 1.0.1 on the latest version of Xcode, you'll probably need to change your Deployment Target from the default settings to avoid some weird compilation errors. Don't worry; it's easy. 4.2 is a pretty safe setting these days. (March of 2012) 
Now that that's out of the way... theory!
We should talk some theory. Like so many other systems in Computer Science, Cocos2D is largely based around a single data structure. In Cocos2D, that data structure is a tree.
Nope, try again. You really have been out of school for too long, haven't you?
Yes, that kind of tree! It's a tree made of nodes. And in the case of Cocos2D, each of those nodes is represented by a subclass of the all-encompassing CCNode class. Here's how a typical CCScene's hierarchy tree might look. See?

I'll go into much greater detail about the different kinds of CCNodes and their various functions in a future lesson, but for now, understand that a CCNode is the main element in Cocos2D. Anything that gets drawn or contains things that get drawn is a CCNode.
Also understand that another one of Cocos2D's most important classes is the CCDirector, a singleton class which manages all of the scenes in your game. Scenes (CCScenes) are just a kind of CCNode that the CCDirector can manage. Each CCScene represents a single "screen" in your game... like a menu screen, an intro screen, a game screen, et cetera. And each CCScene generally contains exactly one child, a custom subclass of CCLayer. You can see this in the image above, where the root of the tree is a CCScene, and its only child is a CCLayer. Read that a couple of times until it starts to sink in.
Code is good.
Let's move on to the actual code. Look at the files that the template starts you out with.
You get an AppDelegate class and a RootViewController, which should look fairly familiar if you've ever written an app before. You'll also find HelloWorldLayer and GameConfig. Don't worry about GameConfig for now. Let's look at HelloWorldLayer.m.
HelloWorldLayer is a custom subclass of CCLayer. So keep in mind that all the code in this file is going to be called by the CCLayer that is the only child of the CCScene at the root of the tree (hierarchy). This guy, right here:
The first method is just boilerplate stuff. Don't mess with this until you know what you're doing. ...And even then, you'll rarely touch it unless you're trying to pass data between CCScenes, but again, that's for another tutorial.
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
You're going to see this method in every custom subclass of CCLayer. But what does it mean? Well... it creates a new CCScene object for the CCDirector singleton to manage. And it's only four lines long, so let's go through it. First, it creates a new CCScene object. Second, it creates a HelloWorldLayer object which will become the sole child of the CCScene (as depicted in the tree diagram above). Third, it actually adds the layer as the child. And finally, it returns the whole CCScene, so that it can be passed off to the CCDirector. Making sense yet?
Good. Now let's look at init.
- (id)init {
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if ((self = [super init])) {
// create and initialize a Label
CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World" fontName:@"Marker Felt" fontSize:64];
// ask director the the window size
CGSize size = [[CCDirector sharedDirector] winSize];
// position the label on the center of the screen
label.position = ccp(size.width / 2, size.height / 2);
// add the label as a child to this Layer
[self addChild: label];
}
return self;
}
Again, it's only four lines long. Let's look around. First, as soon as we have initialized our CCLayer, we create a CCLabelTTF object with the text "Hello Word". How very creative. CCLabelTTF is just a subclass of CCLabel, which is one of the many kinds of CCNodes that can be drawn in a CCScene. As one might imagine, a CCLabel is a CCNode that draws text on the screen. Once we've created the "Hello World" CCLabel, we make a call to the CCDirector singleton (See? I told you he would come up.) to ask him what the current size of the screen is, and we store the result. Next, we take that result, and we use it to set the position property of the CCLabel node using some sort of weird function that you've never seen before: ccp. It turns out that ccp is Cocos2D shorthand for CGPointMake, a function you may have encountered when working with coordinates in other iOS applications. It just returns a CGPoint struct with the specified coordinates. Game devs end up working with coordinates all the time, so it's helpful to be able to write "ccp" instead of "CGPointMake" every five seconds. So in this init method, we're setting the position of the CCLabel to a point halfway across the screen and halfway up the screen. Finally, we add the CCLabel as a child and return our newborn HelloWorldLayer.
Wait... did you say halfway up the screen? Don't you mean halfway down the screen? Well... unlike most UIKit applications, Cocos2D games are set directly in an OpenGL environment. Although OpenGL lets you specify whatever kind of coordinate system you'd like, for whatever reason, Cocos2D uses a system with its origin at the lower-left corner of the screen. I know... it took me a while to get used to it too. But now it's kind of second nature.
Moving on, we have the dealloc method. dealloc just calls the standard [super dealloc] method for now, so there's nothing we need to worry about in there. If you're a good programmer, you're probably concerned about leaking memory. I mean... we created a CCLabel object and added it to the layer earlier. Shouldn't we clean that up somehow? Well... in this case, Cocos2D actually handles all the clean-up for us. How nice of it to clean up after us! Sometimes, however, you have to be careful. The rule is that Cocos2D will automatically release any CCNodes (and their subnodes) that are part of the CCScene's hierarchy tree at the time when the CCScene is deallocated. That means that if you created any instance variables in your custom CCLayer subclass that are NOT CCNodes, or that are CCNodes but have NOT been added as children anywhere in the scene... you still have to release those! The good news is that most of the components that make up Cocos2D games are CCNodes that spend their entire lives as children of something attached to the CCScene, so you won't find yourself dealing with the dealloc method very often. Yay!
I'm bored. Are we there yet?
No, but here's something fun for you to do! You haven't actually made any changes to the code yet, but the template code is runnable right out of the box, so go ahead and run it on your device.
As you might expect, here's what you will see:
Those little numbers in the corner are your framerate, displayed in frames-per-second of course! Cocos2D automatically keeps this information handy on your screen at all times during testing so that you can tell when a new chunk of code that you've added is bogging down your game. When you're ready to turn it off (not until just before release), you can comment out the following line in AppDelegate.m:
When you've had enough fun flipping your phone over and watching it auto-rotate, come on back, and I'll show you how to do some really cool stuff!
Sprites
By now I've mentioned a few times that everything in the world of Cocos2D is made up of CCNodes. Everything that gets drawn on the screen, anyway. Like most 2D games, Cocos2D games are largely driven by the interaction of moving images called sprites. In fact, Cocos2D has a class called CCSprite that is a subclass of CCNode. You'll probably use CCSprites more often than any other kind of CCNode.
To make any game, you're going to need some artwork. Conveniently, I have three images ready for us to use as sprites. Here they are:


It's us! Hah. Feel free to use any png files of similar size in your own app--just make sure you pay attention to the file names!
Go ahead and copy these images (or download them from the links at the bottom of this post) to some location on your computer. From there, drag them into the Resources group on the left-hand bar in Xcode. You'll be greeted by the following prompt:![]()
Mark the boxes as you see above, click Finish, and you're all set to use these images as sprites in your project.
Now let's use these images in the code. Go to your header file, HelloWorldLayer.h, and add the following three CCSprites as instance variables:
@interface HelloWorldLayer : CCLayer {
CCSprite *aaron;
CCSprite *bill;
CCSprite *mark;
}
While we're here, let's also define some constants at the top of the file, right after the #import directive. These will be useful here in a second.
#import "cocos2d.h"
#define SCREEN_WIDTH 480.0f
#define SCREEN_HEIGHT 320.0f
Easy enough. Now switch back to the init method in HelloWorldLayer.m. Take out all of the code in the middle, so we're left with a blank slate:
- (id)init {
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if ((self = [super init])) {
}
return self;
}
Now let's fill in the empty space with the code to add those images we downloaded into the CCLayer as CCSprites.
- (id)init {
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if ((self = [super init])) {
//Add Aaron's sprite
aaron = [CCSprite spriteWithFile:@"tinyaaron.png"];
aaron.position = ccp(SCREEN_WIDTH * 0.25f, SCREEN_HEIGHT * 0.5f);
[self addChild:aaron];
//Add Bill's sprite
bill = [CCSprite spriteWithFile:@"tinybill.png"];
bill.position = ccp(SCREEN_WIDTH * 0.5f, SCREEN_HEIGHT * 0.5f);
[self addChild:bill];
//Add Mark's sprite
mark = [CCSprite spriteWithFile:@"tinymark.png"];
mark.position = ccp(SCREEN_WIDTH * 0.75f, SCREEN_HEIGHT * 0.5f);
[self addChild:mark];
}
return self;
}
Nothing fancy here, right? We're doing the same thing three times for three different sprites. First, we create a sprite with the appropriate file name. Second, we position that sprite at a location a certain percentage of the way across the screen. Finally, we add the sprites to the layer. It couldn't get any simpler.
Go ahead and fire it up! Watch in amazement as the three of us appear and stand in place across your iPhone's screen...
We're pretty handsome, eh? Although I specifically asked Mark to draw me with muscles and a jet-pack. I'm still a little bitter that he refused.
OK, when you're done staring at the three of us in all our majesty, let's make the sprites do something.
Sprites run Actions.
If CCNodes are the nouns of Cocos2D, then CCActions are the verbs. CCAction is the all-encompassing base class from which different types of actions are derived. Actions are anything that a CCNode can do over time. For example, some common CCAction subclasses are CCRotateBy, CCScaleTo, and CCMoveTo. Why don't we try out these actions by having our sprites run them?
Back in HelloWorldLayer.m, let's add a new method above init.
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
//Make Bill spin
CCAction *actionSpin = [CCRotateBy actionWithDuration:0.5f angle:360.0f];
[bill runAction:actionSpin];
return YES;
}
This method will be called anytime the player taps the screen. For now, it does only two things. First, it creates a CCAction (a CCRotateBy) that tells a CCNode to rotate by 360.0 degrees in 0.5 seconds. Then, it tells Bill's sprite to run that CCAction. The return value just indicates that the touch was detected (and should be consumed).
Before we can try this out, we need to tell the scene to start detecting touches. To do that, add this line to the beginning of init, right before we add Aaron's sprite:
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
Once that line is in place, give it a spin!
In a future revision of the game, we might want to program Bill to vomit as well. For now, it's Mark's turn. Mwa-ha-ha...
Add another few lines to ccTouchBegan so it looks like this:
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
//Make Bill spin
CCAction *actionSpin = [CCRotateBy actionWithDuration:0.5f angle:360.0f];
[bill runAction:actionSpin];
//Make Mark's sprite scale down or return to normal size
CCAction *actionScale;
if (mark.scale > 0.5f) {
actionScale = [CCScaleTo actionWithDuration:0.75f scale:0.25f];
} else {
actionScale = [CCScaleTo actionWithDuration:0.75f scale:1.0f];
}
[mark runAction:actionScale];
return YES;
}
What is the new code doing? It checks to see if the scale of Mark's sprite is greater or less than 50% at the time when the tap is detected. If the sprite is larger than a scale of 0.5, it creates an action to shrink the sprite to 25% of its original size in three quarters of a second. If the sprite is larger than a scale of 50%, it creates an action to grow the sprite to 100% of its original size in the same amount of time. Finally, it has Mark's sprite run the action. Try it out!

Whoah... where'd Mark go?
And for our last trick, yours truly will perform a magnificent feat. I shall walk to the coordinates that you specify!
Make the following addition to ccTouchBegan below what we just added:
CGPoint touchPoint = [self convertTouchToNodeSpace:touch];
//Make Aaron walk to the touch point
CCAction *actionWalk = [CCMoveTo actionWithDuration:1.0f position:touchPoint];
[aaron runAction:actionWalk];
Hopefully you already see where this is going. Since Cocos2D uses a different coordinate system than the rest of iOS, we need to convert the touch location to OpenGL coordinates. The first line does that. Then we just create a CCMoveTo action to make me walk to those coordinates in 1.0 seconds. Finally, we tell my sprite to run the action. So simple. OK, let's do this!

Re. Spect. Walk.
Congratulations! You understand the basics of Cocos2D.
I'm attaching the finished project for you to download.
By now, I hope you're starting to imagine how these CCNodes and CCActions could be combined to form all kinds of new and interesting games. My recommendation for you: keep experimenting! You can read plenty of great tutorials on the Internet, but in my experience, a little bit of trial and error is the best way to learn. If you have an idea for your own simple game, why not try to build part of it? When you get stuck, remember that Google is a programmer's best friend. I hope you've enjoyed this tutorial and have found it informative. Please remember to check back here soon, as I'll be posting some follow-ups on slightly more advanced topics. For now, thanks for reading and happy coding!
Comments appreciated. Very much. :-)

2 Comments
Nicely done
Submitted by Karl (not verified) on
Looking good! Here are a couple of suggestions:
1. Since there are different dimension/aspect ratio displays, it's probably safer to start newbs off using the actual screen size instead of relying on defines:
CGSize screenSize = [CCDirector sharedDirector].winSize;
2. Instead of registering manually with the touch dispatcher, you can use the isTouchEnabled property of CCLayer:
self.isTouchEnabled = YES;
Thanks, Karl!
Submitted by aaron on
Great suggestions, Karl! And you're absolutely right; both of your suggestions are definitely simpler and easier for the beginning Cocos programmer to understand.
So naturally, I'm not going to use them. :-P
Seriously, your code would make more sense. But there is some method to my madness. I'm planning some future lessons to demonstrate techniques I've used to save myself a lot of time. One of them will show my way of converting between iPhone and iPad coordinates, which works with 'define' statements, and the other will show how to create a custom Cocos2D equivalent of the UIAlertView, which works with the touch dispatcher. So rather than just starting people off using the simplest code and having them un-learn it later, I'm going to stick with my slightly-more-complicated code purely for the sake of consistency.
But thanks again! I really do appreciate the input.
Add new comment