Integrating Level Helper to hybrid project iOS+Android using Cocos2d-x

The wonder of Cocos2dx is: it's written in C++. And because it's written in C++, it can run on any system that supports C++. That means all systems, except Windows phone (as of this writing).

To integrate Level Helper to hybrid iOS Android Cocos2d-x project (common C++ codes for both iOS and Android), first create hybrid project as is explained in this post: http://growingshoot.blogspot.com/2013/04/cocos2dx-hybrid-project-ios-and-android.html

>> The trick to integrate Level Helper <<

Most Android does not support pvr.ccz, while most (or all?) iPhones support it. I want pvr.ccz for iPhone project, and plain PNG for Android project. pvr.ccz for iPhone project is even more compelling because most of the time, the PNG generated by SpriteHelper causes pngcrush caught libpng error  on compile time, while the same PNG file does not cause trouble for Android.

To achieve that,  I create the Sprite Helper project, and save the pvr.ccz version inside {PROJECT_NAME}/Resources directory and save the PNG version inside {PROJECT_NAME}/android/assets directory. Then, I create the Level Helper project inside {PROJECT_NAME}/Resources directory.

The {PROJECT_NAME}/android/build_native.sh needs modification so it does not delete the assets directory and replace it with contents of Resources directory. It also must copy only PNG and plhs (project file of Level Helper) from inside Resources directory into the assets directory. When copying plhs file, it must replace all occurences of pvr.ccz strings with png strings.

Following screenshots, respectively: saving Sprite Sheet for iPhone project (pvr.ccz, cocos2d-x resource handling, hd suffix set, 2x hd suffix empty), saving Sprite Sheet for Android project (png, cocos2d-x resource handling, hd suffix empty, 2x hd suffix empty), new build_native.sh file, old build_native.sh file.





New build_native.sh below and old build_native.sh above:



2. Do not forget to set content scale factor to 2 in App Delegate!     pDirector->setContentScaleFactor(2); You must also tell iPhone to look inside hd directory for files when in Retina mode: CCFileUtils::sharedFileUtils()->setResourceDirectory("hd"); This must be done before loading level. Can not be done in App Delegate!

3. C++ codes generated by Level Helper must be referenced in the {Project name}/android/jni/Android.mk file (LOCAL_SRC_FILES for the cpp files and LOCAL_C_INCLUDES for the headers). The following are my Android.mk file and my project structure (I put LevelHelper dir, which is codes generated by LevelHelper, under Classes dir).



Cocos2dx hybrid project iOS and Android

So I'm porting a game from iOS to Android. It's a Cocos2d game. Naturally I look to implementing the Android port using Cocos2dX, since it's a C++ port of Cocos2d.
I found many tutorials online of how to create a shared project for Android and iOS. By "shared", I mean the C++ code. The C++ code is common to iOS and Android. With some Objective-C code binding for the iOS project and some Java code for the Android project.
But the Objective-C and Java codes are small and do not change.
The ones that change is the C++ codes, shared by iOS and Android project.
Among all tutorials online, I find this one most concise and easy to follow: http://www.bold-it.com/ios/cocos2d-x-box2d-iosandroid-hybrid-tutorial/

It's just that the tutorial is written for Cocos2d-2.0-x-2.0.2. The most current version as of this writing is Cocos2d-2.0-x-2.0.4.
Only minor version change but I had to make some extra adjustment to compile and run both project successfully.

So, follow the steps in the above tutorial:
1. Download Cocos2dx.
2. Install the XCode template: ./install-templates-xcode.sh
3. Create XCode project for iOS.
4. Edit the create-android-project.sh file before creating the Android project. Set the NDK_ROOT_LOCAL and ANDROID_SDK_ROOT_LOCAL variables.
5. Execute create-android-project.sh --box2d to create Android box2D project.
6. Make sure it compiles by executing ./build_native.sh
7. Move the necessary Android files:

  • Move the /testgame/proj.android folder to the iphone project folder, next to ios. Rename it android.
  • Copy the /external/Box2D folder into /libs/, replace what is there.
  • Copy the /cocos2dx folder into /libs/, replace what is there.
  • Copy the /CocosDenshion/android folder into /libs/CocosDenshion/
  • Copy the /extensions folder to /libs/, replace what is there.
8. In /android/build_native.sh, change line 40: COCOS2DX_ROOT="$DIR/../libs"
9. Next, in android/jni/Android.mk, add a LOCAL_C_INCLUDES path to Box2D and change “$(call import-module,external/Box2D)” to “$(call import-module,Box2D)”. To be able to see logs in Logcat, add LOCAL_CFLAGS += -DCOCOS2D_DEBUG=1. Delete this line or set the value to 0 for production to improve efficiency.
This is how my Android.mk looks like:

After the log is enabled, you can see the log output from console by typing: adb logcat | grep D/cocos2d-x. Don't forget to use CCLOG to print debugging messages.
10. Update android.library.reference.1 in android/project.properties:

# Project target.
target=android-10
android.library.reference.1=../libs/cocos2dx/platform/android/java
11. Define sdk.dir in libs/cocos2dx/platform/android/java/ant.properties as such:
sdk.dir=/Users/firman/Documents/android-sdk-macosx
12. Edit the target in libs/cocos2dx/platform/android/java/project.properties to match the target defined in android/project.properties:
target=android-10

Done! Now you can run the iOS project from inside XCode. As for the Android project:


./build_native.sh clean
./build_native.sh
ant debug
adb install -r bin/testgame-debug.apk
adb shell am start -a android.intent.action.MAIN -n com.boldit.testgame/.testgame