How To Make a Cross-Platform Game with Cocos2D Javascript Tutorial: The Platforms

Ray Wenderlich

This is not a picture – it’s a game! Click to play!

Welcome back to our series on creating a cross-platform game using Cocos2D!

In the first part of this series, you learned how to make the simple game you see over on the right. That’s right, that’s not a picture it’s a game – click it to see for yourself!

So far you have the game code 100% complete, and you have it running on iOS and in debug mode for the web.

But what if you want to publish it to the web for real, run it on the Mac, or get it working on the Android? In this tutorial you’ll round it all up and get it fully working everywhere!

This project begins where the last project left off, so download the project where we left it off if you haven’t already.

Keep reading to fill out your platforms!

Deploying for the Web

I like to think of my Cocos2D-HTML5 setup in terms of “Debug mode” and “Release mode”.

Right now you have “Debug mode” working well. You’re linking to the easy-to-read and expanded Cocos2D source in the Cocos2DSimpleGame\Platform\HTML5 directory which you copied from the Cocos2D-HTML5 distribution.

This is great for debugging because if you ever have a problem you can step right into the Cocos2D-Javascript source code using your browser’s Javascript debugging capabilities. But it is not so good for release.

This is because there’s a lot of overhead in loading files on the web, so loading these directories containing tons of Cocos2D files isn’t very efficient. It’s much better for release to pack all of your Javascript code into a single file.

Luckily, this is quite easy with Cocos2D-Javscript! You can “minimize” all of the Cocos2D framework code and your own into one compressed file for release mode. It isn’t very easy to read, but loads real quickly.

Let’s try this out. Find the directory where you downloaded cocos2d-html5 to, find the cocos2d-html5-v2.x.x\lib\Cocos2d-html5-v2.x.x.min.js file, and copy it into your Cocos2DSimpleGame\Platform\HTML5 directory. If you’ve done it right it should look like the following:

Copying the minified Cocos2D-HTML5 Javascript file

This is the pre-minified version of the Cocos2D framework. Now, you just need to combine this with your own Javascript code into a single file.

While you’re there, also copy cocos2d-html5-v2.x.x\tools\compiler\compiler.jar into your Cocos2DSimpleGame\Platform\HTML5 directory. If you’ve done it right it should look like the following:

Copying the ant Javascript minimizer compiler

You need this file in order to perform the minimization process using a tool called ant.

If you’re a Java programmer, you will be well familiar with ant. If not, bear with me (or should I say “ant” with me?), as you can just modify the example below.

Create a new file Cocos2DSimpleGame\Platform\HTML5\build.xml and replace the contents with the following:

<?xml version="1.0"?>
<project name="Javascript compress project" basedir="." default="compile">
    <taskdef name="jscomp" classname=""
    <target name="compile">
        <jscomp compilationLevel="simple" warning="quiet"
                debug="false" output="${basedir}/../../Cocos2DSimpleGame-v0.1.js">
            <sources dir="${basedir}">
                <file name="Cocos2d-html5-v2.1.1.min.js" />
            <sources dir="${basedir}/../../Src">
                <file name="GameOver.js" />
                <file name="MainLayer.js" />
                <file name="resource.js" />
                <file name="main.js" />

Replace Cocos2d-html5-v2.1.1.min.js with the name of the file for the version of Cocos2D that you are using.

You don’t neeed to really understand what this is doing, except to notice that you have to list out each of the files in your project.

Next, open up a Terminal and swtich to your Cocos2DSimpleGame\Platform\HTML5 directory. Enter the command ant and hit enter. You should see something like the following:

localhost:HTML5 rwenderlich$ ant
Buildfile: /Users/rwenderlich/Desktop/Cocos2D-JS-Series/Part2/Cocos2DSimpleGame/

   [jscomp] Compiling 5 file(s) with 40 extern(s)
   [jscomp] 0 error(s), 0 warning(s)

Total time: 5 seconds

You should also see a new file called Cocos2DSimpleGame\Cocos2DSimpleGame-v0.1.js. Now all you need to do is tell the framework to use this file.

To do this, open Cocos2DSimpleGame\cocos2d.js and replace the beginning part of the file (up to the event listener) with the following:

(function () {
    var d = document;
    var c = {
        // RELEASE
        // DEBUG
    // Rest of file...

So instead of setting the engineDir and appFiles, you just specify one parameter – the SingleEngineFile.

And that’s it! Load index.html into your web browser and refresh to make sure it works.

Testing the minimized version

Also, if you’d like to deploy to an actual web server, now you can! All you need to do is copy these files/directories:

  • Art
  • cocos2d.js
  • Cocso2DSimpleGame-v0.1.js
  • index.html
  • logo.png
  • Sounds

In other words, everything but the Platform and Src directories. And if you want to try it out on my server, check it out!

Deploying for Mac

Remember how easy this was to get working for Cocos2D-iOS? Well it’s just as easy to get working for Cocos2D-Mac.

To do so, open Xcode and create a project with the OX X\cocos2d v2.x\cocos2d OS X with JavaScript template. Name the project Cocos2DSimpleGame, and save it to your Cocos2DSimpleGame\Platform\OSX directory.

Then, like you did for the iOS project, inside Finder find your Cocos2DSimpleGame folder, select the Art, Sounds, and Src folders, and drag them into your Xcode project. Important: In the popup that appears, select Create folder references for any added folders, and set the rest of the options like the screenshot below:

Adding folders to your Xcode project

If you did it correctly, your folders should be blue in Xcode like the screenshot below. If they are yellow, you selected “groups” instead – remove them and try again.

Adding folders to your Xcode project

Next, open Resources\main.js and replace it with the same contents as you did for the iOS version:

director = cc.Director.getInstance();
winSize = director.getWinSize();
centerPos = cc.p( winSize.width/2, winSize.height/2 );
function run()
    director.runWithScene( MainLayer.scene() );

Build and run, and now your game works on the Mac!

Cocos2D Javascript running on the Mac

Deploying for Android

There’s only one platform left – Android. I found this one the hardest to initially get working, but that could be just because I’m an Android n00b :]

This tutorial assumes you have some basic familiarity with Android development and that you have the Eclipse, the Android SDK, and the Android NDK installed. If you do not, check out this tutorial for more information.

Next you need to download the latest version of Cocos2D 2.X. At the time of writing, this is cocos2d-2.1beta3-x-2.1.1.

Unzip the file, then open a Terminal window and switch to the directory where you unzipped the file. Open and update the first two lines to point to where you installed your Android SDK and NDK:

# set environment paramters

Now run the script from the command line and you will get several prompts as to various input values. Let’s run through the prompts and what you need to input one-by-one:

  • Input package path: com.raywenderlich.Cocos2DSimpleGame
  • Target id: Choose from list or hit 1
  • Project name: Cocos2DSimpleGame

It should then create a Cocos2DSimpleGame directory for you. Copy the entire directory to your Cocos2DSimpleGame\Platform\Android folder.

There are two steps to building the project – compiling the C++ code with a command line script, and compiling the Java code with Eclipse. Let’s start with the C++ code.

Building the C++ code

Next, you need to update your script to fix up the paths and to copy the resources from your project’s root directory. Open Cocos2DSimpleGame\Platform\Android\Cocos2DSimpleGame\\ and update the part toward the top of the file that sets up and echos the paths to the following:


Except replace the hardcoded directoreis I have here to where you actually have your copy of Cocos2D-X.

Then add these lines toward the bottom of the file, right after the “copy icons” section:

# copy bindings/*.js into assets' root
cp -f "$BINDINGS_JS_ROOT"/*.js "$APP_ANDROID_ROOT"/assets
# copy resources
cp -rf "$RESOURCES_ROOT/Sounds" "$APP_ANDROID_ROOT"/assets

These copy your project resources from the root directory into the assets directory – a special directory in Android that gets added to your binary.

Now, go to your Cocos2DSimpleGame\Platform\Android\Cocos2DSimpleGame\\ directory in Terminal and run It should compile Cocos2D-X and generate libcocos2d.a, libcocosdenshion.a, and other libraries. You will also see your resources are now in the assets folder.

Building the Java code

To build the Java code, you’ll add the Cocos2D-X Java library to Eclipse and then your project.

To do this, start Eclipse and go to File\New\Other. Choose Android\Android Project from Existing Code, and click Next. For root directory, click Browse, navigate to your cocos2d-xxx/cocos2dx/platform/android/java directory, click Open, Select All, and Finish.

That imported the Cocos2D-X Java library. Now to add your project, go to go to File\New\Other again, choose Android\Android Project from Existing Code, and click Next. For root directory, click Browse, navigate to your Cocos2DSimpleGame\Platform\Android directory, click Open, Select All, and Finish.

If all goes well, your project directory should look like this right now:

Eclipse package explorer for Cocos2D-X Javascript project

I had to do two final things to get this to compile. Right click on Cocos2DSimpleGame and choose Properties. Then go to Android and in the Library section click Add, and select the Cocos2D-X Java library.

Adding Cocos2D-X Library dependency for Cocos2D-X Javascript Project in Eclipse

Finally, right click AndroidManifest.xml and choose Open With\Android Common XML editor. Change the minSdkVerison to 1:

<uses-sdk android:minSdkVersion="1"/>

And modify the application tag to remove any references to the app icon:

<application android:label="@string/app_name">

At this point you can build and run the hello world app on your device, but it won’t load your Javascript code yet. That’s coming next!

Running the Javascript

Just like you did for the other platforms, you need to add some “starter” Javascript. So create a new file Cocos2DSimpleGame\Platform\Android\Cocos2DSimpleGame\Resources\Cocos2DSimpleGame-jsb.js, and replace the contents with the following:

var MW = MW || {};
var appFiles = [
for( var i=0; i < appFiles.length; i++) {
    require( appFiles[i] );
var director = cc.Director.getInstance();
// set FPS. the default value is 1.0/60 if you don't call this
director.setAnimationInterval(1.0 / 60);
var winSize = director.getWinSize();
var centerPos = cc.p( winSize.width/2, winSize.height/2 );
// create a scene. it's an autorelease object
var mainScene = MainLayer.scene();
// run

This is very similar to the main.js file you created for Cocos2D Mac and iOS.

Next, open Cocos2DSimpleGame\Platform\Android\Cocos2DSimpleGame\Classes\AppDelegate.cpp and replace the contents with the following:

#include "AppDelegate.h"
#include "cocos2d.h"
#include "SimpleAudioEngine.h"
#include "ScriptingCore.h"
#include "generated/cocos2dx.hpp"
#include "cocos2d_specifics.hpp"
#include "js_bindings_chipmunk_registration.h"
#include "js_bindings_ccbreader.h"
using namespace CocosDenshion;
bool AppDelegate::applicationDidFinishLaunching()
    // initialize director
    CCDirector *pDirector = CCDirector::sharedDirector();
    // Set the design resolution
    CCEGLView::sharedOpenGLView()->setDesignResolutionSize(480, 320, kResolutionExactFit);
    // turn on display FPS
    // set FPS. the default value is 1.0/60 if you don't call this
    pDirector->setAnimationInterval(1.0 / 60);
    ScriptingCore* sc = ScriptingCore::getInstance();
    CCScriptEngineProtocol *pEngine = ScriptingCore::getInstance();
    return true;
void handle_signal(int signal) {
    static int internal_state = 0;
    ScriptingCore* sc = ScriptingCore::getInstance();
    // should start everything back
    CCDirector* director = CCDirector::sharedDirector();
    if (director->getRunningScene()) {
    } else {
        if (internal_state == 0) {
            //sc->dumpRoot(NULL, 0, NULL);
            internal_state = 1;
        } else {
            internal_state = 0;
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()

This is just some boilerplate code that starts up Cocos2D Javascript. I got it from one of the samples that ccomes with Cocos2D-X.

Finally, you need to make a few changes to the build scripts in order to pull in the Javascript bindings libraries. Open Cocos2DSimpleGame\Platform\Android\Cocos2DSimpleGame\\jni\ and replace the contents with the following:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := game_shared


LOCAL_SRC_FILES := hellocpp/main.cpp \
                   ../../Classes/AppDelegate.cpp \


LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
LOCAL_WHOLE_STATIC_LIBRARIES += spidermonkey_static
LOCAL_WHOLE_STATIC_LIBRARIES += scriptingcore-spidermonkey



$(call import-module,cocos2dx)
$(call import-module,CocosDenshion/android)
$(call import-module,external/chipmunk)
$(call import-module,scripting/javascript/spidermonkey-android)
$(call import-module,scripting/javascript/bindings)

Don’t worry if you don’t understand this stuff – it’s just telling the compiler which libraries to bring in.

Open Cocos2DSimpleGame\Platform\Android\Cocos2DSimpleGame\\jni\ and replace the contents with the following:

APP_STL := gnustl_static

Finally, go to your Cocos2DSimpleGame\Platform\Android\Cocos2DSimpleGame\\ directory in Terminal and run again. It should compile everything again but bring in your updated AppDelegate and the bindings code this time.

Once it’s finished, refresh your Eclipse and build and run – and the app works on your Android!

Cocos2D-X Javascript game working on Android

Note: The Android version is a little dodgy on my test device. The music stops after the first reset of the level, and sometimes it hangs completely! I have no clue why this is, so if anyone else is more experienced with Android and Cocos2D-X development and does know please let me know :]

Where To Go From Here?

Here is the final example project from this tutorial series.

Congratulations – you have now made a cross platform game using Cocos2D Javascript Bindings and got it working on iOS, HTML, Android, and the Mac – all using the same code!

What’s more, but you have a well thought out directory structure that makes working across the different platforms a breeze.

I hope this tutorial has piqued your interest about Cocos2D Javascript development. If you would like to see more tutorials about Cocos2D Javascript please let me know.

In the meantime, if you have any comments or questions, please join the forum discussion below!

Ray Wenderlich

Ray is an indie software developer currently focusing on iPhone and iPad development, and the administrator of this site. He’s the founder of a small iPhone development studio called Razeware, and is passionate both about making apps and teaching others the techniques to make them.

When Ray’s not programming, he’s probably playing video games, role playing games, or board games.

User Comments


  • What a great set of tutorials... I was just investigating different HTML5 gaming APIs with the hope of using PhoneGap to accomplish cross platform release, but that was not looking to be very promising for developing anything with a decent frame rate and responsiveness.

    Is it possible to access tilt input from mobile devices and keyboard input from Mac using same javascript source code (obviously with some logic to check whether tilt/keyboard input is available)? Also, are you able to use other javascript libraries and still release to all the platforms (for example, the javascript FaceBook API)?

    Thanks, and I hope you add additional cocos2d-javascript tutorials in the future.
  • yes, tilt (accelerometer) api exists, and it even works on macbook, and yes, macbook got accelerometer built in, it is compatible with Cocos2d-iPhone and Cocos2d-X

    However, Javascript API designed for the web pages will not work, as DOM is not implemented in Cocos2d-iPhone and Cocos2d-X.
    those kind of code you will need to rewrite to use the native sdk for native app
  • Thanks for the great tutorial :)

    I tried to port one of my former ios game html5 and everything works fine except that when I tried to embed the game into a wordpress post (just like you do in the tutorial)

    The structure of all my files:

    -root (
    - GameDeploy
    - all files here (js, ccbi, png ... no folders inside)

    And the error occurs when loading resource:

    Code: Select all

    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".
    XHR finished loading: "".

    GET 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//splashTitle.png
    GET 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//about-ja.png 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//mainBg.png
    GET 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//about-en.png
    GET 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//about-zh.png
    GET 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//tableBg1.jpg
    GET 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//paigow.png
    GET 404 (Not Found)
    GET 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//tableBg2.jpg
    cocos2d:Failed loading resource: undefined/GameDeploy//element.png
    GET 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//tableBg3.jpg
    GET 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//tableBg4.jpg
    GET 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//tableBg5.jpg
    GET 404 (Not Found)
    cocos2d:Failed loading resource: undefined/GameDeploy//tutorial.png

    And my resources-html5.js file:

    Code: Select all

    var dir = "/GameDeploy/";

    var ccb_resources = [
        {type:'image', src:dir + "splashTitle.png"},
        {type:'image', src:dir + "about-zh.png"},
        {type:'image', src:dir + "about-en.png"},
        {type:'image', src:dir + "about-ja.png"},
        {type:'image', src:dir + "element.png"},
        {type:'image', src:dir + "mainBg.png"},
        {type:'image', src:dir + "paigow.png"},
        {type:'image', src:dir + "tableBg1.jpg"},
        {type:'image', src:dir + "tableBg2.jpg"},
        {type:'image', src:dir + "tableBg3.jpg"},
        {type:'image', src:dir + "tableBg4.jpg"},
        {type:'image', src:dir + "tableBg5.jpg"},
        {type:'image', src:dir + "tutorial.png"},

        {type:'ccbi', src:dir + "AboutScene.ccbi"},
        {type:'ccbi', src:dir + "CFSGamePlayScene.ccbi"},
        {type:'ccbi', src:dir + "HelpScene.ccbi"},
        {type:'ccbi', src:dir + "HighScoreScene.ccbi"},
        {type:'ccbi', src:dir + "LevelSelectScene.ccbi"},
        {type:'ccbi', src:dir + "MainMenuScene.ccbi"},
        {type:'ccbi', src:dir + "OpenningTitle-en.ccbi"},
        {type:'ccbi', src:dir + "OpenningTitle-ja.ccbi"},
        {type:'ccbi', src:dir + "OpenningTitle-zh.ccbi"},
        {type:'ccbi', src:dir + "OptionLayer.ccbi"},
        {type:'ccbi', src:dir + "PauseLayer.ccbi"},
        {type:'ccbi', src:dir + "ReadySetGo.ccbi"},

        {type:'plist', src:dir + "element.plist"},
        {type:'plist', src:dir + "paigow.plist"},
        {type:'plist', src:dir + "tutorial.plist"}

    You see all the ccbi and plist files loads successfully but when it comes to the image files the path to load became weird (where dose that "undefined" come from ~)

    Hope you can give me some advice, thanks :)
  • What about the .js files?? Would they be visible?? That way you could eassyly get your game cloned !
  • For anyone interested I had a problem with ...

    #include "generated/cocos2dx.hpp"

    changed it to

    #include "generated/jsb_cocos2dx_auto.hpp"

    and it worked.

  • Great tutorial. I have a question. How can you load a json file from the folder 'src' in main.js? Thanks
  • Hi,
    Thanx for your great tutorial , but when I run it on Android device , it quits the app immediately with no errors.What could be the possible problem?
  • Hi , thanks for this wonderful tutorial,
    However the output i am getting is
    "Failed to load resource: the server responded with a status of 404 (Not Found)" : refering to undefined platform/jsloader,js

    i followed all the steps as it is and ran the ant command which completed with no errors.
    Can you please guide me as to where i may have gone wrong
  • is it possible that im encountering this error because of using cocos2d-html5-v2.1.4.min.js
    could something have changed between 2.1.1 to 2.1.4 that probably requires a different method of deployment
  • Hi Ray, super tut man, but I hav one little problem:

    Im trying to run the "" file: I get an error: :o sebastian$ bash

    ..."Compile++ thumb : game_shared <= AppDelegate.cpp
    jni/../../Classes/AppDelegate.cpp:6:34: fatal error: generated/cocos2dx.hpp: No such file or directory
    compilation terminated.
    make: *** [obj/local/armeabi/objs/game_shared/__/__/Classes/AppDelegate.o] Error 1
    make: Leaving directory `/Users/sebastian/RayWenderlich/Cocos2DSimpleGame/Platform/Android/Cocos2DSimpleGame/'


    I am using the cocos2d-x-2.1.4 - I would prefer to use it, rather than the Beta 2.1.1 that your used at the time of the writing of your tut.

    Do you have any Idea whats going on here?

    The Process I followed was as follows:

    1. Downloaded your Final package for the "The Platforms" tutorial
    2. Updated the with my paths
    3. error...
  • I re-read your tutorial and figured out :idea: that I should have used the NEWER AppDelegate.cpp file from the Current Cocos2d-x (in the samples folder) version that i was using.

    So all is good now :P : just use the new AppDelegate.cpp/.h files from your current version of the Cocos2d-x that you are using.

    Adios. :D
  • Hi Ray,

    This was very helpfull link and it is working almost.However when i run the application, am getting an extra image loading in the application.


    BetCoin Fortune


    I dont know why that inline image is coming. Do you have an idea ?

  • Hi ,

    This is a very helping tutorial. I am very much happy.

  • Thank you so much for this tutorial.. I finally got to make the program work on my phone..

    although there is a bug with regards to the refresh of the collision function (update)..

    anyway..for all it thank you so much!!!

Other Items of Interest

Ray's Monthly Newsletter

Sign up to receive a monthly newsletter with my favorite dev links, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

Vote for Our Next Tutorial!

Every week, we alternate between Gaming and Non-Gaming tutorial votes. This week: Gaming!

    Loading ... Loading ...

Last week's winner: Apple TestFlight Tutorial.

Suggest a Tutorial - Past Results

Hang Out With Us!

Every month, we have a free live Tech Talk - come hang out with us!

Coming up in January: WatchKit.

Sign Up - January

Our Books

Our Team

Tutorial Team

  • Dani Arnaout

... 60 total!

Update Team

  • Ray Fix
  • Riccardo D'Antoni

... 12 total!

Editorial Team

... 17 total!

Code Team

  • Orta Therox

... 3 total!

Subject Matter Experts

  • Richard Casey

... 4 total!