by Alex Rozanski

cocos2d for Mac

Nov 21st 2010Published in Cocoa, Development

cocos2d for iPhone is an open-source framework that is used to create 2D graphics and games for the iPhone and iPad, based on the original cocos2d project (which is written in Python). cocos2d for iPhone is a port to iOS and is written in Objective-C, and is built upon OpenGL. The cocos2d for iPhone project has been successful with games written for the iPhone, and there is a long list of apps which use the library.

In recent months it has been ported to the Mac (presumably with the upcoming opening of the Mac App Store) and in this post I’ll walk you through getting it up and running for Mac projects and then finish by listing some of the differences between the iOS version and the Mac port.

1. Get the source

At the time of writing, the Mac port of cocos2d is still in beta; but the latest version can be found on GitHub or is easily cloned from the command line with Git:

$ git clone https://github.com/cocos2d/cocos2d-iphone.git

You can also checkout the develop branch if you want the blindingly up-to-date code, but I didn’t bother.

2. Build the cocos2d static library

Once you’ve checked out the source, there is an Xcode project called cocos2d-mac in the root directory. Open this up in Xcode, and select the cocos2d target, which is a static library.

With the upcoming opening of the Mac app store, building cocos2d as a static library is the best way to go, since it is likely that the only permitted way of linking against third party libraries is if they are static libraries (this is where the compiled object files are copied into the application executable when it is built, rather than being loaded at runtime; see this post for more information).

I did a Release build and set an installation directory for the static library as a “shared” folder I store libraries in that I use in several projects.

To do an installation when the project is being built, you need to set three values in the Build settings for the static library target (Ensuring the Configuration dropdown box is for a Release build):

  1. Set the Installation Build Products Location to the root directory that you want to copy the static library to when it is built.
  2. Set the Installation Directory to the relative path that you want to copy the static library to when it is built. This value is appended to the installation build products location, forming the full path to which the library is copied to.
  3. Check the Deployment Location checkbox.

Now do a Release build of the cocos2d static library target. The library will be built then copied to the location that you specified in the build settings.

3. Setting up the project

With the static library built and copied to a shared folder, you now need to create a new project and add cocos2d. First you need to add the static library that you have built. By default, the cocos2d static library is built as libcocos2d.a.

If you did a Release build and installed it to a folder then locate this and drag it into the Frameworks > Linked Frameworks folder in the Groups & Files Pane. Uncheck “Copy items into destination group’s folder” and check the checkbox for the application target that you want to link cocos2d with.

Now you need to add some other frameworks to your application target, namely:

  • ApplicationServices.framework
  • QuartzCore.framework
  • OpenGL.framework
  • libz.dylib

These are the dependencies of cocos2d and have to be added to the project because cocos2d is being linked as a static library.

You also need to set a flag in Other Linker Flags in the Build settings for your application target, which is -all_load. This forces copying of all the object files from the cocos2d static library to the application executable, and you will run into problems later if you don’t, for example when using cocos2d objects in Interface Builder, since the relevant object files won’t have been copied into the applicatione executable from the static library.

Have a look at this technical note for more information.

4. Using cocos2d in your projects

For those who have used cocos2d on the iPhone/iPad, building an application using the framework is pretty much the same process as for iOS devices. For those who haven’t, I would recommend looking at the following resources, especially before reading further with this article:

Although both are listed as being “for iPhone”, the documentation is almost identical for both platforms.

However, there are a few distinct differences between using cocos2d for iOS and for the Mac, namely:

  • The input devices are different
  • Integrating with AppKit/UIKit is slightly different

Fortunately, since the Mac port of cocos2d is a port, most of the work has been done for us.

Event Dispatcher

Those who have used cocos2d on iOS devices will be used to using CCTouchDispatcher with the CCTouchDelegateProtocol for touch events.

For the Mac, you will be using the CCEventDispatcher instead, which handles both mouse and keyboard events. To register a node to receive mouse events, call -addMouseDelegate:priority: on CCEventDispatcher:

[[CCEventDispatcher sharedDispatcher] addMouseDelegate:node priority:0];

To register a node to receive keyboard events, call -addKeyboardDelegate:priority:

[[CCEventDispatcher sharedDispatcher] addKeyboardDelegate:node priority:0];

The priority argument denotes the priority of which mouse or keyboard events are sent to the delegate(s). The nodes that have been registered with a lower priority will be notified of the events before the nodes with a higher priority.

Mouse delegates are notified of:

- (BOOL)ccMouseDown:(NSEvent*)event;
- (BOOL)ccMouseDragged:(NSEvent*)event;
- (BOOL)ccMouseMoved:(NSEvent*)event;
- (BOOL)ccMouseUp:(NSEvent*)event;

- (BOOL)ccRightMouseDown:(NSEvent*)event;
- (BOOL)ccRightMouseDragged:(NSEvent*)event;
- (BOOL)ccRightMouseUp:(NSEvent*)event;

- (BOOL)ccOtherMouseDown:(NSEvent*)event;
- (BOOL)ccOtherMouseDragged:(NSEvent*)event;
- (BOOL)ccOtherMouseUp:(NSEvent*)event;

- (BOOL)ccScrollWheel:(NSEvent*)theEvent;

- (void)ccMouseEntered:(NSEvent*)theEvent;
- (void)ccMouseExited:(NSEvent*)theEvent;

Keyboard delegates are notified of:

- (BOOL)ccKeyUp:(NSEvent*)event;
- (BOOL)ccKeyDown:(NSEvent*)event;

The event process is much like the Cocoa responder chain, in that delegates with the lowest priority are sent the event notifications first. If they respond to the event, they return YES. If they return NO then the notifications are sent to the delegate with the next lowest priority, and so on, until someone responds to the event or the list of delegates is exhausted.

MacGLView

The MacGLView is a subclass of NSOpenGLView which is used to integrate with the cocos2d framework.

When you create the view that you want your cocos2d project to run in, drag an NSOpenGLView out into Interface Builder then change its class to MacGLView, or create a MacGLView in code. Then when you call -setOpenGLView: on CCDirector pass the MacGLView reference in.

Final thoughts

This is just an introduction to using cocos2d in your Mac applications; for more information have a look at the project website or the project page on GitHub.

The version which had the Mac port included is also currently in beta; although I didn’t find any bugs when doing some tests, if you are using cocos2d in any production applications, bear this in mind.

Also make sure to observe LICENSE.cocos2d that is bundled with the source.

Comments — 1

  1. RightThat’sMyName

    Jan 15, 2011

    Great article. Thanks 🙂

Add comment

Please enter your name and comment