Dissecting Cocos2D - CCDirector
Cocos2D is a great open source game framework created by Ricardo Quesada with contributions from its community. Not only does it save you time in creating 2D-based games for the iOS, a careful reading of the code will make you a better game developer and an iOS coder.
In this series, we will dissect Cocos2D a little bit at a time, pick up valuable coding techniques and examine design patterns and decisions utilized by Cocos2D along the way.
We will start off by looking at the entry point, the heart of Cocos2D - the CCDirector class. CCDirector is a singleton class that manages and coordinates the overall operation of your game. Another common name for this in a game framework is a Game Manager. Most of the time there is only one game manager managing an entire game, that's why CCDirector is a singleton class.
Let's look at some code snippets in CCDirector and see what we can learn from it:
static CCDirector *_sharedDirector = nil;
+ (CCDirector *)sharedDirector
{
if (!_sharedDirector) {
//
// Default Director is TimerDirector
//
if( [ [CCDirector class] isEqual:[self class]] )
_sharedDirector = [[CC_DIRECTOR_DEFAULT alloc] init];
else
_sharedDirector = [[self alloc] init];
}
return _sharedDirector;
}
+(id)alloc
{
NSAssert(_sharedDirector == nil, @"Attempted to allocate a second instance of a singleton.");
return [super alloc];
}
The above code snippet implements a singleton. The static keyword appearing in the class scope has different semantic than had it appear in a method/function scope. In class scope, the static keyword means your variable is internally linked only and therefore not visible outside of this class. In method/function scope, a static variable persists its value across multiple calls to the method, which makes it behaves like a member variable but visible to your method only.
The alloc method makes it so if you attempt to instantiate CCDirector directly (via the regular two-staged creation of alloc-init), your code will fail the assertion.
The code snippet above is typically how you would implement singleton for your class.
Notice the class check inside the init method, which isn't always present in typical singleton implementation. What does this do?
[ [CCDirector class] isEqual:[self class]]
This tests to see if the instantiation is on the abstract base class or from one of its derived concrete classes. If it is from the base class, instantiate the default derived class via the macro CC_DIRECTOR_DEFAULT. Currently there are four types of CCDirector-derived classes for iOS (implemented in CCDirectorIOS.m class) and one type for Mac (CCDirectorMac.m class).
For CCDirectorIOS, they are briefly: CCDirectoryTypeNSTimer, CCDirectorTypeMainLoop, CCDirectorTypeThreadMainLoop, and CCDirectorTypeDisplayLink. We will look at these in more details in a later series.
Since we mention CCDirectorIOS, we will digress a little and look at one code snippet in CCDirectorIOS class:
@interface CCDirector () -(void) setNextScene; -(void) showFPS; -(void) calculateDeltaTime; @end
This is a category method for CCDirector. Why does it appear inside CCDirectorIOS? Actually with this technique, you are able to implement CCDirector's private method setNextScene from within CCDirectorIOS that you wouldn't otherwise able to. This is the same technique developers use to override Apple's private API's implementation. The downside to using category method technique to extend/change the behavior of a base class's method is that you can't call the base class's method like you can via inheritance using the super keyword.
That's all for this series. In the next series, we will look at CCDirector in more details and learn a few tricks along the way.
cocos2d,
iOS in
Development,
idevblogaday 





