Using Cocos2D in a UIKit project

I recently needed to add a “water ripple” effect to a project. Although there is a simple water ripple effect built-in to the SDK, it really didn’t fill my needs. It seemed like my only options would be to quickly boost my OpenGL skills (from none to something), or find an alternative. I soon found a really nice water ripple effect built for Cocos2D, which was exactly what I wanted. The only stumbling block was how to integrate Cocos2D into my existing UIKit project. As it turns out, it’s fairly simple.

First, download the source for Cocos2D. If your UIKit project is using ARC, you’ll need to download the “bleeding edge” version from GitHub, as this is currently the only version in which the header files are all ARC friendly. If you are not using ARC, the latest stable version should be fine (currently v1.0.1). Once you have the Cocos2D source, locate the file “cocos2d-ios.xcodeproj”. Open up your UIKit project, and drag this file into your file navigator. You should end up with something like this:

Next, go to the Build Phases settings for your project, and add the Cocos2D library (libcocos2d.a) as a linked library. You’ll probably also need to add OpenGLES.framework, and libz.dylib, like so:

You’ll also need to modify your Build Settings. Set Always Search User Paths to YES, and add the Cocos2D source directory to the User Header Search Paths (as a recursive path):

At this point, you should be able to import the “cocos2d.h” header into one of your source files, and compile your project. If you are using ARC and get some build errors, make sure your Cocos2D source is the development (bleeding edge) branch. Even though Cocos2D itself is not ARC enabled, it’s no problem to combine it with an ARC enabled project, provided you are using the correct version.

Now that Cocos2D is part of your project, it’s time to write some code. I only needed Cocos2D in one small part of my application, so I decided to limit it to a single UIViewController. This is the code that I used:

- (void)viewDidLoad {
	[super viewDidLoad];
	
	CCScene *introScene = [CCScene node];
	self.introLayer = [IntroLayer node];
	[introScene addChild:self.introLayer];
	
	if(![CCDirector setDirectorType:kCCDirectorTypeDisplayLink]) {
		[CCDirector setDirectorType:kCCDirectorTypeDefault];
	}
		
	CCDirector *director = [CCDirector sharedDirector];
	EAGLView *glView = [EAGLView viewWithFrame:CGRectMake(0, 0, 1024, 768)
			pixelFormat:kEAGLColorFormatRGB565 depthFormat:0];
	[director setOpenGLView:glView];
	[director setDeviceOrientation:kCCDeviceOrientationPortrait];
	[director setAnimationInterval:1.0/60];
	[self setView:glView];
	[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGB565];
	[[CCDirector sharedDirector] runWithScene:introScene];
	
	[self.introLayer setupScene];
}

- (void)runRippleAnimation {
	[self.introLayer runRippleAnimation];
}

- (void)endRippleAnimation {
	CCDirector* director = [CCDirector sharedDirector];
	[director end];
}

I won’t go through the details of how to create a CCScene and CCLayer – there’s plenty of Cocos2D tutorials out there. The code that you’ll be most interested in is this:

if(![CCDirector setDirectorType:kCCDirectorTypeDisplayLink]) {
	[CCDirector setDirectorType:kCCDirectorTypeDefault];
}
	
CCDirector *director = [CCDirector sharedDirector];
EAGLView *glView = [EAGLView viewWithFrame:CGRectMake(0, 0, 1024, 768)
			pixelFormat:kEAGLColorFormatRGB565 depthFormat:0];
[director setOpenGLView:glView];
[director setDeviceOrientation:kCCDeviceOrientationPortrait];
[director setAnimationInterval:1.0/60];
[self setView:glView];
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGB565];
[[CCDirector sharedDirector] runWithScene:introScene];

This basically sets up the Cocos2D environment, and starts running your CCScene. And that’s it! I presented this UIViewController modally, but I expect you should be able to use this method within a subview just as easily.

Combining UIKit and Cocos2D does suffer a performance hit, but I’m not doing anything overly complex here, so it wasn’t a problem. I’m also not sure if this is entirely the correct way to do things, but again – it works, so I’m happy.

Cocos2D has a heap of really nice effects, with a great community behind it. If you need some extra pizazz in your app, it might just be the way to go.

This entry was posted in blog, idevblogaday. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

15 Comments

  1. Posted January 25, 2012 at 11:38 am | Permalink

    I am looking for a nice OpenGL based image processing solution. Do you think Cocos2d can be used for an added framework to handle image processing such as Brightness, Contrast, Hue, or Effect?

    • Posted January 25, 2012 at 3:56 pm | Permalink

      Honestly I’m not sure, I don’t know enough about Cocos2D to answer. Given that it’s a gaming framework though, I’m not sure how good at would be at that sort of image processing. Maybe take a look into Core Image?

  2. Posted January 25, 2012 at 8:46 pm | Permalink

    Hi Ben, well explained and to the point!

    You don’t have to add libz.dylib. You can also add -lz in Build Settings under Other Linker Flags to achieve the same.

    Adding the cocos2d-ios.xcodeproj into your project has a side effect: there are dozens of test case schemes littering the scheme selection and scheme manager. You can delete them one by one or instead create an empty cocos2d project from the Xcode template, then add the cocos2d code in the libs subfolder to your project. Preferably as a static library to make use of ARC.

    @Peter: you’ll be looking at OpenGL ES programming, preferably 2.0 with shaders. In that case Cocos2D won’t help you that much. By default it can only render images transparent or with a color tint. Brightness, contrast, hue and other effects at the least require modifying the glBlendFunc. See this visual blend func tool to check which effects you can expect to recreate without shader programming.

    • Posted January 26, 2012 at 8:25 am | Permalink

      Thanks Steffen! Means a lot coming from you :-)

      I did notice all the test case schemes, but kinda forgot about them. Creating an empty project sounds like a nice way to go about it.

  3. Posted February 9, 2012 at 8:09 am | Permalink

    Looks like I’ve been asked to do exactly this at work and my first thought was to revise this tutorial. Many thanks!

  4. Posted March 6, 2012 at 11:18 am | Permalink

    Hi… Very nice tutorial. I’ve seen a couple of sites that even copied it.
    Even though I have followed every single step, I still have problems importing cocos2d.h.
    I’m using
    #import “cocos2d.h”
    but Xcode says “‘cocos2d.h’ file not found.“.
    Strangely, though, autocomplete lists the file as I type the command!
    I’ve gone through the tutorial over and over and can’t import cocos2d.
    The only difference I’ve noticed in my case is that when I add the “libcocos2d.a” library in the Build Phases, it’s being listed in red — not black like yours.
    PLEASE HELP!

  5. Posted March 6, 2012 at 12:12 pm | Permalink

    FINALLY GOT IT!
    I began searching for problems specific to “user header search paths” and finally got a solution. The problem is that the path to my Cocos2d source files contains whitespaces and, because of this, I have to escape the whitespace in the search path.
    If anyone else is interested, this is where I found the solution:
    Stack Overflow.

    Thanks, again, for this great tutorial… Maybe you should add this bit of information to it! I struggled 2 days with this problem.

    • Posted March 6, 2012 at 4:36 pm | Permalink

      Great, glad you got it sorted! It’s crazy in this day and age that whitespaces still cause problems…

  6. Pterie
    Posted March 21, 2012 at 4:21 pm | Permalink

    I have a very weird problem. I can import cocos2d.h in the app delegate and root view controller that is created by Xcode, but I cannot import it in any other files I create.

    When I try to import in any other file, Xcode highlights the line and says “file not found”.
    Surprisingly, code sense suggests “cocos2d.h” when I start typing, but once I finish typing, it says file not found. Likewise, code sense does not recognize and classes or methods from the cocos2d api when I am in this new file. But in app delegate & root view controller everything works fine.

    In addition, there is no problem building. Even though code sense etc doesn’t work in the new files, everything compiles and runs fine.

    Is there a step I could have missed out? I am using cocos2d 1.0.1 and Xcode 4.3.1

    • Pterie
      Posted March 21, 2012 at 4:23 pm | Permalink

      My problem seems similar to Spencer. cocos2d is red in my build phases too. But the path to my cocos2d sources does not contain whitespaces, so I’m not sure what to do.

  7. Pterie
    Posted March 21, 2012 at 4:40 pm | Permalink

    I renamed my folder containing cocos2d – I removed the “.”‘s , so that the folder reads cocos2d101 instead of cocos2d1.0.1.

    This solved the import problem —> now the message saying file not found is gone.
    But it hasn’t fixed code sense. Code sense doesn’t make any suggestions regarding the cocos2d api. But when I CMD + click on a cocos2d method, it takes me to the source.

    I can’t figure it out. :S

  8. Pterie
    Posted March 21, 2012 at 4:51 pm | Permalink

    Problem solved.

    I needed to add the user header paths / search user path settings in the project settings. I had only added it to the target. This is why it compiled properly, but didn’t show up in code sense.

    The “.”‘s don’t seem to matter. I rename my folder back to cocos2d1.0.1. :S

    • Posted March 27, 2012 at 8:07 am | Permalink

      Glad you got it all sorted in the end, and thanks for coming back and reporting what you needed to do. Hopefully this helps someone out in the future!

  9. Imantha SIlva
    Posted June 11, 2012 at 7:48 am | Permalink

    I ran in to a problem same as Spencer . But in mu case it was the hyphen causing the problem . Didn’t know how to workaround hyphens so I just changed the folder name to a simple one.

    • Chang Liu
      Posted August 21, 2012 at 10:40 am | Permalink

      You can also achieve this by putting double quotes around your path without changing path name. My company(someone who is obviously not technical) put a “.” inside my user name so the path wouldn’t work for me initially either.

Post a Comment?

Your email is never published nor shared.

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>