Since I am just starting up with Cocos2D-x and I come from an iPhone background I figured I should note the things that are different in -x from the iPhone version of the library.

What this guide won’t do is tell you how to port your existing Cocos2D game to Cocos2D-x, as it targets a project that is created from scratch.

Although the iPhone version is not the original one (the original one was a Python library called Cocos2D), I will refer to it as “the original Cocos2D” below.

IDE

Fortunately you can use XCode as your IDE, as everything should work out of the box. Just install the project templates from the downloadable zip file from the Cocos2D-x website and create a new project. I personally prefer XCode3 over Xcode4 because it is not a steaming pile of crap.

Language

You probably figured out by now you will be writing C++. For years I avoided it because I thought it was ugly – I still do, but I used to, too.

The syntax is quite different from Objective C – one thing that I noticed is that it is impossible to write beautifully formatted C++ code (if anyone can point out some beautifully formatted, readable, functional C++ code, please do so, I am more than open minded to suggestions!).

Due to the efforts of the -x devs, the structure of the Cocos2D-x applications, classes and object usage will mimic the feel of the original library.

Memory management

Since C++ does not have automatic or semi-automatic memory management I believed I had to go the old fashion way, but due to the efforts made by the Cocos2D-x team, an autorelease system has been put into place. The autorelease system works similarly to the iOS NSAutoreleasePool.

Manual memory management

Objective C

CCSprite *sprite = [[CCSprite alloc] initWithFile:@"player.png"]
 
// ...
 
[sprite release]; // sprite gets deallocated

C++

CCSprite *sprite = new CCSprite();
sprite->initWithFile("player.png");
 
// ...
 
sprite->release(); // sprite gets deallocated

Semiautomatic memory management (autorelease)

Objective C

CCSprite *sprite = [CCSprite spriteWithFile:@"player.png"];
[sprite autorelease];
 
// ...
 
// sprite will get deallocated sometime in the future after the current methods is done executing

C++

CCSprite *sprite = CCSprite::spriteWithFile("player.png");
sprite->autorelease();
 
// ...
 
// sprite will get deallocated sometime in the future

Relevant C++ crash course

There are plenty of C++ books and tutorials out there in the wild. What this crash course aims to do is give you a quick glimpse over the differences between Cocos2D code in Objective C and Cocos2D-x in C++.

Defining classes

Objective C

#import
#import "cocos2d.h"
 
@interface HelloWorld : CCLayer {
 
}
 
+ (id)scene;
 
@end

C++

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
 
class HelloWorld : public cocos2d::CCColorLayer
{
public:
	// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
	virtual bool init();  
 
	// there's no 'id' in cpp, so we recommand to return the exactly class pointer
	static cocos2d::CCScene* scene();
};
 
#endif

Objective C has the #import macro that makes sure you don’t include a file twice. Since C++ doesn’t have that we have to resort to the classic #ifndef solution. The way this works is by checking if a certain macro has been set and if it hasn’t it means that the file has not been included so far. The macro is then defined, causing all future includes to skip over the class definition code. Most IDEs do this by default when creating a new file, so you probably shouldn’t worry too much about it.

The following line defines a new class and tells it to extend CCColorLayer which can be found in the cocos2d namespace.

class HelloWorld : public cocos2d::CCColorLayer

You can think of namespaces as virtual containers for your classes – without using namespaces you would not be able to have two classes with the same name in the same project. When you’re writing all of the code that’s not a problem, but what do you do if you are trying to add two libraries to your project that don’t use namespaces? You’re right, they are going to conflict with eachother. Objective C does not have such a construct, but the closest thing to it is the prefix you are assigning to your classes.

The following line

static cocos2d::CCScene* scene();

declares a new static function called scene of type cocos2d::CCScene*. This is a class (or static) method similar to Objective C methods declared like this:

+ (id)scene;

Defining methods

In Cocos2D implementing the scene method is one of the very first things you do when you create a new layer subclass. Let’s look at the differences:

Objective C

+ (id)scene {
    CCScene *scene = [CCScene node];
    AboutScene *layer = [AboutScene node];
    [scene addChild: layer];
    return scene;
}

C++

CCScene* HelloWorld::scene()
{
    // 'scene' is an autoreleased object
    CCScene *scene = CCScene::node();
 
    // 'layer' is an autoreleased object
    HelloWorld *layer = HelloWorld::node();
 
    // add layer as a child to scene
    scene->;addChild(layer);
 
    // return the scene
    return scene;
}

Creating a new CCScene object is as simple as calling CCScene::node(). This will instantiate a new autoreleased object.

Calling a method on an object is done via scene->addChild(layer);, as opposed to Objective C’s [scene addChild: layer];

Calling a super method

C++ does not have the super keyword, but provides you a way of calling a method implemented in the parent class. Let’s look at the init method of a scene:

Objective C

- (id)init {
	if ((self = [super initWithColor:ccColor4B(255, 255, 255, 255)])) {
	//...
	}

C++

bool HelloWorld::init()
{
	if ( !CCColorLayer::initWithColor( ccc4(255,255,255,255) ) )	{
		return false;
	}
	//...
}

The current instance

In Objective C you can access the current instance by calling self:

[self addTarget];

In C++ you can do the exact same thing by using the this keyword:

this->addTarget();

Using selectors

Using selectors in Objective C feels natural and very straightforward, as this functionality is built-in. C++ does not have such a tight integration with selectors, but since they are actually just a pointer to a method this behavior can be easily replicated.

[CCCallFuncN actionWithTarget:self
                     selector:@selector(spriteMoveFinished:)];

Due to the efforts of the Cocos2D-x team, in C++ this is as simple as sending the class method pointer as an argument to a macro:

CCCallFuncN::actionWithTarget(
    this, // the instance that the selector will be called on
    callfuncN_selector(HelloWorld::spriteMoveFinished)); // the selector

One disadvantage in Cocos2D-x is that there are separate macros for each selector type:

#define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR)
#define callfunc_selector(_SELECTOR) (SEL_CallFunc)(&_SELECTOR)
#define callfuncN_selector(_SELECTOR) (SEL_CallFuncN)(&_SELECTOR)
#define callfuncND_selector(_SELECTOR) (SEL_CallFuncND)(&_SELECTOR)
#define callfuncO_selector(_SELECTOR) (SEL_CallFuncO)(&_SELECTOR)
#define menu_selector(_SELECTOR) (SEL_MenuHandler)(&_SELECTOR)
#define event_selector(_SELECTOR) (SEL_EventHandler)(&_SELECTOR)

So if you want to create a menu item and you want it to call a method when the item is activated you will have to use the menu_selector macro. If you want to call another type of selector, you will have to use one of the other macros. I am not exactly clear where do they all fit, but I am sure a little playing around will reveal what goes where.

Useful resources

Share this article

Tagged on:     

9 thoughts on “iPhone Cocos2D user’s guide to Cocos2D-x (Part1)

  • August 10, 2011 at 12:54 pm
    Permalink

    iphone developer. And had just started to follow some articles on cocos2d for iPhone and got to know about this cocos2d-x. Now, i have a serious doubt about what to go on with. should i now shift to learning cocos2dx? Or do i require to know cocos2d properly first?? m in some serious confusion. Please help!

    Reply
    • August 10, 2011 at 1:03 pm
      Permalink

      To tell you the truth, Cocos2D-x is built around the iPhone Cocos2D mindset and it is obvious that the team ha gone to great lengths to make it relatively easy for the Cocos2D developer to switch tracks.

      I don’t think that you need to learn Cocos2D first, it depends on your proficiency in C++ really. There are plenty (plenty plenty plenty) more resources on Cocos2D than Cocos2D-x out there so if you are at the beginner level it may feel easier to just go with the iPhone version for now.

      If you feel you are proficient enough in C++ and knowledgeable enough in Objective C, it shouldn’t be a problem for you to port the tutorials you find on the net to Cocos2D-x.

      Bottom line – it is a bit more difficult to start with Cocos2D-x, unless you have some experience in both C++ and Objective C (doesn’t mean that the effort doesn’t pay off :) ).

      Reply
      • August 11, 2011 at 10:58 am
        Permalink

        oky… thankx for dat. :) actually i do know some basics related to c++. but i have decided to stay with cocos2d for some time and also learn c++ for some time. but can u suggest me some stuff related to c++?

        Reply
        • August 11, 2011 at 11:02 am
          Permalink

          Try this guide: http://www.cplusplus.com/doc/tutorial/ There are plenty of books around as well, but some go actually into too much detail.

          This guide is straightforward enough and doesn’t go beating around the bush. Also, looking at Objective C and C++ code side by side and actually writing C++ code will make things easier and faster for you.

          Reply
  • February 16, 2012 at 10:04 am
    Permalink

    For the record, your semiautomatic memory management example code is wrong. This will overrelease, as CCSprite::spriteFromFile will return an already autoreleased CCSprite*.

    Reply
  • October 13, 2012 at 10:08 pm
    Permalink

    @srikanth Have you managed to convert it? If yes, can you please help me?

    Reply
  • April 20, 2013 at 12:44 am
    Permalink

    Kudos fo “I personally prefer XCode3 over Xcode4 because it is not a steaming pile of crap”. I really laughet at how detailed you presented your problems with XCode4 :D

    Reply
  • May 10, 2013 at 2:32 am
    Permalink

    CCSprite *sprite = [CCSprite spriteWithFile:@"player.png"];
    [sprite autorelease];

    The [sprite autorelease]; line will cause the app to crash. [CCSprite spriteWithFile:@"player.png"]; is already autoreleased. Can’t call release or autolease if you have not called alloc/init prior.

    The only actions that can be performed on sprite are:
    [sprite retain]; OR sprite = nil;

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">

Email
Print