1. Integrate Cocos2d-x into an UIKit application

    Cocos2d-x is a multi-platform open source (MIT) C++ / OpenGL. With one source code, you can generate binaries for iPhone, Android, and more. That’s a big time saver.

    Cocos2d-x is younger than its famous brother Cocos2d and despite being actively developed and quite stable already, it lacks of tutorials.

    As I’ve struggled a bit to integrate Cocos2d-x into a UIKit application (UIVIewController), here is a walkthrough.

    [UPDATE 2012-06-14] As pointed out in the comments, if you want to achieve the contrary (use UIKit components over a Cocos2d-x app), there is an open source project about it on GitHub shared by Di Wu.

    [UPDATE 2012-06-28] New tutorial! Achieve the same thing on Android, launch a Cocos2d-x actvity in your Android apps.

    http://www.youtube.com/v/J28NwrKLp50

    0. Better than words, here is a sample project for people in a hurry. Sample project Cocos2dxOnUikit.zip.

    1. You have a UIKit project on iPhone, at one time, you want to show a Cocos2d-x OpenGL view in a view controller.

    2. Download the latest sources of Cocos2d-x (I used Cocos2d-x v1 / Opengl 1.1).

    3. Unzip and have a look in cocos2dx/platform and cocos2dx/platform/third_party. There are many platforms you don’t need.

    4. In Xcode (4.3 in my case), add all sources you need (of course only add the source for iOS platform in cocos2dx/platform/ios and cocos2dx/platform/third_party/ios).

    5. Remove references to cocos2dx/platform/CCImage.cpp and CCThread.cpp.

    6. In your “Library Search Paths” $(SRCROOT)/cocos2dx/platform/third_party/ios/libraries/ (for the curl library used by cocos2dx)

    7. In your “Headers Search Paths” add $(SRCROOT)/cocos2dx and $(SDKROOT)/usr/include/libxml2 (for libxml framework)

    8. In “Other C++ Flags” add -DCC_UNDER_IOS

    9. Copy and add AppDelegate.cpp and AppDelegate.h from the HelloWorld example (shipped with the Cocos2d-x sources) into your project.
    Comment out the applicationDidFinishLaunching() method as shown on the screenshot (this is more or less the code we will move into the ViewController later).
    Side note : make sure the AppDelegate of your UIKit app is not called AppDelegate too as you would have in your project 2 AppDelegate.h files.

    10. Change the extension of YourAppDelegate.m into YourAppDelegate.mm (for turning it into Objective C++ wich makes it compatible with C++ calls).

    11. Add in YourAppDelegate.mm :
    
    #import "AppDelegate.h"
    static AppDelegate s_sharedApplication;
    

    12. Now change the extension of YourViewController.m into YourViewController.mm.

    13. Add this quick fix if it has not been merged in the main branch. To avoid a leak when releasing the OpenGL view.

    14. In cocos2dx/support/zip_support/ioapi.cpp change fopen64 into fopen, fseeko64 into fseeko, ftello64 into ftello.

    15. Add these frameworks.
    
    OpenGLES.framework
    libxml2.dylib
    libz.1.2.5.dylib
    QuartzCore.framework
    

    16. Now, the last step, Cocos2d-x OpenGL view is integrated into the controller’s view (used as a modal view controller) :
    
    -(void)loadOpenglScene:(CGRect)rect {
        cocos2d::CCApplication::sharedApplication().run();
     
        EAGLView *glView = [EAGLView viewWithFrame: rect
                                        pixelFormat: kEAGLColorFormatRGBA8
                                        depthFormat: GL_DEPTH_COMPONENT16_OES
                                        preserveBackbuffer: NO
                                        sharegroup:nil
                                        multiSampling:NO
                                        numberOfSamples:0];
        
        [self.view insertSubview:glView atIndex:0];
        
        cocos2d::CCDirector *pDirector = cocos2d::CCDirector::sharedDirector();
        
        pDirector->setOpenGLView(&cocos2d::CCEGLView::sharedOpenGLView());
        
        // enable High Resource Mode(2x, such as iphone4) and maintains low resource on other devices.
        // pDirector->enableRetinaDisplay(true);
        
        // turn on display FPS
        //pDirector->setDisplayFPS(true);
        
        // pDirector->setDeviceOrientation(kCCDeviceOrientationLandscapeLeft);
        
        // set FPS. the default value is 1.0/60 if you don't call this
        pDirector->setAnimationInterval(1.0 / 60);
    
        // create a scene. it's an autorelease object
        cocos2d::CCScene *pScene_ = cocos2d::MyGraphicsEngine::scene(myparams);
        
        // run
        pDirector->runWithScene(pScene_);
    
        // Retained because if not, we get an BAD ACCESS exception when we try to release the Cocos2d-x environment later
        [[EAGLView sharedEGLView] retain];
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    
    
        // In this example we use a navigation bar and a "close" button, the Cocos2d-x view will be added below the navigation bar
        UINavigationBar *bar=[[[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 49)] autorelease];
        [self.view insertSubview:bar atIndex:0];
        UIBarButtonItem *closeButton=[[[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStyleDone target:self action:@selector(close)] autorelease];
        
        UINavigationItem *item = [[UINavigationItem alloc] initWithTitle:@""];
        item.rightBarButtonItem = closeButton;
        item.hidesBackButton = YES;
        [bar pushNavigationItem:item animated:NO];
        [item release];
        
        
        [self loadOpenglScene:CGRectMake(0, bar.frame.size.height, self.view.frame.size.width, self.view.frame.size.height-bar.frame.size.height)];
        
    }
    
    -(void)close {
        //TODO
    }
    
    -(void)viewDidDisappear:(BOOL)animated {
        //Release Cocos2d-x stack
        cocos2d::CCDirector *pDirector = cocos2d::CCDirector::sharedDirector();
        //CCDirector::end() is asynchronous. That's why you can't release [EAGLView sharedEGLView] here after (you'll get a BAD ACCESS exception), and that's why we put it un viewDidUnload.
        pDirector->end();
        
        [self checkWin];
    }
    
    - (void)viewDidUnload {
        [[EAGLView sharedEGLView] release];
        [super viewDidUnload];
        // Release any retained subviews of the main view.
    }
    

    17. Stay tuned @jpsarda.
     
  1. myhandmadejewelry likes this
  2. eralpkaraduman likes this
  3. jpsarda posted this