cocos2d-x 从win32到android移植的全套解决方案

引言:咱们使用cocos2d-x引擎制做了一款飞行射击游戏,其中创新性地融入了手势识别功能。可是咱们在移植过程当中遇到了不少的问题,同时也发现网上的资料少而不全。因此在项目行将结束的时候,咱们特意写了这篇文章来完整记录咱们整个移植的过程,记念咱们项目的成功完成,更以此来表达对帮助过咱们的人的感谢。移植过程当中咱们在网上获得了不少帮助,更要感谢黄杨学长在最后时刻帮助咱们突破难关!html

0、开发平台java


系统:win8 profession 64bitlinux

IDE:vs2012 rtm, eclipseandroid

cocos2d-x版本:2.1.2c++

 

一、移植准备windows


在windows下移植咱们须要以下环境支持:Android SDK、 NDK、 Eclipse、 Cygwin.安全

 

1.1下载Cygwin安装程序bash

在Cygwin官网上找(http://cygwin.com/install.html)到在线安装程序,下载对应版本。这里我选择 windows 64bit版本。app

 

1.2 Cygwin安装过程eclipse

打开下载好的setup-x86_64.exe,可一路单击下一步(篇幅所限,太过细节的问题就不一一阐述了),直到以下页面:

选择下载的站点,正确选择站点以后下载会很快。咱们(在北航)选择了ftp://mirrors.neusoft.edu.cn,速度仍是挺快的。这里要提醒你们注意,并非全部站点的下载都是完整的!Rylynn(博客名)选择的好几个站点都下载不完整,你们若是遇到这个问题,可尝试不一样的站点。

选择完站点以后将出现如上界面,这是要选择安装包。为了使Cywin可以编译程序,咱们须要选择一些必要的组件。在不改动默认选择的前提下,咱们须要保证在Devel分支里以下包已经被选中:binutils, gcc-c++,gcc-core,gdb,make,mingw-gcc-core,mingw-gcc-c++。安装成功后,运行Cygwin,能够在Cygwin窗口中分别输入gcc+ -v, g++ -version, make -v, gdb -v等命令并回车,若是看到窗口输出了各组件的版本信息,那么说明安装成功。若是输入某条命令,窗口输出 command not found,那么就须要从新打开安装程序并安装对应的组件,不须要所有从新安装。

 

1.3 安装Eclipse、Android SDK、 Android NDK

这里提供网站连接,你们可自行下载和安装。NDK下载后解压便可。Eclipse的安装和环境配置,请你们参考相应的文章,在此再也不赘述。

Android SDK:http://developer.android.com/sdk/index.html

Android NDK:http://developer.android.com/tools/sdk/ndk/index.html

Eclipse:http://www.eclipse.org/downloads/

 

 1.4 编辑create-android-project脚本

  在cocos2d-x引擎的根目录下,能够找到create-android-project脚本。在windows下,对应的是"create-android-project.bat",这个脚本用于生成游戏的android工程。

  使用任何支持unix风格换行的编辑器(咱们选择了Ultra Editor)打开脚本文件,找到以下语句,并进行修改。

set _CYGBIN = e:\cygwin\bin

set _ANDROIDTOOLS =e:\android\andoird-sdk\tools

set _NDKROOT = e:\android\android-ndk-r8d

其中将_CYGBIN设置为Cygwin安装目录下的"bin"文件夹路径,_ANDROIDTOOLS设置为Andoird SDK安装路径下"tools"文件夹路径,_NDKROOT设置为NDK的解压路径。

完成设置后,在Cygwin中运行"create-android-project"脚本(可直接将文件拖入Cygwin窗口后回车)。若提示以下,则修改为功:

Input package path. For example: org.cocos2dx.example:

 

二、生成项目


接下来咱们执行create-android-project脚本。用Cygwin运行"create-android-project.bat",看到以下提示:

Input package path. For example: org.cocos2dx.example:

此时输入咱们想要建立的程序包名(程序包的命名应遵照Andoird命名规范)。咱们输入:"org.cocofish.skyline"(咱们这个项目的队名叫cocofish,项目叫作skyline。你们可随意选择,只要记住就好)。回车后,窗口输出:

Input project name:

咱们输入了"Skyline"

回车后,窗口会列出计算机中安装的全部Android SDK版本,你们能够根据须要自行选择。咱们输入了"1",即选择android 4.1.2的版本。在Lmeng(博客名)的计算机里,整个过程窗口输出的内容贴在下方:

 

Please enter your package path. For example: org.cocos2dx.example:org.cocofish.skyline
Please enter your project name:Skyline
"Now cocos2d-x suppurts Android 2.1-update1, 2.2, 2.3 & 3.0"
"Other versions have not tested."
Available Android targets:
----------
id: 1 or "android-16"
     Name: Android 4.1.2
     Type: Platform
     API level: 16
     Revision: 4
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, W
XGA720, WXGA800, WXGA800-7in
     ABIs : armeabi-v7a, mips, x86
----------
id: 2 or "Google Inc.:Google APIs:16"
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Revision: 3
     Description: Android + Google APIs
     Based on Android 4.1.2 (API level 16)
     Libraries:
      * com.google.android.media.effects (effects.jar)
          Collection of video effects
      * com.android.future.usb.accessory (usb.jar)
          API for USB Accessories
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: WVGA854, WQVGA400, WSVGA, WXGA800-7in, WXGA720, HVGA, WQVGA432, WVGA
800 (default), QVGA, WXGA800
     ABIs : armeabi-v7a
----------
id: 3 or "android-17"
     Name: Android 4.2.2
     Type: Platform
     API level: 17
     Revision: 2
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, W
XGA720, WXGA800, WXGA800-7in
     ABIs : armeabi-v7a, mips, x86
----------
id: 4 or "Google Inc.:Google APIs:17"
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Revision: 3
     Description: Android + Google APIs
     Based on Android 4.2.2 (API level 17)
     Libraries:
      * com.google.android.media.effects (effects.jar)
          Collection of video effects
      * com.android.future.usb.accessory (usb.jar)
          API for USB Accessories
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: WVGA854, WQVGA400, WSVGA, WXGA800-7in, WXGA720, HVGA, WQVGA432, WVGA
800 (default), QVGA, WXGA800
     ABIs : armeabi-v7a
Please input target id:1

 

完成以后,脚本会在根目录下建立"Skyline"的目录,并在此目录里生成Android项目文件。新建立的项目文件中有Helloworld的项目,你们接着可直接跳到从"执行build_native.sh"继续后续操做,经过完成这样一个默认的项目的移植来检测整个配置和操做过程的正确性。这里将继续本身项目的移植。

打开新建立的项目目录(咱们这里是"Skyline"),能够看到"Classes"和"Resources"目录,脚本会在这两个目录下建立默认的Helloworld代码和资源文件,咱们把它们所有删除。接着,把咱们本身的项目源码和资源复制到这两个目录里。一般,咱们将源代码(.cpp和.h)复制到"Classes"目录下,把资源文件(图片,音乐等)复制到"Resources"目录下。操做完成后,进入下一步。

重要!在新建的项目后,proj.android\jni\hellocpp下,有个main.cpp,是整个项目的入口。直接点击,会弹出"拒绝访问"。若是想要查看里面的内容的话,要先修改它的属性-安全-高级,在权限条目里将权限设置为"彻底控制"(双击后可修改)。main.cpp的内容,通常状况下不须要作修改。

 

三、编译


 完成上述操做后,咱们要对项目进行编译,并生成.so文件(unix的动态连接库,与windows的.dll相似)。

3.1 修改"Android.mk"

"Android.mk"文件位于项目的"proj.android\jni"目录下,它记录了项目所包含的源码文件信息。利用编辑器(如Ultra Editor)打开此文件,参照下面的文件进行修改。/*...*/里的内容是笔者加上的注释

 

LOCAL_PATH := $(call my-dir)   /*不改动*/

include $(CLEAR_VARS)           /*不改动*/

LOCAL_MODULE := sky_shared       /*默认为game_sharred,若是改动,请必定记住*/

LOCAL_MODULE_FILENAME := libsky  /*默认为libgame,若是改动,请必定记住。*/

LOCAL_SRC_FILES := hellocpp/main.cpp \ 
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/其余源文件.cpp       /*添加上本身项目里全部的源文件,结尾的'\'是链接符,若是下一行还有内容,请不要漏掉.并且'\'后应直接回车*/           
                   
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \
                    $(LOCAL_PATH)/../../../cocos2dx/platform/third_party/win32 \
                    $(LOCAL_PATH)/../../../extensions                   /*添加上本身项目里头文件所在的目录。后两行是笔者由于项目而单独添加的,前一个是为线程,后一个是为                                           控件类引入的头文件所在的目录*/

LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static cocosdenshion_static cocos_extension_static   /*如下均不做改动*/
            
include $(BUILD_SHARED_LIBRARY)

$(call import-module,CocosDenshion/android) \
$(call import-module,cocos2dx) \
$(call import-module,extensions)                           

 

重要!出错点!笔者在这一步遇到不少问题,因此也请读者加以重视。

(1)对LOCAL_MODULE与LOCAL_MODULE_FILENAME修改后请务必记住本身所修改的名字。好比笔者将它们改成skyline_shared和libskyline。由于这里的skyline将会在导入eclipse那一步以后用到。咱们须要将在经过执行“create-android-project”建立的项目文件夹里的"<你的项目名>.java”(好比"skyline.java")这个文件里System.loadLibrary("game")的“game”改为本身所修改的名字,在笔者这里就是"skyline",不然就是黑屏。估计是没法加载生成的libskyline.so(后面会提到)。笔者由于这个问题纠结了好久!最后才发现原来就一个字符串的事情!!若是不改动前面的LOCAL_MODULE和LOCAL_MODULE_FILENAME,由于默认的是"game",那就不会有问题。

(2)若是你在项目里引入了线程和控件类,可参考笔者这个代码框里的LOCAL_C_INCLUDES。对于线程,请注意:将你引入线程的那个文件里"#include 'pthread/pthread.h'"改成"#include'pthread.h'",以使编译可以经过。(笔者不知道缘由,也许没有这么麻烦,可是在笔者计算机里成功了。也但愿明白的人告知~)

3.2 执行"build_native.sh"

接下来就启动编译了。进入android项目路径下,使用Cygwin执行"build_native.sh"脚本(tip:可直接将文件拖入Cygwin窗口),若是顺利,咱们能够在Cygwin窗口输出的最后发现“Install : libsky.so => libs/armeabi/libsky.so”,而且在libs/armeabi目录下找到编译得到的"libskyline.so"(注意到了吗,这是上一步设置的LOCAL_MODULE_FILENAME)。

重要!出错点!若是此时提示“please define NDK_ROOT”,找到cygwin\home\xxx(你的用户名)目录下.bash_profile文件,用文本编辑器打开,在最后加入下面两行:

NDK_ROOT=/cygdrive/d/Coco/android-ndk-r9

 

export NDK_ROOT

错误将再也不出现。d/Coco/android-ndk-r9 是你ndk解压目录,笔者的原目录是D:\Coco\android-ndk-r9,作相似改动便可。

 

然而,事情每每不那么顺利!

重要!出错点!很大可能你会看到Cygwin输出一大堆乱七八糟的东西,并且在中途停下。这时候就是编译出错了。可是千万不要着急,一点点调。虽然出错了,可是报错点仍是很准确的。因此请你们从最上面往下一行一行找。发现有"error"的这行,这就是报错点。仔细看这行的内容,它很明确地告诉你是哪一个文件哪一行出了错。这时候去找到那个出错的位置,根据报错的信息,查找一些资料,加上本身的判断和尝试,把错误处理掉。而后再编译一遍。若是有错误,继续处理。不要看一堆字母感受烦躁(看着就像乱码的感受),这时候你最须要的就是慢慢来。并且这个错误可能来自于引擎代码自己!!

好比笔者遇到这样几个错误:

(1)使用了未声明的"itoa"。因而我去查Classes目录下的props_number_shower.cpp第27行,确实调用了itoa这个方法。虽然这个在vs2012里运行没问题,可是这里并不支持。因而我从网上找了一个替代itoa功能的函数源代码,加入到这个源文件中,编译就经过了。网友涵曦(博客名)提示,这是包含文件的问题。在此表示感谢!

(2)格式问题。一样的思路,找到CocosDenshion/android/SimpleAudioEngine.cpp第77行。发现了LOGD(deviceModel)(如图)。上网查了下发现好像linux对格式要求比较严格,因而笔者尝试把这行改成LOGD("%s", deviceModel);发现编译经过。在编译的过程当中发现很是多相似的报错,你们若是看到报错信息以下图,找到指定位置修改便可。

(3)文件流。笔者对c++文件流是否能在Cygwin中编译经过没有作足够的测试。可是笔者将fstream换成c的FILE操做的时候就不报错了,若是你们在这里遇到问题,能够尝试着改改。可是对于移植到android上,还应采CCFileUtils。范例以下:

string fullPath=CCFileUtils::sharedFileUtils()->getWritablePath()+"rank.txt";   /*"rank.txt"是本身使用的资源文件,其余的不用改动。此行用于得到文件位置*/
unsigned long file_size;                                                       /*声明变量,在下一行中使用,用于接收文件内容大小*/
char *filedata=(char*)CCFileUtils::sharedFileUtils()->getFileData(fullPath.c_str(),"r",&file_size); /*取得文件指针*/
if(filedata==NULL)...                                                                                /*对于文件指针的用法,与C++同样*/

 若是遇到其余的错误,读者可按照以上解决问题的思路自行解决问题。

 

四、导入Eclipse


 

 4.1新建项目

 打开Eclipse,一次打开"File"-"New"-"Project"-"Android"-"Android Project from Existing Code"项目,在随后出现的界面中点击browser,后找到游戏项目的"proj.android"并确认,此时即从原有代码中新建了安卓项目。

4.2复制必要文件

4.2.1将cocos2d-2.1rc0-x-2.1.2(根目录)\cocos2dx\platform\android\java\src下的文件复制到Sky(游戏项目根目录)\proj.android\src里,并在eclipse中手动导入

4.2.2若是Sky(游戏项目根目录)\proj.android\assets里没有资源文件,将Sky(游戏项目根目录)\Resources下你的全部资源文件复制到assets中,并在eclipse中手动导入

4.3 作必要的修改

4.3.1 在Sky(游戏根目录)\src\<项目名>里的Sky.java文件里,下图所标示的那行中,请记得将loadLibrary("xxx");里的字符串改成先前修改过的LOCAL_MODULE_FILENAME的值(去掉lib),如笔者改成sky。注意!这在上面已经强调过,若是这里的字符串和LOCAL_MODULE_FILENAME(去掉lib)的不匹配,结果很惨烈!看不见界面!笔者在这里费了不少时间!

 4.3.2 其余简单的错误,好比下图所示:找不到drawable/icon,可在eclipse工程中res里加入一个icon.png文件便可。固然也可将icon更名成其余以存在于工程的图片文件(通常为png文件)

 

五、调试


 虚拟机十分卡,并且好像并不支持opengl,因此建议使用真机进行调试(使用方法这里就不详细展开,你们可在网上查阅相关资料)。调试过程当中不免发生问题,这里将列举出笔者在调试过程当中遇到的问题,探讨解决的思路。

5.1 文件权限问题。在调试过程当中咱们在logcat message窗口看到这样一个错误,意思是某个文件权限不够。若是这时候你们复制这么长串的看起来像目录的东西去搜索,是找不到的。由于他们毕竟不是目录名。这个时候,你们能够选去关键词去搜索。好比这张图片里,咱们认为"shader"是关键词,果真在项目安卓工程里找到了"shaders"文件夹,将里面全部文件的权限修改为“彻底控制”,发现调试再也不报错,能够认为修改为功!

 

5.2文件读写问题

  某种意义上笔者并不肯意把它称做文件读写问题。后面将作解释。

  若是读者还记得的话,上面已经提到过读写问题。若是单纯采用C的文件读写写法,工程就会找不到资源文件。所以将它改为上述的CCFileUtils,将解决此类问题。

string fullPath=CCFileUtils::sharedFileUtils()->getWritablePath()+"rank.txt";   /*"rank.txt"是本身使用的资源文件,其余的不用改动。此行用于得到文件位置*/
unsigned long file_size;                                                       /*声明变量,在下一行中使用,用于接收文件内容大小*/
char *filedata=(char*)CCFileUtils::sharedFileUtils()->getFileData(fullPath.c_str(),"r",&file_size); /*取得文件指针*/
if(filedata==NULL)...    

5.3 如何调试

之因此说读者不肯意把“5.2文件读写问题”称做“文件读写问题”,是由于读者在解决这类问题的时候使用的方法实际上是告诉了咱们如何进行调试。笔者在完成5.1那一步以后发现真机上仍是没有显示出任何内容。黑屏!这个时候咱们着急了,曾经已经将helloword显示在手机上了,为何这个项目就不能够?!学长提示咱们是否是主菜单加载不成功,并知道咱们对每个关键部分加上一个输出,经过在控制台的输出查看哪一步出了问题!好比咱们在主菜单"mainmenu.cpp"的"init()"里每个加载操做后加上了CCLOG("%s","init() xxx;--From MainMenu")("xxx"这里改为特定的值,用于肯定出错位置)。也是经过这个方法,咱们才肯定了全部的“文件读写问题”。所以,若是你们遇到问题,请你们不要气馁,一点点地去判断出错位置,而后修改,尝试。

 

六、分辨率适配


最后一个问题就是分辨率适配了。在网上翻看了相关资料后,总算解决了问题。其实就是一行代码的事情。

在 AppDelegate.cpp的 bool AppDelegate::applicationDidFinishLaunching() 方法里,加上

CCEGLView::sharedOpenGLView()->setDesignResolutionSize(576,324,kResolutionNoBorder);便可解决分辨率适配问题。

其中,576,324 是笔者在win32设计游戏时采用的宽度和高度,你们改成本身所设置的宽高便可。kResolutionNoBorder是指在屏幕拉伸时采用的其中一种策略,保证拉伸后无边界,可是设计时界面的边缘部分可能在最后被遮盖。笔者经过vs2012的 "go to definition"操做找到了以下的定义。如下便是所有的适配策略了。

 

enum ResolutionPolicy
{
    // The entire application is visible in the specified area without trying to preserve the original aspect ratio.
    // Distortion can occur, and the application may appear stretched or compressed.
    kResolutionExactFit,
    // The entire application fills the specified area, without distortion but possibly with some cropping,
    // while maintaining the original aspect ratio of the application.
    kResolutionNoBorder,
    // The entire application is visible in the specified area without distortion while maintaining the original
    // aspect ratio of the application. Borders can appear on two sides of the application.
    kResolutionShowAll,

    kResolutionUnKnown,
};

 

 参考资料:参考的资料较为零碎,多为网上的文章。由于比较繁乱,没有记录下来。另外参考了《Cocos2d-x高级开发教程》的移植部分。

总结:

  笔者和队友在整个移植过程当中备受煎熬,几近绝望。可是始终相信既然别人可以移植成功,咱们也必定能够!最终咱们用了两天多的时间终于让咱们的游戏成功运行在手机上!那个兴奋感、那种绝处逢生的快感到如今还十分难忘!因此请各位cocos2d-x的战友们不要气馁,问题都是能够解决的,一点一点来,不要着急,给本身信心。先把helloworld显示出来,而后再把本身的项目慢慢调出来。坚持下去,总会成功的!

       Here is our game <SkyLine Beta1.0>, Please download it to support us!!!

      http://pan.baidu.com/s/13O4dT

  但愿这篇文章可以帮到困扰在cocosd-x移植android过程当中的朋友们。若是文章内容与错误或者某些部分有更好的解法,也请留言。咱们很但愿和你们交流经验!谢谢!

转载请注明原地址:http://www.cnblogs.com/Z-XML/p/3349518.html

编辑:Lmeng Rylynn

相关文章
相关标签/搜索