Introduction
Wouldn't it be great if you could write a program and just have it run on Android, Windows Phone, Windows desktop, Mac, and IOS?
With Cocos2d-x (V3.2 at the time of writing) it is now possible to develop truly native cross-platform games in C++.
While the same code-base can be used across platforms, the development environment is necessarily different - usually Visual Studio on Windows for Windows Phone, XCode on Mac for i-Devices and Eclipse on almost anything for Android.
Setting up the development environment on a Mac to develop for IOS is pretty simple.
Setting up the development environment on a Mac to develop for Android isn't so simple, and is not well documented. Hence this article!
Background
One of the common problems in mobile App development is cross-platform development. Do you write the same thing in Objective-C, C++ (or C#) and Java? Do you stick to HTML and Javascript?
I chose to look at Cocos2d-X specifically because it allows me to write a single code-base, using C++, that will run on just about everything.
As I use a Mac at home, I first used Cocos2d-X on Xcode, compiling for IOS - and the whole process was simple (create project, open in XCode, build project, deploy project).
Setting up a development environment to build for Android, though, proved much, much harder. I mean harder to the point where I actually gave up for a while.
So when I eventually got it working, I saw it as my duty to fellow developers to document the process.
Using this article
I'm writing this as a step-by-step guide for people who, like me, are unfamiliar with Android development. There are a few tricks for new players, and gotchas to be avoided, which I've tried to point out.
Some of the information you will need to type in while following along will involve pathnames on your Mac. Because your user name is almost certainly not Maxxx, you won't be able to just copy the text from the artice. Instead, I recommend using Terminal's lovely feature whereby you can drag-and-drop a file or folder from a Finder window to a Terminal window, and it will insert the path for you.
Points of Interest
I swore a lot while getting my development environment up and running- mainly because the help and advice available tended to come from seasoned Android developers who would answer thousand-word questions with "just install the drivers and you'll be OK", without explaining which drivers, or whether to install them on my Android device or my Mac!
In fact, you don't need to install any drivers, anywhere!
Hopefully you won't be so confused - but if you are, just send a message & I will try to resist teh temptation to tell you to just install the drivers :)
History
Release 1.
Downloads
There are a few things you will need to download to set up your Mac for developing for Android.
The easiest thing to do is to download them all to a folder where you will be developing for Android. I am using a folder called AndroidDevelopment.
Excluding XCode, there is just short of 1Gb of downloads here, so you may want to start them off, then go grab a tea (Earl Grey. Black, since you asked) before continuing.
** YOU MUST NOT HAVE ANY SPACES IN ANY OF THE PATHNAMES USED **
Cocos2d-X 3.2
http://www.cocos2d-x.org/download
I'd recommend downloading the latest stable 3.x release (3.2 currently)
** Make sure you download cocos2d-x and NOT cocos2d-JS **
Eclipse ADT with the Android SDK for Mac
http://developer.android.com/sdk/index.html
ADT stands for Android Development Tools - so what we're getting here is a version of Eclipse (an open source generic IDE) configured for developing for Android.
Some folk don't like Eclipse. I can't say that I know it well enogh to comment, but in my case, my primary environment for Cocos2dx development is Max/IOS - so I only need to use Eclipse for platform-specific tweaks.
Android NDK
https://dl.google.com/android/ndk/android-ndk-r9d-darwin-x86_64.tar.bz2
NDK stands for Native Development Kit - i.e. Native code not Java.
The link here is directly to the zipped files (more accurately the tar-bz2'd files) rather than the page, because you need to download the r9d version.
** don't try to download the latest version (10.x) because it doesn't work with cocos2d-x **
If you're interested in the problems, they are documented at http://cocos2d-x.org/news/307 so may be fixed by the time you read this...
Apache ANT
http://ant.apache.org/bindownload.cgi
Apache Ant is "a Java library and command-line tool that help building software" so now you know.
I used 1.9.4 which was the latest version. There are instructions on the page how to verify your download - follow them if you will or just trust to luck like I did :)
XCode
http://itunes.apple.com/us/app/xcode/id497799835?ls=1&mt=12
XCode is a free download from the Apple App store, and if you are a developer with a Mac you surely have a copy. If not, you'll need it. I'm currently running XCode 5.1.1
Java
http://www.java.com/en/download/index.jsp
You'll need Java installed. I nearly forgot this as I've had it installed on my Mac forever - but if you don't just grab the latest version and follow the prompts...
Installing
XCode will install from the App store.
For the others, just open their containing folder in Finder and double-click each in turn. You will then have four folders (one from each zip file). it's safe now to move or delete the zip files to free up some disk space.
Now's the time to move them if you think you might want to - as later we'll be setting environment variables to point to these paths and changing their location will be somewhat more complex.
** Remember that the folder in which you have these extracted folders cannot have a space anywhere in its pathname **
Setting up cocos2d-x
Bring up a Terminal window and change to the cocos2d-x-3.2 directory. (remember, if you have a Finder window open you can just type 'CD
' then drag the cocos2d-x-3.2 folder to the Terminal window
The setup program for cocos2d-x is called, unsurprisingly, setup! It’s a python script, but we won’t hold that against it.
Type ./setup.py
The script will run and ask you to “Please enter the path of NDK_ROOT”
This is the pathname of the folder you extracted from the Zip file (android-ndk-r9d) – to make sure I get the paths right I always drag the folder from an open Finder window into the Terminal Window. When you drag a file name to the Terminal window, it helpfully adds a space to the end for you. If you do this ** Make sure you remove any trailing space from the path ** as this will cause an error.
If you do go wrong, you can safely kill the process (ctrl-d
) and start again with the setup.py.
Next it will ask you “Please enter the path of ANDROID_SDK_ROOT”. This SDK folder is found inside the ADT Bundle folder you extracted.
So you can drag the folder to your Terminal window.
** Make sure you remove any trailing space from the path **
Now you will be asked to “Please enter the path of ANT_ROOT”.
This is the apache-ant ‘bin’ folder
So again, drag the bin folder to the terminal window, remove any trailing space, and press Enter.
** Make sure you remove any trailing space from the path **
The last thing the setup tells you to do is ‘execute command: “source /Users/maxxx/.bash_profile” to make added system variables take effect.
If you’ve been reading the screen as the setup runs, you’ll see it is just setting some environment variables so it knows how to find stuff. It’s updated the bash_profile, which runs when you log in – so running it now saves logging off and on again!
Type in (or copy/paste) the command as shown in Terminal (e.g. source /Users/maxxx/.bash_profile). Unless your user name is maxxx, it will be different to mine.
Here’s my whole session, with the parts I entered in bold.
Maxxxs-iMac:~ maxxx$ cd /Users/maxxx/Documents/AndroidDevelopment/cocos2d-x-3.2
Maxxxs-iMac:cocos2d-x-3.2 maxxx$ ./setup.py
Setting up cocos2d-x...
->Check environment variable COCOS_CONSOLE_ROOT
->Search for environment variable COCOS_CONSOLE_ROOT...
->COCOS_CONSOLE_ROOT is found : /Users/maxxx/Desktop/Android
->Update variable COCOS_CONSOLE_ROOT in files ['.bash_profile', '.bash_login', '.profile']
->File /Users/maxxx/.bash_profile updated!
->Configuration for Android platform only, you can also skip and manually edit "/Users/maxxx/.bash_profile"
->Check environment variable NDK_ROOT
->Search for environment variable NDK_ROOT...
->NDK_ROOT not found
->Search for command ndk-build in system...
->Command ndk-build not found
->Please enter the path of NDK_ROOT (or press Enter to skip):/Users/maxxx/Documents/AndroidDevelopment/android-ndk-r9d
-> Add NDK_ROOT environment variable...
->Added NDK_ROOT=/Users/maxxx/Documents/AndroidDevelopment/android-ndk-r9d
->Check environment variable ANDROID_SDK_ROOT
->Search for environment variable ANDROID_SDK_ROOT...
->ANDROID_SDK_ROOT not found
->Search for command android in system...
->Command android not found
->Please enter the path of ANDROID_SDK_ROOT (or press Enter to skip):/Users/maxxx/Documents/AndroidDevelopment/adt-bundle-mac-x86_64-20140702/sdk
-> Add ANDROID_SDK_ROOT environment variable...
->Added ANDROID_SDK_ROOT=/Users/maxxx/Documents/AndroidDevelopment/adt-bundle-mac-x86_64-20140702/sdk
->Check environment variable ANT_ROOT
->Search for environment variable ANT_ROOT...
->ANT_ROOT not found
->Search for command ant in system...
->Command ant not found
->Please enter the path of ANT_ROOT (or press Enter to skip):/Users/maxxx/Documents/AndroidDevelopment/apache-ant-1.9.4/bin
-> Add ANT_ROOT environment variable...
->Added ANT_ROOT=/Users/maxxx/Documents/AndroidDevelopment/apache-ant-1.9.4/bin
A backup file "/Users/maxxx/.bash_profile.backup" is created for "/Users/maxxx/.bash_profile".
Please execute command: "source /Users/maxxx/.bash_profile" to make added system variables take effect
Maxxxs-iMac:cocos2d-x-3.2 maxxx$ source /Users/maxxx/.bash_profile
Maxxxs-iMac:cocos2d-x-3.2 maxxx$
Checking the setup
The setup.py checks for the environment variables, and only asks for them if it doesn’t find them. So re-running the setup shouldn’t prompt you to enter the paths again. If it does, just enter them again!
Creating a new Cocos2d-x project
Cocos2d-x has a command line option to create new projects. All projects are initially cross-platform when created (that is, it creates an empty project for Windows, IOS, Max, Android and then the shared files sit in their own folder, ready for you to play with.)
Let’s call the game ‘Bounce’, we’ll call the package we’re creating ‘com.codeproject.bounce’. The language will be ‘cpp’ (cocos2d-x supports javascript and lua as well) and we’ll put the source code in a folder within your AndroidDevelopment folder.
So your command line is:
cocos new Bounce -p com.codeproject.bounce -l cpp -d /Users/maxxx/Documents/AndroidDevelopment
in case it's not obvious, the -p parameter defines the package name, the -l parameter (that's a lower-case L) defines the language and -d defines the Directory in which to put the project.
It takes a few seconds to copy, then displays a bunch of stuff about changing project names – don’t worry about that for now.
Cocos2d-x project structure
It isn't necessary to know this for the purposes of this article, bit I tought it would be a good time to talk about how Cocos2d-x projects are structured.
In the Bounce folder are the following folders:
Classes
This folder is where all of the cross-platform code you develop for this project will reside
cocos2d
This folder contains the cocos2d-x library source files
proj.android
This folder contains the Project files for your Android project
proj.ios_mac
This folder contains the project files for both IOS and Mac projects
proj.linux
This will currently be more or less empty as cocos2d-x 4.x doesn't currently support Linux as a target
proj.win32
This folder contains the project files for the Windows project
proj.wp8-xaml
This folder contains the project files for the Windows Phone 8 project
Resouces
This folder contains generic resources for all projects
So, the idea is that you open your project in your development environment and just change the code in the Classes folder, and add resources to the Resources folder.
Then you open the specific project in a suitable development environment (probably Eclipse for Android, Visual studio for Windows and XCode for mac or IOS) and build the project.
Make a change to your code in Classes, and rebuild each project - and deploy to each device!
The really great thing for me about this is that I can use my favourite IDE for most of the development, then just change to the platform-specific one to build for that platform.
Building The Project
Having created the Bounce project,and set the various Environment variables, you now need to build it for the first time.
In terminal again, cd
to the proj.android
driectory inside the Bounce
directory
** Make sure you remove any trailing space from the path **
Here is the command to build the project for android.
Type ./build_native.py
This now compiles the project we’ve just created (and, in fact, the whole cocos2d library!)
This will take quite a long time the first time – but not quite long enough for a cup of tea.
Opening the Project in Eclipse
To find the Eclipse executable, look in the eclipse folder inside the adt-bundle folder that you extracted.
Run Eclipse and take the default workspace option.
You need to import the project into Eclipse:
Select File..Import
from the menu.
Expand the Android item in the tree, and select Existing Android Code into Workspace
Browse to the folder where you created your project (in my case, the 'Bounce' folder). Select this folder and click 'Open'.
The Import Projects window will show a list of projects to import. You only want to import the libcocos2dx and Bounce projects, for now, so de-select everything else and click 'Finish'.
Finishing Touches
You're nearly there!
We need to tell Eclipse where to find the NDK. Remember, cocos has set up an envoronment variable for it, but Eclipse doesn't know about that, you you need to tell it personally.
Find the path for NDK_ROOT by typing Echo $NDK_ROOT in Terminal
I get
/Users/maxxx/Documents/AndroidDevelopment/android-ndk-r9d
Copy this to the clipboard to save typing it.
In Eclipse, right-click the Bounce project in Package explorer, and select properties
Expand the C/C++ Build and select Environment
Click the Add button to add a new Environment Variable
Name the variable NDK_ROOT and paste the path from above in the Value
Click OK to close the dialog, then OK to close the properties.
Devices
We need to have a device to run on. Although there are emulators, it is far better to develop and test on a real device to get a realistic idea of performance; Virtual devices are great for experimenting with different screen sizes and different OS versions, though, so I'll talk you through setting up both a real and virtual device.
Setting up a device for testing
The process changed around version 4.2, so I've documented the different processes below.
Note that you may need to reboot your device for this to work (I did, others report they didn't need to) so I would play safe and reboot, if I were you.
Android 4.2+
Go to Settings on your device.
Scroll to the bottom and select About tablet (or About phone)
Scroll to the bottom, and click on Build number seven times. Yes, that’s right, 7 times (it will show you a message when you get there!) If you already have developer options, you'll see a different message, shown in the screenshot.
Click ‘back’ and you will see a new option in the Settings – {} Developer Options
Select this option, then select USB Debugging and any other settings you might like.
Android < 4.2
I don't have a suitable device to try this on, but am reliably informed that the following steps will turn on USB Debugging.
Go to Setting on your device.
Select Applications
Select Development
Select USB Debugging
Checking Your device
The reason for setting USB Debugging on your device is to make it visible to your Mac. Make sure your device is plugged into a USB attached to the Mac.
There are two ways to quickly check it's working...
1. If you have Google chrome installed on your Mac
Go to chrome://inspect/#devices
In the screen shot above you will see I have a Nexus 7 attached, and an emulator running
2. Go to Terminal
Type adb devices
This runs the adb executable that is in the sdk\platform-tools folder within the ADT folder you extracted earlier.
You should be able to run the command directly (without specifying it's path) because the cocos2d set up added to the path to your environment variables. If you get a 'command not found' error, you may have enter the whole path of the command file - just drag it into the Terminal window from Finder.
Maxxxs-iMac:~ maxxx$ adb devices
List of devices attached
emulator-5554 device
0a1c2fba device
Not quite as friendly as Chrome, perhaps, but it's just a quick check that all is working - hopefully you know which devices are attached to your Mac!
Setting up a Virtual device for testing
Whether you have a physical Android device or not, at some point you will want to create a virtual device to test your program on. (in fact, at one point, my Eclipse refused to detect my real device until I had created a virtual device!)
Here's how to create a Virtual Device.
In Eclipse, select Window...Android SDK Manager
in the SDK manager, you will see a list of all of the revisions of all of the tools - and a status column showing whether they are installed or not.
Choose which you want to test with, and select the SDK Platform and System Image as appropriate.
Unless you are on a really fast internet link with unlimited bandwidth, I'd select only one or two - as they need to be downloaded, and they are not small!
When you have selected the ones you want, click the Install x packages button.
Check all the Accept and Accept License radio buttons (seriously badly defined form IMHO, so just click around until you have a bunch of green ticks) and click Install.
The images can be fairly large- so time enough for a cup of tea.
Once you have them, go back to Eclipse and select Window ... Android Virtual Device Manager
Click on the Device Definitions tab
Select one of the pre-defined devices from the list, and click Create AVD...
This will pre-enter some of the fields in the 'Create new Android Virtual Device' form. Fill in the remaiing values (specifically, select a target and CPU from those you have downloaded, and ** Check the Use Host GPU checkbox **) and click OK
When you're done, click OK then, back at the AVF Manager, select your newly created Virtual Device, and click Start.
Starting the Virtual Device can take ages. Be patient!
Running Your Program
That took a lot of setting up, but you are ready to go!
In Eclipse, right-click on the project and select Run As ... Android Application
Assuming your project builds OK (and it should) you may see the Android Device Chooser.
This will list all of the devices, real or virtual, that Eclipse can see. The top grid shows the currently running devices, the bottom grid shows the virtual devices that are currently not running.
If you don't see this, it means there is only one device available so Eclipse will use it. If you want to use a virtual device while your physical device is attached, the easiest way is to start your virtual device (from the Android Virtual Device Manager accessed from Eclipse via Windows...Android Virtual Device Manager)
If you do see it, select whichever takes your fancy, click OK, and wait for the magic to happen!
And here it is! Not much of a game, but this is real, C++, cross platform gaming.
Cross-Platform
I started off this article talking abut cross-platform development - so let's finish up showing how you can run this same app on your iPhone.
On your Mac, go to the folder that you created your porject in (AndroidDevelopment/Bounce in my case) and browse to proj.ios_mac
There you will find Bounce.xcodeproj. Double-click to open in XCode.
You will see that, in the Classes folder, is the same source we looked at in Eclipse.
Build and run the project on your IOS device
or even as a Mac app ...
... and you will see the same App as you saw on your Android device.
(The cocos2d-x image you see isn't scaled for the individual device sizes - that's a skill in itself - hence the different apps do look somewhat dissimilar)
So now, even if you hate Eclipse, you can use XCode to write the cpp, and just use Eclipse to build and run the project for Android.
Caveats, Notes and other stuff.
While having the ability to run emulators is great, the default emulators are slow. And when I say 'slow' a don't mean jsut a little slow, not even make-a-cup-of-tea slow, I mean teribly, terribly slow.Honestly, the start up time can be minutes in some cases.
There are ways you can improve this - but the best one (using a snapshot) can't be used because we need to use the host GPU - and the two options are mutually exclusive.
If you are despairing at the speed, do take a google. But don't hold your breath!
If you want to take this further, and start developing games with Cocos2d-x, then there is a lot of help out there, but I warn you, having changed from cocos2d-iPhone (which is still active) through cocos2d-x 2.x (which is still active) to cocos2d-x 3.x (which is pretty new) it can be hard to find out how best to do things.
If you have questions about cocos2d-x I recommend looking at the forums on the cocos2d-x.org site.
To just have a play around, simply open up HelloWorldScene.cpp in the Classes folder in the application, and make some changes.