Friday, March 7, 2014

Cocos2D-X Tutorial for iOS and Android: Getting Started

Cocos2D is an amazing and easy to use framework, but since it’s written in Objective-C you can only write games with it for iOS and the Mac.
Wouldn’t it be great if you could use the same easy to use Cocos2D API, but have it run on Android as well? This way you could greatly extend the market for your app, without adding a lot of extra work!
Well, this is possible with the Cocos2D-X game framework! Cocos2D-X is a C++ port of the Cocos2D API, so you can use the API you know and love. And since it’s in C++, it works on many platforms – from iOS to Android to Windows to Linux and more!
In this Cocos2D-X tutorial, you’ll learn how to use Cocos2D-X and C++ to produce a cross-platform “Hello World” app that will run under both iOS and Android.
And in a few days, I’ll post a follow-up Cocos2D-X tutorial that will show you a practical game example – a cross platform space shooter!
So grab your iPhone and/or Android device, and let’s get started! 

Hello, Cocos2D-X for iOS!

Before you go any further, make sure you download the latest version of Cocos2D-X.
Unzip the file in to a folder somewhere on your hard drive. Note the full path to that folder – it will be referred as $COCOS2DX_HOME.
Now that you’ve got the code, let’s install the templates! You can do this with a script that’s inside$COCOS2DX_HOME. To run it, just quit Xcode, open a shell terminal and type:
cd $COCOS2DX_HOME
./install-templates-xcode.sh -f -u
Note: In the above, for the first line, you need to replace $COCOS2DX_HOME with the actual path to where you extracted the files. Simply typing in $COCOS2DX_HOME as part of the command will do nothing.
The installation will simply proceed without any further intervention from you. Once the templates are installed, run Xcode and create a New Project. You should see a new Cocos2d-x temples section in the project template dialog. Don’t worry, the Cocos2d-X templates don’t conflict with the classic Cocos2D templates, so you can continue to create new projects using Cocos2D, when needed.
Let’s try the new templates out! Open up Xcode (4.6 if using the last version) and create a new project, selecting the iOS\cocos2d-x\cocos2dx template:


Click Next, name the project Cocos2DxFirstIosSample, choose iPhone for Device Family, click Next and then click Create.
Now press the Run button to see the Cocos2d-x Hello World app running:

Pretty easy, eh? While you’re at it, take a look at the project files in Xcode – particularlyClasses\HelloWorldScene.h and Classes\HelloWorldScene.cpp. If you’re familiar with Cocos2D, this should look familiar to you – the same Cocos2D API, but in C++!

Setting up Eclipse for Cocos2D-X Development

You’re now done with the Xcode setup part and you need to have a look at the Android Cocos2D-X configuration with Eclipse.
This Cocos2D-X tutorial assumes that you have a fully-functional Android Eclipse standard development environment. 
But wait… A standard Eclipse Android environment is dedicated to Java development only, and Cocos2D-X is based on C++!
Don’t worry, Eclipse has been around for 10 years, so there are tons of plugins out there to extend its core functionality beyond just Java development.
This includes some plugins for C/C++ development! Let’s install them now. Open up Eclipse and perform the following steps:
  • From the Eclipse IDE main toolbar, go to Help/Install New Software
  • Open the Work with combo box and select the item containing your Eclipse version name (Juno if using the last version of Eclipse).
  • Find Programming Languages in the plugin tree (you’ll only see the plugin tree if you checked theGroup items by category checkbox – otherwise, you might have to search the list a bit …) and checkC/C++ Development Tools.
  • Click Next and walk through the rest of the wizard, and wait for the components to download and install. At the end of the install process Eclipse will ask you to restart, click Yes.
  • To ensure that the installation was successful, from the Eclipse IDE main toolbar, go to Help/Install New Software
  • Select the already installed link and check the installation of the following components.
You will now be able to develop C/C++ projects using Eclipse!

Setup the Android NDK (Native Development Toolkit)

Initially, Android development was done exclusively in Java, and most of the Android apps on the market today are Java-based.
However, these days you can write Android apps in C/C++ with the Native Development Toolkit (NDK)! This was introduced by Google in June 2009 as a way to allow components written in C/C++ to be accessed via the standard Java Native Interface (JNI).
Installing the NDK is straightforward:
  • Download the latest version of the NDK here (choose the MacOSX platform).
  • Unzip the tar.bz2 file to the location of your choice. This location will be referred from now on as$NDKROOT.
The NDK brings to the Android environment a C/C++ compilation toolchain, able to cleanly compile/link (using the GCC 4.7 compiler) and build a ready-to-install APK-signed package.
Having this compilation toolchain in place allows you to integrate external C/C++ libraries (like Cocos2d-x) into Eclipse. These libraries, compiled as external dynamic libraries bound inside an APK, communicate with the “legacy Java Android architecture” though the JNI (Java Native Interface).
The compilation toolchain can be used in two ways :
  • Standalone mode: uses the arm-linux-androideabi-g++ directly in your custom make file. This will increase your project complexity/maintainability. I recommend you avoid this mode unless you have no alternative.
  • Integrated mode: uses the $NDKROOT/ndk-build shell tool, which is a highly-customized make file dedicated to NDK library builds. This is the preferred way to go and the mode you will use in this Cocos2D-X tutorial.
Explaining the JNI and NDK would take too long, and is out of the scope of this Cocos2D-X tutorial. There is a lot of documentation about JNI available on the web. The only book seriously covering this topic is available for free here.
If you need more information about the NDK, there is a very good book available that covers NDK C/C++ development: Android Native Development Kit Beginner’s Guide by Sylvain Ratabouil. This book covers NDK programming in depth and should rather be called “From Beginner to Expert.”
The NDK itself also comes with very detailed documentation, located under $NDKROOT/docs.

Hello, Cocos2D-X for Android!

Now let’s do a “Hello, World” Cocos2D-X tutorial for the Android platform, just as you did for iOS.
You will need to do this via the command line, however, since there are no Cocos2D-X project templates available via the Eclipse IDE at the moment. (You know what? This would be a great open source project candidate, if you are so inclined :])
The $COCOS2DX_HOME directory contains a shell script named create-android-project.sh that you will use to generate the android project.
But, before launching this shell script for the first time, you need to make a tiny customization at the top of the above file:
# set environment paramters
NDK_ROOT_LOCAL="/home/laschweinski/android/android-ndk-r8d"
ANDROID_SDK_ROOT_LOCAL="/home/laschweinski/android/android-sdk-linux_86"
Modify these above lines so that the NDK_ROOT_LOCAL variable points to the directory where you installed the Android NDK ($NDKROOT) and ANDROID_SDK_ROOT_LOCAL points to the place where you installed the Android SDK.
Now run the create-android-project.sh script from the command line and you will get several prompts as to various input values. These prompts will ask you to provide the below information:
  1. The first prompt will ask you for the “Input package path”. This is the package name that will be used for java code production. You can use reversed domain notation here (similar to an iOS bundle ID) – something like com.yourdomain.samplecocos2dxandroid (remember to replace com.yourdomain with the reverse domain notation for your actual domain)
  2. Next, you will get a list of available Android APIs and their ids. Depending on what’s installed on your machine, the list will vary. But the prompt at this stage simply asks for the Android API level your app will support and you can use the id for the last item on the list that’s a Google API.
  3. Finally, you have to provide the project name. Call it samplecocos2dxandroid.
The command-line output from the above process will look something like the following:
bash-$ ./create-android-project.sh
Input package path. For example: org.cocos2dx.example
org.jymc.samplecocos2dxandroid
. . . 
Available Android targets:
----------
. . .
----------
id: 25 or "Google Inc.:Google APIs:17"
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Revision: 2
     Description: Android + Google APIs
     Based on Android 4.2.2 (API level 17)
. . .
input target id:
25
input your project name:
samplecocos2dxandroid
Created project directory: 
/Users/jymen/development/cocos2dx/samplecocos2dxandroid/proj.android
. . .
Added file /Users/jymen/development/cocos2dx/samplecocos2dxandroid/AndroidManifest.xml
Added file /Users/jymen/development/cocos2dx/samplecocos2dxandroid/build.xml
Added file /Users/jymen/development/cocos2dx/samplecocos2dxandroid/proguard.cfg
bash-$ 
Pay attention to the Created project directory: line towards the end of the script output. That’s where your Android project has been created by the script. The project location (/Users/jymen/development/cocos2dx/samplecocos2dxandroid in the above example) will be referred as $PROJECT_HOME from now on.
Note: Do not try to move the project from that location to a different location. At least one of the scripts you’ll work with in the next section will not work if you do.

Building the Project

There are two steps to building the project – compiling the C++ code with a command line script, and compiling the Java code with Eclipse.
But, before compiling, you need to define NDK_ROOT parameter so it points to your $NDKROOTdirectory. Open the $PROJECT_HOME/proj.android/build_native.sh shell script and add the following line at the top of the file:
# paths
NDK_ROOT="/home/laschweinski/android/android-ndk-r8d" 
Modify the above line so that the NDK_ROOT variable points to the directory where you installed the Android NDK ($NDKROOT).
To compile the C++ code, switch to the $PROJECT_HOME/proj.android folder via the command-line and issue the following command:
./build_native.sh 
Note: If at this point you are getting the message “please define NDK_ROOT” you must ensure that you specified correctly the root to your Android NDK directory in the above step.
You should see some output similar to the following in response to the above command:
Gdbserver      : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
Gdbsetup       : libs/armeabi/gdb.setup
Compile++ thumb  : cocos2d <= CCConfiguration.cpp
Compile++ thumb  : cocos2d <= CCDrawingPrimitives.cpp
:
:
:
Compile++ thumb  : cocos2d <= CCTileMapAtlas.cpp
Compile++ thumb  : cocos2d <= CCTouchDispatcher.cpp
Compile++ thumb  : cocos2d <= CCTouchHandler.cpp
Prebuilt       : libstlport_static.a <= /sources/cxx-stl/stlport/libs/armeabi/
SharedLibrary  : libcocos2d.so
Install        : libcocos2d.so => libs/armeabi/libcocos2d.so
Compile++ thumb  : cocosdenshion <= SimpleAudioEngine.cpp
Compile++ thumb  : cocosdenshion <= SimpleAudioEngineJni.cpp
SharedLibrary  : libcocosdenshion.so
Install        : libcocosdenshion.so => libs/armeabi/libcocosdenshion.so
Compile++ thumb  : game_logic <= AppDelegate.cpp
Compile++ thumb  : game_logic <= HelloWorldScene.cpp
SharedLibrary  : libgame_logic.so
Install        : libgame_logic.so => libs/armeabi/libgame_logic.so
Compile++ thumb  : game <= main.cpp
SharedLibrary  : libgame.so
Install        : libgame.so => libs/armeabi/libgame.so
This builds the C++ Cocos2D-X libraries, and the C++ code for your project.
To build the Java code, you’ll create an Eclipse project – that’s way easier than working via the command-line :]
Start Eclipse and go to File\New\Other. Choose Android\Android Project from Existing Code, and clickNext. Click Browse and select the $PROJECT_HOME/proj.android folder, as shown below.

Click Finish, and you now have a project!

At this point the project might have some errors but don’t be affraid, they are pretty easy to fix:
One of the errors rises because Eclipse can’t find the resource “@drawable/icon” so, expand the project tree on the left, open AndroidManifest.xml and change to the AndroidManifest.xml view so you can see the plain text. Look for the following line of code:
 android:label="@string/app_name"
android:icon="@drawable/icon">
and change it by the correct icon name:
 android:label="@string/app_name" 
android:icon="@drawable/ic_launcher">
And, before you close AndroidManifest.xml, modify android:minSdkVersion to be:
 android:minSdkVersion="14"/>
and Save the file.
The second error rises because Eclipse can’t find some Cocos2D-X Java classes. Select Project\Propertiesfrom the main menu and choose Java Build Path from the list on the left. In the Source tab click on Link Source and Browse to the following directory
$COCOS2DX_HOME/cocos2dx/platform/android/java/src/
where $COCOS2DX_HOME is the directory where you installed the Cocos2D-X resources. In Folder namewrite cocos2dx-src, click Finish and OK.


You can now run it. Right click the project in the tree on the left and select Run As\Android Application. The AVD (Android Virtual Device) will launch showing the Hello, Cocos2D-X project (maybe, if it doesn’t work keep reading below):


If the application does not launch on the emulator and LogCat Eclipse view shows the errorjava.lang.IllegalArgumentException: No config chosen, it’s due to an issue with OpenGL ES 2.0 in latest AVD Target versions. To solve it you must take two steps:
1) Go to the Android Virtual Device Manager, select the AVD you are using and click Edit. Then make sure the Use Host GPU checkbox is checked, as shown below:

2) Now open samplecocos2dxandroid/cocos2dx-src/org.cocos2dx.lib/Cocos2dxActivity.java, look forinit() method and add:
this.mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
before:
this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());
Now try running it again – and hopefully it should work this time.
Congrats, you now have a “Hello, World” project running on both iOS and Android!

Defining a Combined Java/C++ Project in Eclipse

Compiling the C++ code with a command line script and compiling the Java code with Eclipse is cumbersome. It would be a lot easier if you could just build everything using Eclipse.
Luckily, you can do this by telling Eclipse that your Android project is a combined Java/C++ cross language project!
To do this, select the samplecocos2dxandroid project in the left tree, and select File\New\Other from the menu and then, C/C++\Convert to a C/C++ Project from the dialog, as shown below:

Click Next. In the next screen, check the box for your project, select the C++ Project option, and specify the Makefile project\Other Toolchain option for Project type:

Click Finish. Eclipse may ask you if you want to open the C/C++ perspective, just click No if this occurs.
The next step is to change the project settings to specify how to run your make command. In the left tree, right click the samplecocos2dxandroid project, select Properties, and select the C/C++ Build section.

Uncheck the Use default build command checkbox, and in the build command textbox type in:
bash ${workspace_loc:/samplecocos2dxandroid}/build_native.sh NDK_DEBUG=1 V=1
Click Apply, and click OK.
Select Project\Build All from the main menu, and you’ll see the C++ make run in the Eclipse console:
make-displayed-in-eclipse
There are still some warnings to resolve. To see what I mean, open up jni/hellocpp/main.cpp, and you’ll see a bunch of warnings:
Cocos2D-X include files not resolved
These are occurring because you do not have the correct C++ include path specified yet. To do this, in the left tree, right click the samplecocos2dxandroid project and select Properties\C/C++ General\Paths and Symbols\Includes\GNU C++.
Use the Add button to select the two directories shown below, then click Apply and OK.
$(NDKROOT)/platforms/android-14/arch-arm/usr/include
$(COCOS2DX_HOME)/cocos2dx/include
Note: Don’t forget to replace $(NDKROOT) and $(COCOS2DX_HOME) with the actual paths where you installed these on your machine.
Updating paths and symbols for Cocos2D-X
Click Apply and you might be prompted to re-build the indexes. Go ahead and say Yes and then click OKto close the dialog.
Now, if you look at main.cpp, you’ll see most of the include warnings have disappeared:
Most warnings resolved for Cocos2D-X
However, the AppDelegate.h file still can’t be found. This is because the AppDelegate.h file is located in the $PROJECT_HOME\Classes folder. This folder is very important for you since it contains the portable C++ classes for your project, such as HelloWorldScene.cpp, which will be the starting point for your project.
When you created your Eclipse project, you had to select the $PROJECT_HOME\proj.android folder as the root folder since Eclipse requires AndroidManifest.xml to be inside the specified folder. But this means your project does not contain the critical Classes folder, and this is why you’re still getting that warning.
Let’s fix it now. In the left tree, right click the samplecocos2dxandroid project, and selectProperties\C/C++ General\Paths and Symbols\Source Location. Click Link Folder, check the Link to a folder in the file system checkbox, and browse to the Classes directory inside the $PROJECT_HOMEfolder. Click OK, then Apply and OK.
fixing-paths-final
You should now be able to see the Classes directory in your file tree, and the #include “AppDelegate.h”warning in main.cpp should have gone away.
Eclipse will still have some warnings in the project, but this is just because Eclipse is not that great at parsing C++ header files for the code analyzer stage. To disable this, bring up the project properties (right-click the project and select Properties from the context menu) and turn off the warnings in theCode Analysis section, as you can see in the screenshot below:
Turn of C++ Code Analysis and Warnings in Eclipse
Click Apply and then OK and finally – a project you can edit and build with Eclipse! :]

What About the Java Code?

If you look over the project content in Eclipse, you will notice some Java code in the src and gen folders and might wonder what that’s all about.
The main language for Android development is Java. The project template has created some Java scaffolding code for you that loads the C++ code that does all the heavy lifting in your app.
You won’t usually have to modify the Java code, but let’s look at the main class –src\com\xxx\samplecosos2dxandroid\samplecocos2dandroid.java – in more detail to see what it does.
This class contains the main Android Activity class that takes control when the app launches. It will first load the requested C++ dynamic library generated by the NDK:
show-load-library
Since this class derives from Cocos2dxActivity, behind the scenes, Cocos2D-X will give control to the C++ AppDelegate initInstance method, and finally the applicationDidFinishLAunching method.
So to repeat, the Java code just contains wrapper code that you will rarely need to change, since all the game’s logic will be inside the C++ code.

Combining the iOS and Android Project Structures

Right now you have two Cocos2D-X projects – one for iOS and one for Android. Your goal is to have them share the same directories so that you can use the same C++ files (with all your portable game logic) in both projects.
In both of your projects, you have a folder called Classes that contains this portable game code (Android on the left, iOS on the right):
If you look closely at the Classes directory in Eclipse and Xcode, you will see that the C++ files are completely identical! So all you need to do is point both projects to use the same folder, and you are set!
To do this, open up your Cocos2DxFirstIosSample project in Xcode. Select the Classes group, clickDelete, and select Move to Trash when the popup appears.
Next, right click the project in the Project Navigator, select New Group, and rename the new group toClasses. Right click the Classes group, and select Add Files. Select the following files from your$PROJECT_HOME\Classes folder and make sure that the Copy items into destination group’s foldercheckbox is not checked before you click Add:
Xcode-file-selection
Do a Clean and Build of the Xcode project to check that everything is OK.
Congrats – everything is in place and your Xcode/Eclipse combined iOS/Android projects are ready to use!

When to Use Xcode, and When to Use Eclipse?

Now that you have two project files it might not be immediately obvious which you should use when.
The usual development strategy for Cocos2D-X is to develop and test on iOS (via Xcode) first, and after you’ve got that working, make sure it works on Android (via Eclipse) second. Just keep the following rules in mind:
  1. Test often. Develop short pieces of code and test that they work on Android. This way you don’t get too far before finding any problems.
  2. Test on multiple devices: There are a large number of Android devices available, often with subtle differences, so it’s best to test on as many devices as you can lay your hands on.
It’s also possible to have a reversed strategy (develop for Android with Eclipse first), but I find this approach less productive, since Xcode feels faster and easier to use for me than Eclipse. Plus, the Android emulator usually takes a long time to start up and so takes longer when it comes to debugging things whereas the iOS simulator comes up pretty fast each time you start it.

Debugging Tips and Tricks

Debugging the iOS part of the Cocos2d-x project is exactly the same as debugging standard Cocos2D code, so there is nothing special to add here.
However, for Android, here’s some notes.
When building for debug with NDK, a ‘server side’ gdb and gdbcontext is bundled inside the APK generated by the ndk-build shell and populated to the device. This remote debugger will communicate with any compatible GDB client agent.
The best GDB agent to use with Eclipse is the NVidia debug manager plugin, but installing that is beyond the scope of this Cocos2D-X tutorial.
Note:
If you want to install the NVidia Debug Manager plugin, all you really need to do is to go to this pageand download the full Tegra Android Developer Pack even though you might think you don’t need it. When you install the Tegra Developer pack, it gives you the option to select what you want to install and at this point, you can opt to install just the plugin.
However, that will not install the plugin into Eclipse. It will simply put the plugin ZIP file on your hard drive. Now follow the instructions on this PDF to actually install the plugin.
I found that on some physical devices (Samsumg Galaxy S being one of them), the remote debugger always fails to start though it correctly starts with the same APK on an AVD (Android Virtual Device).
To start a debug session select your project, right click and select Debug As/Android NDK Application, as you can see below:
Do note though that you get the Android NDK Application option only if you download and install the NVidia debug manager plugin. Otherwise, you will not see the above option when you right-click.
You can set a breakpoint by double clicking a code line, as you can see here:
When the breakpoint hits, it will halt at that line of code with more information:
Sadly, debugging from Android using GDB may not always work, so you might find it helpful to add an extra debug tracing system in place as an alternative debugging method. For more info on this, contact me and I’ll share some tips on how you might do this.

For More details :