Saturday, February 4, 2012

More advanced concepts of getting cocos2dx working on Android from Windows 7


NOTE: This tutorial was done with cocos2d-1.0.1-x-0.9.1 and cocos2d-1.0.1-x-0.11.0, and so may not be 100% accurate for either version, or newer [Had to change version in the middle of development], but will serve as a general guideline for anyone using similar versions.

First Part: Quick and dirty guide to getting cocos2dx working on Android from Windows 7

Introduction

Working from the files we obtained in the first part, in this tutorial we shall cover:

  • Moving android-generated folder away from the cocos2d-x folder.
  • Add an extra library ( Chipmunk ).
  • Not having to use the Classes & Resources folders.

It’s important to use the proper editing tool for the files generated by the “create-android-project.bat”, because regular windows editors add extra symbols like “\r” that will confuse your Cygwin. I recommend Notepad++.  A great editor that has the invaluable property of showing hidden symbols by doing: View -> Show symbol -> Show all characters.

Moving The Folder

I generated a new project FOLLOWING THE STEPS IN THE PART ONE OF THE TUTORIAL, let’s call it FVZ, using the following specs:

  • Package: com.companyname.fvz
  • Name: FVZ_2_3
  • Target ID: 13 (Android 2.3.3)

And copied it from the cocos2d-x folder where it’s generated by default, to the folder where my Visual Studio solution held all my code of the project I was working on. To make this work, I had to modify:

  • android/build_native.sh
    • GAME_ROOT=/cygdrive/d/All/Proyects/FVZ/Android/FVZ_2_3
      ( Set the path to where we have copied the project folder, and add the /cygdrive/ in front so Cygwin can use the path ).
  • android/jni/Android.mk
    • Modify project path: addprefix $(LOCAL_PATH)/../../../../FvZv2/ to point to the root folder of the cocos2dx instaltion (where you have all the cocos2dx code, ej: cocos2dx, CocosDenshion, tests, tools…

      What this does is search for all the Android.mk (makefiles) of the libraries you are going to use. (Notice the addprefix & addsufix functions, to generate the full paths).

      # Try to use LOCALPATH, otherwise you’ll have to play a bit with the path till you get it to Cygwin’s liking.
  • android/jni/helloworld
    • LOCAL_SRC_FILES: Add RELATIVE path to each code file (cpp / h) in your Visual Studio project folder. The start of my list is, for example:
      • LOCAL_SRC_FILES := main.cpp \
        ../../../../../FvZv2/FvZ/Classes/AppDelegate.cpp \
        ../../../../../FvZv2/FvZ/Classes/AppDelegate.h \
        ../../../../../FvZv2/FvZ/Classes/HelloWorldScene.cpp …

    • LOCAL_C_INCLLUDES: Change Classes path to the folder where you keep all your code, and set the paths for the different cocos folders so they point to the required folders.
    • LOCAL_LDLIBS: Point the $(LOCAL_PATH)/../../libs/$(TARGET_ARCH_ABI)) to the proper location (TARGET_ARCH_ABI is usually armeabi).
  • andoid/build_native.sh
    • Change GAME_ROOT so it points to the root of your game folder, in my case:
      GAME_ROOT=/cygdrive/d/All/Proyects/FVZ/Android/FVZ_2_1

With all that your project should compile with no problems using Cygwin. As a special note, I made a java script to parse my Classes folder, to generate my LOCAL_SRC_FILES paths, as there where hundreds of files, in nested folders and so on. Sharing it here:

Code Snippet
  1. import java.io.File;
  2.  
  3.  
  4. public class ListFiles
  5. {
  6.     static String initialPath = "D:\\All\\Proyects\\FvZ\\FvZv2\\FvZ\\Classes";
  7.  
  8.     public static void main(String[] args)
  9.     {
  10.         FileTreePrint("");
  11.     }
  12.     
  13.     private static void FileTreePrint(String path)
  14.     {
  15.         String files;
  16.         File folder = new File(initialPath + path);
  17.         File[] listOfFiles = folder.listFiles();
  18.  
  19.         for (int i = 0; i < listOfFiles.length; i++)
  20.         {
  21.             if (listOfFiles[i].isFile())
  22.             {
  23.                 files = listOfFiles[i].getName();
  24.                 System.out.println("../../../../../FvZv2/FvZ/Classes"+ path.replace("\\", "/") + "/" +files+ " \\");
  25.             }
  26.         }
  27.         
  28.         for (int i = 0; i < listOfFiles.length; i++)
  29.         {
  30.             if (listOfFiles[i].isDirectory())
  31.             {
  32.                 FileTreePrint(path + "\\" +listOfFiles[i].getName());
  33.             }
  34.         }
  35.     }
  36. }

 

Adding Chipmunk to the Compilation

We need to modify some files, but it’s a straightforward process if we take another library (CocosDenshion) as a guideline.

  • android/jni/Android.mk
    • Add “chipmunk \” in the line under CocosDenshion/android.
  • android/jni/Application.mk
    • My APP_MODULES looks like:
      APP_MODULES := cocos2d cocosdenshion chipmunk game
  • android/jni/helloworld
    • LOCAL_C_INCLLUDES: Add the path to the chipmunk folder that holds all the files, in my case:
      $(LOCAL_PATH)/../../../../../FvZv2/chipmunk/include/chipmunk \
    • In LOCAL_LDLIBS add –lchipmunk

Lastly, there is one extra modification to be done, that took me quite a while. In the main java file of the .java files generated for your project (in my case FVZ_2_3.java) we need to search for where it does System.loadLibrary(), and add:

  • System.loadLibrary("chipmunk");

Automating the Process

The first thing you will notice with this system is that it’s SLOW. We have have to use the command line every time we want to compile, not to mention that this method copies all the resources of the game from the Resources folder to the assets one each time, which can be very time consuming.

So let’s optimize it a bit.

Making the resource load faster

Grab your build_native.sh and clean out all the logic for cleaning the resource folder, leaving it like this:

Code Snippet
  1. # set params
  2. ANDROID_NDK_ROOT=/cygdrive/c/eclipse/android/android-ndk-r6b
  3. GAME_ROOT=/cygdrive/d/All/Proyects/FVZ/Android/FVZ_2_1
  4. GAME_ANDROID_ROOT=$GAME_ROOT/android
  5.  
  6. # build
  7. $ANDROID_NDK_ROOT/ndk-build -C $GAME_ANDROID_ROOT $*

What is going to happen now is that you’re going to have to remember to manually copy each modified asset from your MVS project to the assets folder of the java project. A small price to pay for compiling in 10 seconds instead of 1 minute.

So go ahead and copy all your resources to the assets folder. Once you’re done…

One Click Process

I created a batch file to be called with a simple double click, that calls cygwin and gets the whole compilation process done. After double clicking on it you just need to refresh the java project in eclipse (F5) and hit “run” to have the game showing in your android. Here is the magical .bat:

Code Snippet
  1. C:\cygwin\bin\bash.exe -l '/cygdrive/d/All/Proyects/FvZ/Android/FVZ_2_1/android/build_native.sh'
  2. pause

Created this Compile.bat thanks to http://forums.techguy.org/windows-xp/424616-calling-unix-scripts-dos-script.html and http://old.nabble.com/Cygwin---batch-file-td15088393.html .

Conclusion

Now you should be able to put your folder wherever you damn well please, add other libraries to it and compile by:

  • Compiling in MVS by hitting F5 (to check it works)
  • Compiling in native code by double clicking Compile.bat
  • Running the game in android by hitting F5 in eclipse, and then “run”.

Tell me if it worked for you!

No comments:

Post a Comment