Porting a Cocos2d-x iOS game to Android

I admit, making an iOS and Android version of a game in parallel is usually a preferred option, but I wanted something out fast, cocos2d-x was new to me and I didn’t want to stuff around with Android.

Gosh I despise working on Android, at least at the moment. Sure, provisioning profiles, certificates and a $140 NZ iOS licensing fee is a bit of a nuisance, but that is trivial next to the cluster-f*** which is Android development. Android Studio, based off IntelliJ was released in pre-release just recently, but I see there is no built in C++ support, just Java.

XCode and the Cocos2d-x project templates makes getting Cocos2d-x set up and running for iOS a breeze next to Android and why the powers that be don’t act upon the fact that Apple is making stupid amounts of money on paid apps (yes, emphasis) through their app store because of a robust application development and delivery eco system, is totally beyond me. Maybe Android Studio is a step in that direction, but it seems 2 years late. Good thing we have short memories, so once it’s finally ready for prime time, maybe all us devs will forget that Android as of June 2013 was a pain in the ass.

To make the Android project I followed the tutorial from Ray Wenderlich, which required the use of the create-android-project.sh script.

Here is the list of gotchas I had to deal with when porting this “cross platform” game to Android.

No STL Libraries

Why this just doesn’t work is beyond me.

Error:
‘int64_t’ has not been declared
(or anything else std related)

Solution:
Add
APP_STL := stlport_static
to the Application.mk file. It may already have
APP_STL := gnustl_static.
Don’t use that, it doesn’t work.

Using boost shared_ptr

Boost is an incredibly useful C++ toolkit that all devs should be aware of. Will it work with Android ‘out of the box’. Of course not, we’re coding for Android!

Error:
…/boost/smart_ptr/detail/shared_count.hpp:106: error: undefined reference to ‘boost::throw_exception(std::exception const&)’

Solution:
Go to the Application.mk file for your project and add
APP_CPPFLAGS := -frtti -fexceptions
APP_CFLAGS += -DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB

Source: Stackoverflow

OpenGL ES header issues

I have some custom drawing code for debugging purposes (rendering box2d shapes, I think).

Error:
fatal error: OpenGLES/ES1/gl.h: No such file or directory
compilation terminated.

Solution:
#ifdef TARGET_OS_IPHONE
#include <OpenGLES/ES1/gl.h>
#include <OpenGLES/ES1/glext.h>
#else
#include <EGL/egl.h>
#endif

Cocos2d-x bugs

In version cocos2d-2.0-x-2.0.4, which is what I’m using, there seems to be some missing code.

I get this when trying to use CC_ASSERT
Error:
error: ‘CCMessageBox’ was not declared in this scope

Solution:
Go into platformandroidCCPlatformDefine.h and change line 11 so that
CCMessageBox(content, "Assert error") becomes cocos2d::CCMessageBox(content, "Assert error")

Source: Cocos2d-x forums

TTF Font Loading is different

Problem:
It turns out that when using cocos2d-x functions that require a font, e.g. CCLabelTTF, that iOS uses the name of the font whereas Android requires the file path of the font.

Solution:
I used some constants and platform specific defines
#ifdef TARGET_OS_IPHONE
const char* FONT_AWESOME_TTF = "FontAwesome";
#else
const char* FONT_AWESOME_TTF = "fontawesome-webfont.ttf";
#endif

Source: A blog post by Jordy

The emulator crashes on startup

If the emulator was running on a secondary monitor, then there’s a chance that trying to restart it on the secondary monitor will result in a crash before it can fully start.

Error:
emulator64-arm quit unexpectedly

Solution:
Open ~/.android/avd/[The name of your virtual device].avd/emulator-user.ini

and set window.x to zero, i.e. window.x=0

Source: A blog post from ‘an IT dad’

Game Center Replacement

I ended up just caching score to a text file for the initial release. Cocos2d-x has a method for telling you where abouts on the Android device data can be cached. From there, simple C File IO calls can be made.

std::string path = CCFileUtils::sharedFileUtils()->getWriteablePath();
FILE* f = fopen(path.c_str(), "r");
...
...
fclose(f);

Logging

printf is not going to work in Eclipse. Instead Cocos2d-x has a CCLOG call that will print output to LogCat.

Solution:
Add #define COCOS2D_DEBUG 1
To the top of any source file, but just before the #include “cocos2d.h”

CCLOG(“Print somethingn”);

Analytics

I use Localytics as my analytical tool. The instructions are quite straight forward so I won’t repeat that here. The Cocos2d-x specifics however are:

  • The .java Activity file that you will want to edit is the ${COCOS2DX_HOME}/cocos2dx/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java file. If you’ve followed this tutorial then it’s located in the Eclipse project tree under cocos2dx-src > org.cocos2dx.lib
  • In the same way that the cocos2dx source was linked to the Eclipse project, copy the Localytics com folder (and its contents) somewhere and link to it in Eclipse using Project Properties > Java Build Path > Source Tab > Link Source. It’s going to look like com.localytics.android in the project tree.

Final thoughts…

That’s enough drama for one post. The main drama was actually messing with file paths because the create-android-project.sh script inside the cocos2d-x download package created a structure that was inconsistent to the XCode templates I’d used for my iOS version.

This ultimately meant

  • a copy past of asset files
  • The C++ source files from my iOS version (in its own separate .git repo) being linked across to the Eclipse/Android project.

Once I figure out what paths the create-android-project.sh has hardcoded into the Eclipse project, I’ll try and consolidate all the files.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s