第2章 Cocos2D-X 引擎的开发环境
Cocos2D-X引擎具备了强大而完善的功能。本章节就将带领读者进入Cocos2D-X引擎的世界。
首先,我们将会建立跨平台的开发环境。这是制作游戏项目的第一步。对于初次接触跨平台开发的读者来说,将会接触到许多新的知识。这些知识大多属于技巧型的。只需要掌握其中的步骤,就可以熟练使用,而无需明白深奥的道理。因为游戏产品的制作需要保证稳定的开发环境,所以通常游戏的开发环境搭建好之后,就很少会出现变更。
然后,依靠引擎中提供的项目工程文件或者脚本代码,在各个平台的开发工具中建立Cocos2D-X引擎的项目。最后,通过一个“HelloWorld”示例项目,为读者展示如何将多个平台集中在一个环境中进行开发。
2.1 跨平台的开发
Cocos2D-X 引擎是专门用于跨平台开发的。它为开发者提供了良好的多平台支持。在表 2-1 中,列出了引擎支持的平台以及版本。跨平台的开发方式存在许多好处,也存在缺点。当然肯定是优大于缺,否则也不会有那么多开发者提倡此技术了。跨平台的好处,不言而喻。缺点呢?同样也是因为多平台开发带来的问题。不同的平台就意味着开发环境、编程语言、开发库以及终端设备不同,这些都无疑会为开发者带来更多的工作。好在有Cocos2D-X引擎的协助,减少了很多开发者的工作。
表2-1 引擎支持平台和版本
续表
本章节将要建立跨平台的开发环境,主要以Android、iOS、PC平台为主,其他平台为辅。上一章中,我们已经安装了游戏引擎的源代码包。接下来就需要建立针对各个平台来建立项目工程。此时读者就会需要下载安装一些开发工具以及系统SDK。因为还要制作iOS设备的游戏产品,所以资金允许的话,读者最好还能有一台Mac系统的电脑。这样的话,就可以开发iPhone和iPad设备上的游戏产品了。
说明:引擎安装,其实就是将下载的源代码包解压。
建立开发环境之后,就是建立项目工程。因为需要针对三个平台进行开发,所以将多平台的项目统一维护是开发者必备的能力。虽然在引擎中提供了项目脚本和示例项目,但是大多数的情况下,开发者会以手工的方式来创建项目工程。这样做自主性会更强一些,主要原因在于要将不同平台的内容串联。虽然使用了不同的项目工程,但是要尽量保证使用同一套代码和资源,这样将会减少跨越平台时所带来的工作量。
说明:多个平台使用同一套代码和资源,只是理想状态。实际的项目中,总会有特别处理的情况。
项目工程构建完成之后,将会为读者介绍工程目录以及文件的组成结构,以验证开发环境是否可用,同时展示一下Cocos2D-X 引擎。此时,将会在三个平台编译且运行“Hello World”示例项目。所以说本章节是跨平台开发的第一步,也是读者初识Cocos2D-X引擎,进入游戏开发领域的第一步。在本章节的介绍中,还包含另一部分内容就是混合编译,这也是跨平台开发的不能缺少的重要内容。
游戏开发人员必须要面对多种语言混合的编译环境,其中包括了C++、Java、Objective-C。除此之外,开发者还会遇到一些脚本语言包括Lua和JavaScript。在章节最后会为读者展示一些引擎中的实例项目,让读者先领略一下引擎强劲的功能,对于之后的内容有一个前期的预览。然后本书就会逐个章节展开,为读者进行详细介绍。
无论正版还是盗版,Windows系统的市场占有率绝对是最高的。所以在实际的开发中,以Windows系统为主要的开发环境是大多数开发者的选择。通常首先完成的就是游戏的 PC 版本,然后再适配到其他移动平台。开发中主要应用的语言为C/C++,也会少量地使用Java 和Objective-C编程语言。综上所述,最后本书所用的跨平台开发方式就如图2-1所示。
图2-1 跨平台开发方式
图 2-1 展示了接下来要制作游戏的主要方式,读者要做好跨平台开发的准备。虽然制作游戏的工作量不是按照平台的数目成倍增长的,但是更多的平台意味着更多的工作内容。在建立开发环境的过程中,读者就能有所体会。下面,让我们开始吧!
2.2 建立开发环境
所谓的开发环境就是制作游戏的地方,打个比方读者就会十分清楚了。比如提到做饭,人们都会想到厨房。这是因为厨房有炉灶、烟机、水盆以及其他工具。这就是一个做饭的环境。很少有人会在卧室炒菜蒸饭吧!同样,游戏开发也需要一个制作环境。这个环境包含了编辑器、程序库、打包工具以及设备连接。因为Cocos2D-X引擎支持多个平台,所以按照之前的介绍,开发者至少需要搭建三个开发环境。这就是接下来介绍的内容。
2.2.1 PC开发环境
PC的开发环境是最好搭建的,也是开发者最常用的一个平台。想必各位读者都会有一台个人电脑。安装Windows 7 版本之后的操作系统,然后安装Visual Studio 2010。在引擎包中,提供了三个版本的项目工程。它们分别针对VS2008、VS2010以及VS2012。除了VS2008是即将要淘汰的版本之外,另外两个读者可以随意选择。不过本书将会使用VS2010进行介绍。
注意:VS2010只支持Win7以后的操作系统。另外,微软官方提供了可免费试用30天的VS2012版本,其他的VS版本读者需要自己想办法来获取了。
安装VS2010的过程,就不在此啰唆了,只要是Windows平台的开发者对此都不会陌生。只不过,在第一次运行软件时,读者记得选择 C++语言的开发方式。完成安装之后,开发者就可以直接双击引擎目录下的工程文件(cocos2d-win32.vc2010.sln)了。通过文件关联,VS2010就会自动启动。此时读者就会看到如图2-2所示的界面。
图2-2 Cocos2D-X示例项目工程
在界面中展示了许多的示例项目。读者选择项目之后,点击右键就可以编译运行。在示例项目中展示了引擎的各项功能。示例项目能够帮助读者熟悉引擎,在后续的章节中将会逐渐介绍它们。
技巧:VS2010有一个非常好用的开发插件VisualAssist X,推荐读者一同安装。
除了直接可用的工程文件之外,PC 版本还提供了批处理编译和模板安装。build-win32.bat 是批处理编译文件。执行后,将会自动编译 Cocos2D-X 引擎中 tests 示例项目。编译成功后生成可执行文件在Release.win32文件夹中。开发者运行tests.exe就会看到如图2-3所示的画面。此示例程序几乎展示了所有Cocos2D-X引擎功能,有兴趣的读者可以通过菜单来选择查看。
图2-3 tests示例项目
Cocos2D-X 引擎提供了VS 直接使用的项目模板。通过执行install-templates-msvc.bat文件就可将项目模板安装至VS当中。当开发者需要新建项目时,就可以在菜单中直接选择。
注意:模板安装文件支持VS2008,而VS2012、VS2010、Visual C++2008 Express、Visual C++2010 Express则为0.8.0版本以后。
模板是用来创建新的项目工程的。在VS界面菜单栏中选择创建项目。开发者可以在图2-4所示的界面中,选择创建一个Cocos2D-X项目。
图2-4 利用模板创建新项目
在使用模板创建新项目时,开发者需要输入项目工程的名字。如果需要创建新的目录,则可以勾选右侧选项。单击“OK”按钮之后,就会进入Cocos2D-X项目配置页面。在如图2-5所示的页面中,开发者可以选择引擎所要引用的程序库。
图2-5 配置Cocos2D新项目所用的工程
图2-5所示的是四个可勾选的程序库,从上到下分别为Box2D物理模块、Chipmunk物理模块、声音引擎以及 Lua 脚本支持。此时读者可能还不太清楚上述模块的功能。这无关紧要。我们也不是马上就要开始建立新的游戏项目,所以直接单击下一步即可,这就完成了新项目的配置。
如果读者能够顺利编译通过,就说明PC的开发环境已经配置完成了。与其他平台相比,PC平台的搭建算是简单的。只要将示例项目编译成功,就可以在“Debug.win32”或者“Release.win32”中找到exe执行文件。将来开发者推出游戏的PC版本时,只需将exe和资源文件打包就可以发布了。
在安装了项目模板之后,开发者创建一个新的项目已经非常容易了。不过在项目创建完成之后,开发者还需要配置一些项目内容,比如库文件的连接以及头文件的引入。这些工作主要是基于VS开发环境来完成的。如果读者有过VS的开发经验,那么就可以跳过本小节。
如图2-6所示,展示了引擎中自带的示例项目工程。在图中几乎列出了所有引擎中的模块以及示例程序。这其中 HelloCpp 是基本的示例项目,类似HelloWorld。HelloLua则是为了展示Lua脚本功能的示例项目。TestCpp则是为了展示引擎中各种功能的示例程序。TestJavaScript和TestLua是为了以脚本语言来呈现引擎中各种功能。《MoonWarriors》则是一款精彩的射击游戏。余下的项目都是引擎中引入的开发库。
图2-6 PC 项目工程
libBox2D与libchipmunk是来自第三方的物理引擎。它们可以实现游戏中的物理模拟与碰撞检测。如果读者需要实现类似《疯狂的小鸟》或者《小鳄鱼爱洗澡》类型的游戏,那么就需要在两者之间选择一个。libcocos2d 则是引擎核心库,它为开发者提供了游戏制作所需的功能。libCocosDenshion是声音引擎,针对不同的平台为开发者提供了统一程序接口。libExtensions是引擎扩展库,其中包括了一些来自开发者分享的成熟功能,比如网络连接、UI控件等。libLua则是为开发者提供的lua脚本支持库。
说明:在其他平台中也会存在相同的内容,只不过表现的形式会略有不同。因为在此已经进行了详细的介绍,所以后续内容再出现时就不再啰唆了。
经过上面的介绍,读者可以归纳出一点:在示例工程中,项目分为两类,一种是可运行的示例项目,另一种则是被引用的程序库。当读者建立新项目时,也需要引入所需的库。每一个项目都不可或缺的就是libcocos2D。其他库则是依据游戏要求来挂接的。比如libCocosDenshion是音乐库,很少有游戏不需要的。
为了引入需要的库,开发者需要在VS中进行设置。选择项目属性,在属性界面中选择连接器(Linker)。在导入分支中,就能看到当前项目引入的程序库。图2-7展示了HelloCpp项目中引入的程序库。
图2-7 HelloCpp引入库
从图2-7可以看到,除了引擎工程中所带的程序库之外,还有一些系统中的开发库。比如pthreadVCE2.lib就是用来管理线程的程序库。读者可以在此添加引擎中的第三方库,比如libCocosDeshine.lib。当前项目引入的库,是为了生成可执行文件的。在编译代码时,项目还需要连接代码的头文件,在配置界面中开发者需要添加头文件的访问路径。图2-8就是HelloCpp项目中头文件的配置路径。
图2-8 HelloCpp头文件路径
在头文件路径中,列出了 C++源代码编译时需要引入的代码声明内容。这也是读者将来需要配置的地方。当读者新建立PC项目工程时,头文件以及库的引入都需要进行配置。配置正确之后,开发者就可编译项目生成游戏的可执行文件了。
注意:开发者需要调整项目工程编译的先后顺序,将第三方库编译放置在工程项目之前,才能够引入编译完成的库文件。
2.2.2 Android开发环境
Android是由谷歌公司维持和更新的半开源操作系统。它主要针对移动设备。如今算谷歌在内,全球已经有八十四家硬件制造商、软件开发商以及电信与电信营运商共同研发改良Android系统。2010年末数据显示,仅正式推出两年的 Android 操作系统在市场占有率上已经超越称霸逾十年的诺基亚Symbian 系统,成为全球第一大智能手机操作系统。如今Android操作系统更是成为了移动手机市场的老大。
Cocos2D-X 引擎对 Android 系统提供了完善的支持。在构建其开发环境之前,读者需要下载下面列出的相关工具以及开发包。
通过谷歌搜索,读者可以轻易地就获得表 2-2 所列出的工具。它们都是免费为开发者提供的。有一点读者需要注意,那就是一定要按照表中的先后顺序进行安装。
表2-2 Android开发环境所需工具
(1)安装JDK
首先从ORACLE网站下载1.6版本的JDK,网址如下。
http://www.oracle.com/technetwork/java/javase/downloads/index.html
在获取了下载包之后,进行安装。读者可以选择默认的安装路径,也可以另选自定义路径。但是一定要记得安装位置,因为在后续步骤中将进行配置。JDK 的安装,并没有复杂之处,只需连续点击下一步,就可以完成。
(2)安装Eclipse
开发者可以从Eclipse官方网站下载此工具。推荐大家直接下载EclipseIDE for Java版本。网址如下。
http://www.eclipse.org/downloads/
Eclipse安装方式十分容易,只需要将下载的文件包解压缩即可。在解压后的目录中,运行Eclipse执行文件,它将会自动搜索并连接JDK。如果没有找到JDK的话,读者可以选择菜单配置(Preferences)选项,将会弹出如图2-9所示的界面。选择Java就可以配置JDK的路径了。首次运行时,开发者需要制定一个工作路径,此路径下就是将来要存放项目工程的地方。
图2-9 配置JDK
(3)安装CDT
CDT作为一个Eclipse的插件,它有两种安装方式。一种是通过Eclipse直接网络安装;另一种则是先下载插件包,然后解压拷贝至插件目录。读者可以随意选择这两种方式,它们的效果是一样的。CDT程序包可以通过下面的地址来下载。
http://www.eclipse.org/cdt/downloads.php
在CDT的下载页面中,列出了适合各种Eclipse版本的内容。网络安装则需要在Eclipse的菜单栏Help选项中选择Install New Software,然后输入CDT的response的地址,点击下一步即可。如果开发者直接下载了插件包,则需要将压缩包中features和plugins内容,放置在Eclipse相同的目录下,然后重启Eclipse即可。
(4)安装Android SDK
Android SDK为开发者提供了Android 系统开发程序包以及模拟器。在如下的网站中,开发者可以获得最新版本的Android SDK。
http://developer.android.com/sdk/index.html#download
Android SDK的安装,与一般软件类似。选择需要安装的路径以及Eclipse路径后,Android SDK就算安装完成。Android SDK中还提供了安装和升级工具SDK Manager,其运行的界面如图2-10 所示。图中列出了所有当前已经安装的Android SDK以及其他开发工具,在此界面开发者可以下载和更新最新的开发包以及工具。
图2-10 SDK Manager 界面
在安装路径下,读者可以找到执行文件SDK Manager,之后如果想要更新ADT或者Android SDK的版本,都可以通过此软件来完成。
(5)安装ADT
ADT也是Eclipse的一个插件,只不过它是由谷歌公司推出的。其安装的方式与CDT类似。开发者可以通过如下网址来下载ADT插件。当然,读者也可以选择通过网络安装。
http://developer.android.com/tools/sdk/eclipse-adt.html
ADT安装成功后,开发者将能够在Eclipse页面看到ADT的三个按钮。在ADT中提供了Android SD and AVD Manager。此工具是用来管理Android SDK和创建Android虚拟机的。开发者需要在ADT中配置Android SDK。在配置 (Preferences)页面中,选择Android 后就会出现如图2-11 所示的界面。此时选择Android SDK的安装路径即可。
图2-11 Android SDK配置
(6)安装NDK
NDK(Native Development Kit)是一系列工具的集合。它能帮助开发者快速开发C(或C++)的动态库,并能自动将生成的so库文件和Java应用一起打包成apk。这些工具对开发者有很大帮助。NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改编译的mk文件就可以创建出so。
NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作,也降低了使用C++语言开发的门槛。NDK提供了一份稳定、功能有限的API头文件声明。谷歌曾明确表示提供的API是稳定的,在后续所有版本中都支持当前发布的 API。从发行的版本中来看,这些 API 支持的功能非常有限,仅仅包含一些基础的程序库:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog)。
NDK是一个Android开发工具。下载的NDK版本只是一个开发者使用的工具,它需要与模拟器等其他工具配合使用,主要用于编译 C++代码成为 Android 系统应用程序。开发者可在官方网站下载最新的版本。读者只需将下载的压缩包解压至特定路径即可。
http://developer.android.com/tools/sdk/ndk/index.html
注意:根据Android官方网站的解释,NDK版本之间并不互相支持,这就意味着高版本与低版本之间,有些工具和项目是不能通用的。
NDK的r8版本,不再需要安装Linux虚拟机就可以进行编译,所以现在的开发者省去了安装Cygwin的步骤。如果读者想要直接安装Android项目模板,则依旧需要安装Cygwin来创建一个Linux虚拟环境。这主要是因为Android系统下的C++代码编译,需要基于Linux环境。create-android-project.bat文件就是用于直接创建Android工程的批处理执行。
技巧:如果读者想省去上述环境搭建的繁琐,可直接下载 ADT Bundle。它集成了 Eclipse、ADT 插件以及AndroidSDK。
在完成了上述配置之后,我们就可以编译一下HelloWorld项目了,来测试一下Android的开发环境是否正确。运行Eclipse工具,在菜单栏中选择导入选项,在如图2-12所示的弹出界面中,选择导入现有项目。
图2-12 导入现有项目
在接下来的弹出界面中,选择Cocos2D-X引擎的sample目录,如图2-13所示,这样的话开发者就可以将所有示例项目都导入到工程当中。在导入项目的过程中,可能会遇到缺少配置文件的情况,读者可手工创建缺少的文件。
图2-13 导入全部示例项目
在导入Cocos2D-X引擎的示例项目后,读者就可以选择其中的HelloCpp。通过点击按钮或者按键Ctrl+F11来运行。运行Android项目需要使用终端设备,读者可以连接真实手机,也可以通过AVD创建模拟器。开发者可以使用AVD Manager 来创建模拟器。如图2-14 所示的界面,展示了创建模拟器时需要配置的选项。如果直接连接手机,则需要安装硬件驱动。
图2-14 AVD Manager 创建虚拟机
刚刚我们在Eclipse中编译的仅仅是Java代码,若要编译C++代码,则必须用到NDK。按照以往的方式,开发者需要安装Linux虚拟机才能够编译C++代码。不过,r8版本的NDK提供了命令行的编译方式,此时就会用到NDK-BUILD.cmd文件。
对于NDK的编译方式,开发者有两种选择:一种是通过命令行的方式,另一种是集成在Eclipse当中。命令行的方式适合在批处理的情况来完成。其原理与集成Eclipse编译是一样的。为了集中开发,下面就以Eclipse集成编译进行介绍了。接下来需要把NDK编译添加进来,以便能够编译C++源代码。如图2-15所示,选择项目的属性。然后在Builders选项中创建一个新的编译项。
图2-15 Builders 配置
在新创建的编译项中,需要输入ndk-build.cmd命令的执行路径。然后再设置工程的执行路径。ndk-build将会依据项目目录jni下的Android.mk来编译当前的项目。这已经是引擎开发者编写好的内容。具体细节读者可以参考图2-16所示的内容。
图2-16 配置新的编译选项
在选择了正确的执行文件以及工作环境之后,如果是2.0以前的引擎版本就可以进行编译了。恰好我们选用的是2.0之后的版本,所以还需要配置环境常量。因为在Android.mk中引用了一个模块,这就是引擎的核心:cocos2dx模块,如果NDK编译时,没有找到它,就会出现错误。应对的办法也很简单,通过在界面中选择环境标签,然后设置NDK_MODULE_PATH环境变量即可。
这里还有一点需要注意。通常游戏会引用多个引擎模块,所以在Android.mk中也包含了多个模块引入设置。当NDK编译时,首先会引入cocos2dx模块。此时就会在路径%NDK_MODULE_PATH\cocos2dx下寻找Android.mk文件,然后再引入其他的模块。所以在编辑Builder的环境时,就需要添加一个NDK_MODULE_PATH变量,如图2-17所示。其中环境变量的具体内容如下。
图2-17 设置环境变量
X:\cocos2d-2.0-rc2-x-2.0.1; X:\cocos2d-2.0-rc2-x-2.0.1\cocos2dx\platform\third_party\android\prebuilt
内容中包括了两个路径,以分号来区分。读者需要填写自己的地址,与上边的内容不同。第二个路径的设置是为了引入游戏所需的其他模块。设置完成之后,就可以进行编译了。
在Eclipse中,刷新项目工程时,就会进行自动编译。如果开发者也希望NDK能够自动编译。则需要在Builder 中进行设置。选择刷新(Refresh)标签,在如图2-18 所示的设置界面,点选Specify Resources,然后就会进入项目目录的选择界面。
图2-18 设置刷新选项
注意:通过配置Eclipse,也可以手动地编译项目工程。
在图 2-19 所示的项目内容中,选择需要 NDK 编译的内容。按照 Cocos2D-X 引擎的结构,在目录 jni中存放着需要NDK编译的内容。所以每次当此路径下文件刷新时,就需要重新编译。因此,读者需要按照图2-19 所示勾选jni 目录。然后再跳转到Build Options标签。
图2-19 选择项目刷新内容
在Build Options界面中,提供了执行编译命令的情况。具体如图2-20 所示。
图2-20 编译条件选项
开发者需要勾选其中的“Specif yworking set of relevant resources”选项。这样在目录刷新时,就会自动执行此Builder命令。单击“确定”按钮,就完成了NDK编译的设置。
说明:记得勾选Allocate Console链接控制台输出信息。这样的话在控制台(Console)中,开发者就能够看到输出的编译信息。
至此为止,我们就完成了Android开发环境的搭建。因为Android开发主要以Java为主,所以为了编译 C++代码开发者需要颇费一番周折。图 2-21 显示了 HelloCpp 项目中的所有内容,其中包含了很多与Android应用程序相关的配置。作为初步的了解,我们来看看其工程的组成内容。
图2-21 HelloCpp 示例项目Android 工程
在图2-21 左侧显示的就是一个标准的Android 项目工程。其中gen 目录是由Android SDK自动生成的资源索引文件。src用来存放应用程序源代码。在此目录中,存放着HelloCpp.java的源代码文件。接下来的是Android开发库的引用。bin文件用来存放编译时产生的中间文件和执行文件。jni存放来自于由C++代码编写经过NDK编写的so程序库。在Linux平台,C++库文件是以“.so”作为文件结尾的。res中存放着项目资源。
注意:res目录中的结构是按照屏幕尺寸来划分大、中、小三个资源文件的。
余下的文件则都是 Android 项目的配置文件。其中 AndroidManifest.xml 是最为重要的。它是每一个Android 应用程序都不可缺少的,也是开发者经常设置的内容。ADT 工具提供了此文件的页面编译形式。但是作为代码工作者,我们还是直接来看文件内容吧!
代码2-1 AndroidManifest.xml配置文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.cocos2dx.hellocpp"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8"/>
<application android:label="@string/app_name"
android:debuggable="true"
android:icon="@drawable/icon">
<activity android:name=".HelloCpp"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:configChanges="orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<supports-screens android:largeScreens="true"
android:smallScreens="true"
android:anyDensity="true"
android:normalScreens="true"/>
</manifest>
代码2-1是一个标准的XML格式文件。在文件中包含了当前应用程序的配置信息。逐行为读者进行介绍。
(1)manifest:指定本应用内java主程序包的包名,包名在Android系统运行时要保持唯一。设置代码版本和版本号。
(2)uses-sdk:标识本应用运行的SDK版本。高兼容性的应用可以忽略此项。
(3)application:应用程序配置内容,包括了名字、图标,是否为测试版本。
(4)activity:应用程序执行设置,包括了名字、标签、屏幕朝向、全屏模式。
(5)intetnt-filter:设置应用程序为首要执行的方式。
(6)supports-screens:支持屏幕类型。
HelloCpp 的配置文件内容相对简单。按照 Android 应用的配置,还会有权限设置(Permission)、认证(Certificate)等等。其中权限的设置是开发者经常遇到的。当引入一些手机功能时,比如联网、定位,就需要进行相应的权限设置。
在完成了上述步骤之后,读者就可以在手机或者模拟器上运行 Cocos2D-X 示例项目了。图 2-22 就是HelloCpp在Android模拟器中运行的画面效果。
图2-22 HelloCpp在Android 平台运行的画面
2.2.3 iOS开发环境
刚刚配置了 Android 开发环境,读者已经略微领略了跨平台开发的繁琐之处。接下来,将要搭建 iOS系统的开发环境。在此环境下读者就可以开发iPhone以及iPad平台的游戏产品。不过要想在真机测试,则还需要花费99美元购买苹果开发者授权。当然,iOS的开发环境是必须要在Mac系统的电脑上进行的。如果读者想要在火爆的应用商店上捞一捅金的话,就需要先准备上述两个条件了。
Mac平台的开发者,如果想要开发iOS系统的应用程序,那么XCode集成开发环境是必不可少的。开发者可以通过MacStore进行下载安装,也可以登录苹果开发者中心来下载安装。苹果开发者中心的网址如下。
https://developer.apple.com/xcode/
在如图2-23所示的页面中,读者可以下载到XCode最新版本4.0。在下载的程序包中,通常也包含了最新的iOS SDK。这是用来开发iOS 系统应用程序所需的程序接口库。通常XCode的安装包都会需要超过1GB的硬盘空间。
图2-23 苹果开发者中心XCode下载页面
Cocos2D-X在Mac上的开发环境搭建相对简单许多。不过,对于第一次接触Mac电脑的人来说,还是有些困难的。读者先将Cocos2D-X引擎的文件包拷贝到Mac电脑当中,直接双击,就可以完成解压。在Cocos2D-X根目录中,找到install-templates-xcode.sh,此文件就是一个Mac系统中的可执行文件。它与Windows系统中的bat文件十分类似。它是用来安装引擎项目模板的。读者可以直接运行,也可以以命令行的方式运行。
在 Finder 中,运行终端( temrial )。然后通过命令行的方式进入到 cocos2d-x 的目录。接着输入sudo./install-templates-xcode.sh就会执行文件。将引擎的项目工程模板安装至XCode当中。安装完成之后,继续在Finder中运行XCode。读者也可在如下的引擎目录中,点击XCode项目工程来开启。
\cocos2d-2.0-x-2.0.4\samples\HelloCpp\proj.mac
在出现了XCode操作界面之后,选择新建项目就会看到如图2-24所示的界面。
图2-24 Cocos2D-X项目模板
在图2-24所示的界面中,开发者可以选择四种工程的类型,它们的区别在于加载了不同的第三方库。这一点与其他平台类似。省去新建项目的时间,我们直接以 HelloCpp 为例。在引擎目录中选择 HelloCpp项目的工程,就能看到如图2-25所示的界面。
图2-25 HelloCpp 项目
此时读者将会看到一个全新的界面。这是与其他平台完全不同的开发环境了。在跨平台开发中,运用多种开发工具也是没办法的事情啊!在XCode界面中,左侧为项目路径。开发者在此页面下可以看到游戏项目的所有内容。图2-25展示了HelloCpp所需要引入的库。在iOS平台,系统库是以framework的形式引入的。开发者可以点击页面下的“+”按钮进行添加。
而由引擎编译而来的程序库,则是以“.a”为文件后缀的,比如所有游戏项目都需要引入libcocos2dx.a库作为引擎。除此之外读者还要设置项目依赖关系。在图 2-25 中就显示了 HelloCpp 示例项目需要依赖coco2dx库的首先编译。单击“运行(Run)”按钮后,开发者就能看到如图2-26所示的运行画面了。
图2-26 HelloCpp 运行画面
经过前面的介绍,估计读者需要耗费一定的时间,才能将三个平台的开发环境构建完成。为了检测开发环境的可用性,最好的办法就是编译和执行了HelloCpp示例项目。示例项目中的构成与将来开发者建立的游戏项目基本类似。
读者需要注意,因为游戏要在不同的平台上开发,所以就需要单独建立的项目工程。最好的方式,就是将各个平台项目工程放置在一起,正如引擎中的示例项目一样,这样可以方便开发者在跨平台环境中共享资源。所以为了合理统一的管理游戏项目,下面也将会以HelloCpp项目为例进行介绍。它是一个简单而实用的典型。
2.3 引擎中的混合编译
经过了对三个平台的搭建,读者已经对跨平台的工作有所了解。不过这只是表面的内容,在跨平台下的底层,就是多种编程语言的融合。在利用编译器编译这些源代码时,开发者习惯将其称为“混合编译”或者“联合编译”。这就是将多种编程语言融合在一起进行编译的方式。比如前面介绍在Android平台就需要混合编译Java和C++代码。针对跨平台开发,我们将会遇到两种混合编译的情况,接下来分别进行介绍。
2.3.1 Java与C++的混合编译
Android系统是建立在Linux平台之上的,它利用Dalvik虚拟机来运行Java平台应用程序。这些应用程序被转换成紧凑的Dalvik可执行格式(.dex)。该格式适合在内存和处理器速度受限的系统上执行。这里有一个简单的道理。既然Android系统是建立在Linux平台之上,Linux平台本身使用的是C++语言体系,那么使用 C++语言来制作游戏,将会获得最直接的效果。这种方式将为开发者带来高效的运行速度和获得硬件支持的渲染画面。
说明:Android系统的开发就是基于C++语言编写完成的。
以C++为编程语言Android平台的开发方式,早就已经存在了。比如之前安装的NDK工具,就是谷歌为C++语言开发者准备的工具。总体来说,当使用C++语言来制作游戏内容时,需要利用NDK生成SO库。SO库是Linux平台上C++的函数库。在代码中则利用JNI技术来实现C++与Java两种语言之间的连接。
JNI 是 Java Native Interface 的缩写,翻译成中文为“Java 本地调用”。其中的 Native 单词,开发者更喜欢理解为“原生”。JNI并不是Android平台新发明的技术,它在Java技术领域已经存在很久了。从 Java1.1 开始,Java Native Interface(JNI)标准成为 Java 平台的一部分,它允许 Java 代码与其他编程语言的代码进行交互。JNI 是为了连接本地已编译语言,尤其是 C 和 C++而设计的,在使用时,开发者需要遵从约定。
JNI的存在,为开发者创建了一条由Java通向C++的通道。不过这条通道很少为开发者所用。这主要是因为JNI 与Java语言的理念是背道而驰的。Java从产生之初就强调“Build Once,Run Every(一次编译,随处运行)!”。JNI的存在恰好违背这条原则。JNI使用Java需要依赖于本地已编译的代码进行交互,通常就会丧失平台可移植性。
在配置Android开发环境时,我们已经使用过了JNI的方式,读者可能没有注意到。下面就来详细介绍引擎当中是如何让JAVA与C++代码之间互相调用的。下面我们以HelloCPP为例子来详细地讲解。在引擎目录\cocos2d-2.0-x-2.0.4\samples\HelloCpp\proj.android\jni\hellocpp中,存在一个main.cpp文件。
代码2-2 main.cpp文件内容
#include "AppDelegate.h"
#include "platform/android/jni/JniHelper.h"
#include <jni.h>
#include <android/log.h>
#include "HelloWorldScene.h"
#define LOG_TAG "main"
//Android日志调试
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
using namespace cocos2d;
//扩展C语言
extern "C"
{
//JNI加载函数
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
JniHelper::setJavaVM(vm);
return JNI_VERSION_1_4;
}
//C++函数将由Java语言调用
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w,jint h)
{
//初始化游戏引擎
if (!CCDirector::sharedDirector()->getOpenGLView())
{
CCEGLView *view = CCEGLView::sharedOpenGLView();
view->setFrameSize(w, h);
AppDelegate *pAppDelegate = new AppDelegate();
CCApplication::sharedApplication()->run();
}
else
{
ccDrawInit();
ccGLInvalidateStateCache();
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
CCTextureCache::reloadAllTextures();
CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND, NULL);
CCDirector::sharedDirector()->setGLDefaultValues();
}
}
}
代码2-2就是C/C++源代码文件。如果读者熟悉C/C++语言,这个文件看起来非常简单。如果不熟悉的话,建议读者最好找一本C/C++入门书籍来学习一下,这样将会更容易学习后续章节的内容。
说明:如果读者一点不懂 JNI 的机制,也不影响以后的游戏制作,因为引擎中已经为开发者配置了良好的程序接口。
代码2-2 声明了一个C++类本地方法。读者会发现此方法的名字和返回参数有些不一样。根据JNI命名的原则,原本Java类中调用的方法,会被重新命名为java_包名_类名_方法名的格式,方法的参数也会产生相应的变化。这是因为在.h的头文件中,方法要被重新申明。为了区分Java的数据类型在C/C++中表现,代码中就将原本类型变为了j类型。表2-3列出了JNI所支持的基本数据类型。
表2-3 JNI数据类型
JNIEnv是一个JNI接口指针,它事实上是由函数表组成的,开发者可以使用JNIEnv来访问java对象。它为Java和C/C++之间的方法交互提供了环境。在编写JNI Native方法时,一定要注意无论是java基本类型还是对象,都不能在 C/C++中直接使用,必须要转成相对应的类型,否则将会导致内存访问错误。因为使用JNI本地化原生调用方法,在Java语言与C/C++语言混合编译的情况下,程序的错误检查机制变得宽泛了,所以在实际开发当中,我们最好尽量少使用JNI调用方式,以便避免差错。
注意:在代码中需要引入<jni.h>,它是使用JNI调用机制必须引用的头文件。
刚刚看到了在main.cpp中一个初始化引擎的函数。此函数将由Java代码进行调用。它是用来初始化游戏画面的显示窗口的。下面来看引擎的源代码中是如何进行调用的。在引擎目录\cocos2d-2.0-x-2.0.4\cocos2dx\platform\android\java\src\org\cocos2dx\lib下,存放了许多的Java文件,这些文件就是通过JNI来调用C++函数的代码文件。代码2-3展示了nativeInit的调用方法。
代码2-3 nativeInit的调用代码
private static native void nativeInit(final int pWidth, final int pHeight);
@Override
public void onSurfaceCreated(final GL10 pGL10, final EGLConfig pEGLConfig) {
Cocos2dxRenderer.nativeInit(this.mScreenWidth, this.mScreenHeight);
this.mLastTickInNanoSeconds = System.nanoTime();
}
上述代码申明了Java语言中的nativeInit函数,然后在onSurfaceCreated函数中进行了调用。这之后就会执行C++代码中的Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit函数。经过JNI的连接,就完成了Java 语言访问 C++语言的过程。这只是一个简单的函数例子。在引擎中还有很多应用方式,有时还需要传递参数或者对象。这都是需要 JNI 作为两者之间的通道来实现的。在此就不深究了,有兴趣的读者可以查看目录下其他的源代码。
说明:此部分内容为引擎中的源代码,是无需开发者进行修改的。在此进行介绍只是为了让读者加深理解,明白其中的奥妙所在。
当开发者使用Cocos2D-X引擎进行Android平台开发时,使用Java语言编码是不可避免的,因为大多数AndroidSDK都是Java版本的。虽然引擎已经为开发者完善了JNI 调用功能,但是当游戏中有特殊需求时,还是需要开发者来编写代码的。Java 语言与 C++语言混合编译的开发方式也成为了跨平台技术的一个门槛。读者需要在此多费心血,好好钻研。
注意:C++语言与 Java 语言的编译是由不同编译器完成的,在代码调试上也增加了一些难度,很难在编译时检查出调用错误。
2.3.2 Objective-C与C++的混合编译
iOS 平台是专属于苹果公司的。开发者如果想要开发 iOS 或者 Mac 系统上的应用程序,就需要使用Objective-C编程语言。为了介绍方便,以后的内容就简写为OC。大多数苹果提供的程序库都是基于OC的。这也是为什么Cocos2D引擎的最初版本也是OC编写的原因。OC是来自于C语言的改良版本,被看作是扩充C语言的面向对象编程语言。因为与C++具有相同的根源,所以混合编译时就相对的容易和灵活,在XCode 当中,就完全可以实现而无需加入第三方工具或者编译器。甚至于开发者可以在一个文件中编写两种语言。编译器允许用户在同一个源文件里自由地混合使用 C++和 Objective-C ,混编后的语言叫Objective-C++。开发者可以在Objective-C应用程序中使用已有的C++类库,两种语言之间可以互相调用对象以及函数。接下来,我们通过引擎中的一段代码来熟悉OC与C++混合编译的方式。
说明:尽量避免在一个文件中写入两种编程语言的类声明,这很容易造成混乱,不宜阅读。
在HelloCpp项目路径\cocos2d-2.0-x-2.0.4\samples\HelloCpp\proj.ios下,存放可以混合编写的代码文件。这些文件的后缀为“.mm”。XCode编译器允许开发者在同一个源文件里自由地混合使用C++和OC,混编后的语言叫Objective-C++,简称为OC++。编译器就是通过文件后缀名来标识OC++文件的。在OC++文件中,可以用C++代码调用方法,也可以从Objective-C调用方法。在两种语言里对象都是指针,可以在任何地方使用。C++类可以使用OC对象的指针作为成员变量,OC类也可以用C++对象指针做实例变量。
AppController.mm文件就有一段这样的代码。
代码2-4 OC与C++混合编写
//引擎应用单例对象
static AppDelegate s_sharedApplication;
//应用启动函数
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//在设备显示窗口中添加游戏画面视窗
window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
EAGLView *__glView = [EAGLView viewWithFrame: [window bounds]
pixelFormat: kEAGLColorFormatRGBA8
depthFormat: GL_DEPTH_COMPONENT16
preserveBackbuffer: NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
//使用RootViewController 来管理EAGLView
viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
viewController.wantsFullScreenLayout = YES;
viewController.view = __glView;
//将RootViewController设置到设备窗口显示
if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
// warning: addSubView doesn't work on iOS6
[window addSubview: viewController.view];
}
else
{
// use this method on ios6
[window setRootViewController:viewController];
}
[window makeKeyAndVisible]; //显示窗口
[[UIApplication sharedApplication] setStatusBarHidden: YES];//隐藏状态条
cocos2d::CCApplication::sharedApplication()->run();//运行游戏内容
return YES;
}
//应用进入待机时调用函数
- (void)applicationWillResignActive:(UIApplication *)application {
cocos2d::CCDirector::sharedDirector()->pause();//暂停游戏
}
//应用恢复运行时调用的函数
- (void)applicationDidBecomeActive:(UIApplication *)application {
cocos2d::CCDirector::sharedDirector()->resume();//恢复游戏
}
//应用进入系统后台之后,释放资源
- (void)applicationDidEnterBackground:(UIApplication *)application {
cocos2d::CCApplication::sharedApplication()->applicationDidEnterBackground();
}
//将要进入后台时调用函数,可回退内容
- (void)applicationWillEnterForeground:(UIApplication *)application {
cocos2d::CCApplication::sharedApplication()->applicationWillEnterForeground();
}
代码2-4的内容来自于AppController.mm,列出了其中部分的函数。此文件是引擎中应用开启的类。它负责管理游戏应用运行周期。在这里作为例子,主要是为读者介绍OC++的编程方式。在代码中application:函数内容就是一个纯粹的OC编码语言。函数调用都是通过“[]”来实现的。而代码中其他的函数,读者细心观察就会发现 C++“箭头”函数调用方法。这就是 OC++的魅力所在。它可以允许两种语言在一个源代码文件中自由调用。从这一点来看,OC与C++混合编译具有较高的自由度,只需将文件变为OC++的“.mm”格式即可。
注意:OC++没有为OC类增加C++的功能,也没有为C++类增加OC的功能。例如,你不能用OC语法调用C++对象,也不能为 OC对象增加构造函数和析构函数,也不能将this和 self互相替换使用。类的体系结构是独立的。C++类不能继承OC类,OC类也不能继承C++类。另外,多语言异常处理是不支持的。也就是说,一个OC抛出的异常不能被C++代码捕获,反过来C++代码抛出的异常也不能被OC代码捕获。
2.4 引擎的起点
经过前面内容,我们已经在三个不同的平台编译并运行了 HelloCpp 项目。此项目作为读者理解Cocos2D-X 引擎来说是一个很好的开始,在项目中包含了大多数引擎支持平台的代码以及资源。此示例项目的结构,对开发者来说有很大的参考价值。它很好地解决了不同开发环境下项目工程、代码和资源共享的问题。因此,为了为读者打下良好的基础,十分有必要对此示例项目进行详细的介绍。只有做好基本工作,以后才能应对更复杂的情况。
接下来继续以HelloCpp示例项目为例,为读者介绍更深层次的内容。读者是否有想过一款游戏产品是如何在各个平台运行起来的?这是一个很关键的问题。它揭示了引擎运行游戏产品的起始点。换句话来说,读者需要明白在各个平台上引擎是如何启动的,游戏项目是如何运行的,这一切都是从哪里开始的。
2.4.1 应用程序入口
有过编程经验的人,对于“程序入口”的概念绝对不会感到陌生。“程序入口”是一种程序员间的口语化表达。它是指一个程序从哪里开始执行。说得更直白一些,那就是应用程序执行的第一行代码在哪里,这就是程序入口。对于不同平台上的应用程序,程序执行的入口都会不同。就算同一平台,不同的编程语言其程序入口也是不一样的。面对这样的情况该如何解决呢?Cocos2D-X引擎中已经帮助开发者解决了此问题。它对不同的程序接口提供了良好封装。对于引擎开发者来说,只需要应对一个开始点即可。
图 2-27 展示了在 PC平台上的 HelloCpp 项目,读者可以看到两个目录下的源代码,其中win32就是基于Windows应用程序的入口。当系统平台转变时,应用程序的入口也会转变。win32目录中的代码也不再需要。只不过经过Cocos2D-X引擎的良好封装,为开发者隐去了不同平台入口转换的细节。Classes目录下的内容则是实际游戏开发内容。因为它是基于引擎的编码,所以将存在于多个平台之上。由于引擎最早的版本来自于OC语言风格的应用程序,所以在程序接口的命名以及函数定义上,都留有iOS应用程序的风格。下面代码2-5展示了PC平台应用程序入口代码,来自于main.cpp。
图2-27 PC 平台的HelloCpp 项目内容
代码2-5 PC平台应用程序入口
#include "main.h"
#include "../Classes/AppDelegate.h"
#include "CCEGLView.h"
USING_NS_CC;
//PC平台应用程序入口
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
//创建应用对象
AppDelegate app;
CCEGLView* eglView = CCEGLView::sharedOpenGLView();
eglView->setFrameSize(2048, 1536);
//设置缩放比例
eglView->setFrameZoomFactor(0.4f);
return CCApplication::sharedApplication()->run();
}
代码2-5所示的函数就是标准的Windows系统下应用程序入口函数。函数的内部代码作用就是唤醒引擎,开始运行游戏。再来看看iOS平台程序入口文件的内容。
代码2-6 iOS平台应用程序入口
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
//初始化自动释放池
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//启动应用程序
int retVal = UIApplicationMain(argc, argv, nil, @"AppController");
[pool release];
return retVal;
}
代码2-6来自项目路径如下。
\cocos2d-2.0-x-2.0.4\samples\HelloCpp\proj.ios\main.m
这就是iOS应用程序的入口,同样是由引擎为开发者准备妥当了。这段代码也是只有在iOS项目中才能发挥作用。
代码2-7 Android平台应用程序入口
package org.cocos2dx.hellocpp;
import org.cocos2dx.lib.Cocos2dxActivity;
import android.os.Bundle;
//Android应用程序对象
public class HelloCpp extends Cocos2dxActivity{
//程序启动入口
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
//引入C++库
static {
System.loadLibrary("hellocpp");
}
}
代码2-7来自于HelloCpp.java文件,路径如下。
\cocos2d-2.0-x-2.0.4\samples\HelloCpp\proj.android\src\org\cocos2dx\hellocpp
读到这里,不知读者是否有恍然大悟的感觉?为了让开发者能够专注于游戏内容的开发,而不是再针对不同的平台进行适配,这只是引擎提供的跨平台功能中很小的一部分内容。除此之外,引擎还要融合各个平台上操作、显示、文件等功能,为开发者提供统一易用的程序接口。上述的程序接口是每个平台或者系统的入口。引擎简化后,还存在其自身应用的入口。这就是前面提到的Class目录下的内容。接下来,让我们熟悉引擎中应用的生命周期。
2.4.2 引擎应用入口
在HelloCpp项目路径Class中,存在一个AppDelegate类文件。此文件的命名是OC编程语言的风格。在此代码文件中,就是与引擎应用生命周期有关的函数。所谓的生命周期,就是指游戏应用开始与结束的过程。在此过程中,引擎应用会存在许多的状态。代码2-8列出了此类的具体内容。
代码2-8 引擎应用的生命周期
#include "AppDelegate.h"
#include "HelloWorldScene.h"
#include "AppMacros.h"
//使用cocos2d-X命名空间
USING_NS_CC;
AppDelegate::AppDelegate() {//构造函数
}
AppDelegate::~AppDelegate() {//析构函数
}
//应用开启的入口
bool AppDelegate::applicationDidFinishLaunching() {
//初始化场景导演
CCDirector* pDirector = CCDirector::sharedDirector();
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
//设置场景窗口
pDirector->setOpenGLView(pEGLView);
//设置屏幕朝向
pEGLView->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height,kResolutionNoBorder);
//设置窗口大小
CCSize frameSize = pEGLView->getFrameSize();
//根据窗口大小来限制图片
if (frameSize.height > mediumResource.size.height)
{
CCFileUtils::sharedFileUtils()->setResourceDirectory(largeResource.directory);
pDirector->setContentScaleFactor(largeResource.size.height
/designResolutionSize.height);
}
else if (frameSize.height > smallResource.size.height)
{
CCFileUtils::sharedFileUtils()->setResourceDirectory
(mediumResource.directory);
pDirector->setContentScaleFactor(mediumResource.size.height
/designResolutionSize.height);
}
else
{
CCFileUtils::sharedFileUtils()->setResourceDirectory(smallResource.directory);
pDirector->setContentScaleFactor(smallResource.size.height
/designResolutionSize.height);
}
//开启FPS
pDirector->setDisplayStats(true);
//设置屏幕刷新率为1.0/60
pDirector->setAnimationInterval(1.0 / 60);
//创建场景
CCScene *pScene = HelloWorld::scene();
//运行场景
pDirector->runWithScene(pScene);
return true;
}
//当应用进入待机状态时调用的函数
void AppDelegate::applicationDidEnterBackground() {
CCDirector::sharedDirector()->stopAnimation();//停止动画
}
//当应用从待机恢复
void AppDelegate::applicationWillEnterForeground() {
CCDirector::sharedDirector()->startAnimation();
}
上述代码展示了三个函数,都是与引擎中应用程序运行状态相关的。因为通常引擎运行时,只会维持一个游戏应用,所以引擎中没有提供多款应用同时运行的情况。这种情况几乎是不存在的,所以当引擎启动之后,就会执行唯一的游戏应用。引擎将会调用applicationDidFinishLaunching()函数作为游戏应用开启的入口。有过iOS应用开发经验的,对于此函数名应该不会陌生。它与iOS平台应用程序入口函数名类似,只不过此处为C++语言编写的函数。
在applicationDidFinishLaunching()函数中,就是进行游戏应用的初始化,主要内容为游戏绘制以及画面的初始化。内容的细节在后续章节再为读者进行详尽的介绍。此处主要是为读者介绍引擎应用的入口,也就是引擎应用的生命周期开始的地方。在引擎应用运行的状态中,还存在一个待机状态。这就是当手机来电话或者退入后台时,游戏进入了暂停状态,同时还要暂停音乐的播放。
引擎应用的入口适用于各个平台。在不同平台之上,引擎会管理 Application 类的对象作为游戏应用的生命周期,为开发者省去跨平台的细节,正如图 2-28所示的结构。
图2-28 引擎应用的结构
作为引擎的使用者,只需在引擎应用中编写游戏内容即可。此时读者就能够体会到Cocos2D-X引擎的魅力了。有了它的存在,开发者省去很多的工作,这仅仅是开始,我们还没有接触到与游戏有关的内容呢。在读者学习的过程中,读者会逐渐领略到引擎中完善而易用的功能。
2.5 丰富的示例程序
在Cocos2D-X引擎包中,提供了多个示例程序。在开源项目中,示例程序发挥着重要作用。它可以帮助开发者学习和使用引擎。示例程序也可以用来测试引擎的功能。另外,为了减少工作量,有些开发者还习惯在示例程序的基础上开发游戏。无论如何,作为Cocos2D-X引擎的使用者,读者都一定要看看示例程序的内容。它能够帮助你快速地掌握引擎的用法。前面内容已经以HelloCpp项目为例,为读者介绍了许多引擎相关的内容。此项目算是所有示例项目中最简单的一个了。下面介绍其他的示例项目供读者熟悉引擎。
2.5.1 TestCpp示例项目
好的引擎,会提供一个完整系列的功能示例。Cocos2D-X 引擎之所以能得到很多人的喜爱,其重要的原因是它提供了丰富而易学的示例。TestCpp示例项目中提供了超过43个引擎功能展示的样例。毫不夸张地说,如果读者将所有的样例代码研究明白了,对于引擎的使用,就会进入驾轻就熟的状态。哪怕不看示例的源代码,只是运行示例来观看效果,这也是一个非常不错的引擎展示程序。
下面我们以PC平台为例,用VS工具选中项目编译然后运行。示例项目的运行画面,读者并不陌生。在任何平台示例项目的选择界面,读者都可以进行选择,观看引擎中各种功能的展示。这些功能都可以用在游戏产品当中。至于具体使用的方法,在后续的章节中,将会逐个为大家详细介绍。
2.5.2 脚本示例项目
Cocos2D-X引擎支持使用Lua和JavaScript脚本开发的方式。这无疑又为开发者降低了游戏制作的难度。脚本与编程语言相比,更加自由灵活、简单易用。在一些游戏制作团队中,脚本编写的工作是交由策划人员完成的。脚本语言除了好用之外,还有许多其他优点。随着游戏复杂度提升,脚本支持已经变成游戏产品必需的内容了,所以在Cocos2D-X引擎的示例项目中提供了脚本示例程序。图2-29就是TestLua中一个样例功能展示。
图2-29 TestLua 样例功能
TestJavascript和TestLua示例项目就是将TestCpp重新用脚本语言实现了一遍。一方面是为了展示引擎的功能,另一方面是为向开发者证明引擎对于脚本语言也提供了完善的支持。这两个项目中所有内容都是通过脚本语言来实现的。读者可以在项目资源目录中,找到对应的源代码文件。在Class目录下则只有AppDelegate类文件,这只是引擎应用的开始入口,在此文件中将会加载Lua或者JavaScript脚本文件。
2.5.3 MoonWarriors示例项目
这是一款飞行射击类的游戏。其实在网络中还有很多来自开发者分享的游戏,它们都是使用Cocos2D-X引擎制作完成的。此款游戏最早是用来展示 HTML5 引擎版本功能的。后来为了统一引擎版本,验证脚本功能才集成在引擎当中。读者可以运行示例项目,来体验一下游戏的乐趣。虽然是示例项目,但是单纯作为射击类游戏来玩,也是很不错的。小心可别玩上瘾!图2-30展示了示例项目的运行画面。如今此款游戏已经能够在多个终端设备以及浏览器中稳定运行了。
图2-30 MoonWarriors示例项目
此示例项目另一大特点,就是游戏编码完全使用JavaScript脚本语言。这也是为了向开发者展示引擎整合方向的重要依据。为了减少多版本引擎带来的额外工作,引擎组人员通过JavaScript脚本语言建立了最高层次。开发者只需要在此层次编写代码,然后游戏产品就可以在更多的平台上运行。与其他编程语言相比,JavaScript拥有众多的开发者。此举将会为游戏业带来更多的新生力量,也能够让Cocos2D引擎继续辉煌。
2.6 本章小结
经过这一章,读者已经快速地进入到了Cocos2D-X引擎开发。在配置开发环境的过程中,因为引擎的版本以及其他配套工具都在升级和更新中,所以很有可能会遇到各种版本不兼容以及缺少文件的情况。此时,笔者建议大家借助网络搜索来寻求答案。跨平台的开发环境配置工作略有繁琐,主要依靠经验。一旦完成了环境搭建,就很少会再变更。所以说搭建开发环境是很多新人要应对的第一道难关。
说明:笔者也曾遇到过很多的错误,也是硬着头皮一点点解决。对于激情满满的投入游戏开发的新手来说,可别还没看到游戏的样子,就轻易放弃了。
在构建开发环境的过程中,我们已经运行了许多Cocos2D-X引擎中的示例项目。这是一个很好的铺垫。因为读者已经领略到Cocos2D-X引擎的强大功能,所以在之后的学习中将会有更深刻的印象。现在在示例项目中看到的效果,都将会在后续章节中进行详细的介绍。
对于本章节所介绍的各个平台实现细节,其实已经超出了引擎使用者的范畴。不过为了让读者有更深入的了解,不妨介绍得更透彻一些。希望通过本书读者不是简单学会使用Cocos2D-X引擎,而是深知引擎的运行机制,将来成为能够提供引擎更新代码或者修正引擎错误的高手。
在接下来一章中,读者将会接触到引擎中最核心的部分:渲染功能。对于任何一个游戏引擎来说,渲染功能永远是排在第一位的。它被用来展示游戏丰富的内容,将精美的画面呈现在玩家眼前。通常这也是游戏制作的起点。所以说,读者马上就要领略到游戏制作技术了。作为一款优秀的游戏引擎Cocos2D-X在渲染方面相比其他引擎毫不逊色。它能够帮助开发者合理高效地绘制游戏界面,同时还能呈现出绚丽多彩的效果。