Cocos2d-x游戏编程——C++篇(txt+pdf+epub+mobi电子书下载)


发布时间:2020-08-15 12:16:11

点击下载

作者:徐飞

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Cocos2d-x游戏编程——C++篇

Cocos2d-x游戏编程——C++篇试读:

前言

随着智能手机的普及,相关的应用犹如雨后春笋般涌现。其中,游戏扮演着一个重要的角色,和端游、页游形成三足鼎立之势。例如,卡牌类游戏我叫 MT、大掌门、放开那三国、名将无双和萌江湖等;RPG 类游戏天龙八部 3D、仙剑奇侠传、全民奇迹和秦时明月等;跑酷类游戏神庙逃亡、天天酷跑、熊大快跑 2015、爸爸去哪儿 2、奔跑吧兄弟、天天风之旅等;塔防类游戏植物大战僵尸2、保卫萝卜等;三消类游戏PopStar、天天星连萌、天天爱消除和开心消消乐等;音乐类游戏节奏大师、乐动达人、全民炫舞和乐动魔方手机版(jukebeat);街机类游戏捕鱼达人系列、拳皇2014和狂野飙车8:急速凌云等不乏精品。

目前市面上两款比较火的手机游戏开发引擎要属Unity3D和Cocos2d-x,前者多用于3D游戏的开发,后者在3.0版本之前是一款2D游戏开发引擎,在3.0后引入了对3D开发的支持,随着版本的升级,3D 开发功能也越来越完善。上面介绍的游戏中,有很多是使用Cocos2d-x 引擎开发的。例如,我叫 MT、大掌门、秦时明月、保卫萝卜、开心消消乐、放开那三国、仙剑奇侠传和捕鱼达人系列等。

本书以Cocos2d-x 引擎为基础,以C++作为开发语言,内容涉及从手机游戏开发到发布各个方面的知识,主要可以分为 4 篇:基础篇、3D 篇、网络篇和高级篇。其中,各个篇的内容如下。

1.基础篇

基础篇共6章,各章的具体情况如下:

第1章介绍引擎的基础知识,内容包括Cocos2d-x引擎的组织结构、Hello World项目的创建、版本变化和C++11标准中的一些知识。

第 2 章介绍引擎中的一些基础类和常用类,分为 6 个部分讲解:Director 类、高级节点类(如Scene、Layer、Sprite等)、文字相关类(如LabelTTF、Label和Text类等)、菜单类Menu、列表类和一些其他常用类(如SpriteBatchNode、Scale9Sprite和EditBox等)。

第 3 章介绍动画,动画有多种类型,如瞬时动画、延时动画、缓冲动画、Speed 动画、Follow动画、ActionTimeLine动画和一些特效动画。

第 4 章介绍引擎中的定时器和事件响应机制。其中,定时器有全局和 Node 之分,事件响应负责处理界面单击事件等操作。

第5章介绍粒子系统,分为普通的2D粒子特效和3D粒子特效。

第6章介绍引擎中的声音,有两种方式:SimpleAudioEngine和AudioEngine。

2.3D篇

3D篇有3章,各章的具体情况如下:

第7章介绍引擎中的3D知识,内容涉及模型、动画、相机、光照和碰撞检测等。

第8章讲解引擎中的数学知识,内容有向量、矩阵、四元素、Size类和Rect类。

第9章从GLSL语言基础知识、Cocos2d-x着色相关类、2D和3D特效4个方面介绍可编程管道着色。

3.网络篇

网络篇有2章,各章的具体情况如下:

第10章介绍HTTP编程,内容涉及libcurl和pthread库的基础知识、游戏中基本的数据通信、文件的上传和下载,以及C++11标准中的线程库std::thread。

第11 章介绍Socket 编程,内容有select 函数介绍、Socket 编程中的一些常用函数和数据通信的实现。

4.高级篇

高级篇有5章,各章的具体情况如下:

第12章介绍游戏中的适配知识,从资源、设计和屏幕分辨率三个方面来讲解。

第 13 章介绍在 Android 平台下怎样实现代码和资源的自动更新,分为 3 方面的知识:怎么实现代码和资源的管理、代码文件更新和资源文件更新。

第14章介绍游戏中资源的加密和解密操作,有2.x版本和3.5版本之分。

第 15 章介绍跨平台编译到 iOS 平台;iOS 平台下一些功能的开发,如经纬度、照相和应用内购买;真机调试和游戏的发布。

第 16 章介绍跨平台编译到 Android 平台;C++和 Java 语言的互调;该平台下一些功能的开发,如经纬度、照相等。

本书中涉及作者编写的类以“XJ”开头,和引擎2.x版本中的“CC”功能一样,只是一种命名的方式,前 9 章的知识都是基于引擎 3.5 版本编写的,在后几章知识的讲解中以引擎2.2.3 版本为基础,但这部分涉及引擎的知识不多,大部分在光盘中都有提供 2.2.3 和 3.5 两个版本的代码,读者在阅读的过程中可以对照参考,如果读者仔细阅读了第 1 章的知识,理解这两个版本的代码应该不是什么难事。

感谢我的研究生导师,北京理工大学的王全玉老师,是他把我带进虚拟现实的世界,让我毕业后就能从事游戏开发的工作;感谢电子工业出版社的王敬栋和张迪两位老师,没有二位老师的帮助,该书就不会顺利出版;感谢我的爷爷奶奶和父母,是他们把我抚育成人;感谢我亲爱的妻子和可爱的儿子,在我创业期间给予我无微不至的关怀和理解。

本书通过 16 章讲解游戏的编写,但由于作者水平有限,书中难免会存在缺点和不足,殷切希望广大读者通过电子邮件(cocos2dx_net@163.com)批评指正。徐飞2015年5月3日于深圳  第1章 Cocos2d-x基础知识

Cocos2d-x 是一个跨平台且开源的游戏引擎,诞生于 2010 年。它允许开发人员使用Windows和Mac桌面系统进行开发和调试,可选择C++、Lua或JavaScript作为开发语言,游戏开发完成后,可部署到 iOS、Android 和 Windows Phone 等平台,实现了一套代码,多个平台运行,大大节约了开发时间和成本。

引擎本身使用 C++语言开发,基于 OpenGL ES 渲染引擎,除了渲染部分外,还封装了2D 物理引擎、网络通信、声音引擎等,是一个比较完整的游戏开发引擎。它提供了丰富的API集合,供开发者使用,且API文档浅显易懂,开发人员很容易入手。

引擎自从发布后,经历了多个版本的变化。其中,最大的是从 2.x 到 3.x 版本的变化。在3.x版本中,加入了3D编程的支持、新的声音引擎、增加了3D粒子特效(3.5版本中加入)和引入了C++11标准等,也遗弃了2.x版本中一些内容,如pthread线程库、CCString类等。本章将先介绍引擎最新版本关于框架的一些知识和怎么创建一个HelloWorld程序,然后再介绍引擎从2.x到3.x版本发生了哪些变化,最后介绍C++11标准的一些知识。1.1 引擎组织结构

读者可以到Cocos2d-x的官网(www.cocos2d-x.org)获取源代码,它提供了最近几个版本源文件的下载地址。在写本书时,引擎的最新版本是3.5,所以本书大部分知识都是基于这个版本讲解的,下载完成后是一个zip压缩文件,解压出来后,可以看到如图1-1所示的目录结构。

从图1-1中可以看出,共11个目录,下面介绍其中一些重要的目录:图1-1 Cocos2d-x 3.5目录结构

· build:Win32 平台下的工程文件,用 VS2012 打开 cocos2d-win32.vc2012.sln文件,可直接对引擎源码和例子进行编译。

· cocos:该目录下包括了引擎的核心代码文件,如 2D、3D、声音(audio)、网络(network)、物理(physics)、数学库(math)、渲染(renderer)及与平台相关的一些代码文件等。

· extensions:资源更新管理、UI 控件和 3D 粒子特效(Particle3D)相关类文件存放的地方,其中控件有ScrollView、TableView等。

· external:包含一些外部库,如物理库(Box2D和chipmunk)、curl库、json文件解析库、XML文件解析库(tinyxml2)、sqlite3和unzip等。

· templates:存放着创建C++和lua项目的模板类和资源。

· tests:包含C++和Lua项目的Samples。

· tools:项目创建、lua bindings等相关工具。

对引擎的目录结构大致了解后,进入 build 目录下,用 VS2012 打开 cocos2d-win32.vc2012.sln这个文件,在解决方案标签下可以看到如图1-2所示引擎的工程结构。

从图1-2中可以看出,在解决方案下,一共有8个工程,它们各自的功能如下:

· libbox2d:2D物理库。

· libSpine:角色骨骼动画库。

· libcocos2d:Cocos2d-x引擎库,引擎的核心代码都在该工程下。

· libluacocos2d:引擎对lua支持库。

· cpp-tests:C++语言编写的Samples工程。

· cpp-empty-test:C++语言空工程。

· lua-tests:lua语言Samples工程。

· lua-empty-test:lua语言空工程。

对整个解决方案进行了解后,重新编译它,成功后,把cpp-tests工程设为启动项,运行该项目,可以看到C++实例工程项目的界面,如图1-3所示。图1-2 Cocos2d-x项目结构图图1-3 cpp-tests工程运行界面

cpp-tests 工程是引擎提供的 Samples,几乎囊括了它各个方面知识的运用,这对于初学者是一份很好的学习材料。引擎提供的源代码项目编译成功后,是生成属于我们自己游戏项目的时候了。前面讲过,引擎根目录的 tools 目录下有创建项目的工具,在创建项目之前要用到 Python 这个脚本工具,所以到 Python 的官网下载一个,使用 2.x 版本的,最新版本是2.7.9,下载完成后安装即可,然后使用 Windows 的命令行工具,进入“tools\cocos2d-console\bin”目录下,输入如下命令:

对于这条命令的解释,将有专门的章节讲述,在这里我们只要了解,执行完这条命令后,将会在bin目录下创建一个名为mygame的项目,这是一个HelloWorld的项目,该项目的目录结构如图1-4所示。

该工程的目录结构解释如下:

· Classes:项目的类文件,以后我们自己写的C++文件都放到该目录下。

· Resources:项目的资源文件,图片、声音、字体等都放在该目录下。

· cocos2d:引擎相关文件。

· proj目录:平台相关目录。

了解完mygame的目录结构后,在proj.win32目录下找到解决方案mygame.sln,双击打开它,编译执行后,可以看到如图1-5所示的界面。图1-4 mygame目录结构图1-5 mygame项目的HelloWorld界面

到此,本节分析了引擎的组织结构和怎么去创建一个属于我们自己的 HelloWorld 项目,在本书其他章节的代码讲解中,将以这个项目为基础,大部分知识的讲解都建立在这个项目上。1.2 从2.x到3.x的变化

引擎在 3.0 后,在保持引擎整个框架结构不变的前提下,较前一个版本还是发生了比较大的变化,其中包括类名、回调函数、事件响应机制等,并且增加了 C++11 标准的一些知识。在 2.x 中以宏出现的功能函数和结构,在 3.x 版本中都通过类的封装来实现,这样使得程序更加简洁,使初学者更加容易理解。在本小节中,将介绍主要的一些变化,使 2.x 编程者很快过渡到3.x版本。1.2.1 类名变化

引擎中,各个类对应的头文件(.h)和执行文件(.cpp)虽然在命名上没有变化,但是里面定义的类在命名上发生了变化,去掉了之前的 CC 前缀。例如,要在界面上显示一张图片,实现程序如程序片段1-1所示。程序片段1-1 显示图片代码

代码中,setPosition函数是设置图片的位置,setAnchorPoint是设置图片的锚点,然后通过addChild函数把这张图片加入场景中进行渲染。这些函数,在后面的章节中将会介绍。在这里,我们看到创建图片的类从CCSprite 变成了Sprite,去掉了CC 前缀,这里只是介绍了Sprite的变化,还有CCDirector变成了Director、CCScene变成了Scene等。1.2.2 单件类变化

单件类中对于用来获取它的实例函数,由share方式变成了get方式,在2.x中的获取和销毁实例方法如表1-1所示。表1-1 2.x中单件类方法

可以看出,在 2.x 中的每个单类,获取和销毁它对应实例的方法都不一样。而在 3.x 中统一为:获取实例方法是 getInstance,销毁实例方法是 destroyInstance。不过,引擎为了迎合2.x程序员的习惯,在3.x中同样可以使用2.x的调用方式。1.2.3 宏定义与结构的变化

宏定义与常量的变化如表1-2所示。表1-2 宏定义与常量对比

2.x版本中的CCPoint、CCSize、CCRect类在3.x中对应的类是Vec2、Size和Rect类,Vec2 由一个点组成,包括两个坐标(x,y);Size 类也由两个成员组成(width,height),分别表示宽和高;而Rect类中的两个成员(origin,size),第一个参数是Vec2类型,表示这个矩形左下角的位置,而第二个参数是Size类型,表示这个矩形区域的宽和高。

结构变化如表1-3所示。表1-3 结构变化

把结构封装成类(在 C++中,结构也是类,只是 struct 默认的访问控制域是 public,而class 默认的是 private),那么常量和功能函数可以直接在类里面定义,不用定义多个宏和全局函数来实现相应功能。1.2.4 回调函数变化

在 2.x 中,回调函数使用函数指针的方式来实现,所有回调的定义如程序片段 1-2所示。程序片段1-2 回调机制定义

片段中的 schedule_selector 用在 update 等函数的定义中,以 callfunc 开头的宏用在动画执行中,用来定义瞬时动画,而 menu_selector 用在菜单响应事件上。这几个类指针和宏定义在实际运用中比较常见,读者在运用过程中会经常用到。

上面介绍了2.x中的定义,而在3.x中,引入了C++11标准中的bind函数,只有4个宏定义来实现,其定义如程序片段1-3所示。程序片段1-3 3.x回调宏定义

在3.x中,使用bind函数的功能,通过回调函数的参数个数来决定使用哪个宏,而不用区分哪个是对应菜单回调、哪个是update回调等。1.2.5 事件响应机制的变化

在2.x中,事件的响应机制是,在要使用触摸事件的类中调用setTouchEnabled激活触摸事件,然后调用 registerWithTouchDispatcher 函数设置目标触摸或标准触摸,然后用表 1-4中的函数响应触摸事件。表1-4 2.x事件响应函数

而在3.x中,使用bind函数来实现。其中,EventListenerTouchOneByOne对应2.x的目标触摸,而 EventListenerTouchAllAtOnce 类对应的是标准触摸事件。例如,要使用触摸事件,则在代码中加入如程序片段1-4所示的代码。程序片段1-4 3.x中触摸事件

其中,_eventDispatcher是EventDispatcher类型指针,CC_CALLBACK_2是一个宏,前面小节中有过介绍,它表明绑定的函数可以带两个参数,代码中的 onTouchesBegan、onTouches Ended等函数,它们是ccTouchesCallback类型的,而该类型的定义如下:

function 是一个函数模板对象,可以把同类型的函数等可调用对象赋值给它,然后通过该函数对象变量来调用被赋值的函数。

知识点

在 C++中,有几种可调用对象,其中包括函数、函数指针、Lambda 表达式,bind 绑定的对象,重载了函数调用操作符的类。1.3 Cocos2d-x中的C++11知识

自从 C++标准委员会发布 C++11 标准后,引进了一些新的知识点,如 auto 指针、Lambda表达式、bind和function函数等,Cocos2d-x引擎把这些知识点也加入了引擎的编写过程中。1.3.1 Lambda表达式

在 C++中,有许多算法用来对比输入序列,如 find_if、sort、for_each 等,这些算法第三个参数断言(predicate)既可以是“<;”或“==”操作符,也可以是一个能调用的对象(函数、函数指针等)。这些断言普遍的一个特点是,要么带一个参数,要么带两个参数。例如,find_if算法中的断言是带一个参数的,如果要在一个vector容器中查找第一为奇数的值时,其实现程序如程序片段1-5所示。程序片段1-5 find_if用法

代码中阐述了 find_if 函数的用法,参数中的断言是带一个参数的。而 sort 算法中的断言,它的实现带两个参数,如程序片段1-6的例子。程序片段1-6 sort用法

有时,我们想传递多于断言参数个数的时候,如在find_if算法中,要求在list容器中查找第一个奇数,且它的值大于3时,IsOdd断言就无法实现了。

为了解决这类问题,C++中引入了 Lambda 表达式,它是一个可调用对象,可以认为它是一个未命名的内联函数,有返回值、参数列表和函数体等,其类型如图1-6所示。图1-6 Lambda表达式原型

Lambda 表达式中除了捕获列表外,其他的三个部分和普通函数类似。其中,参数列表和返回类型可以省略,其他两个必须存在,一个简单的例子如程序片段1-7所示。程序片段1-7 Lambda表达式例子

这段代码执行后,会在控制台上打印出“Hello World”的字样。如果函数体中只有一个带return的语句,那么表达式可以推断出返回类型,否则将返回void类型。

1.捕获列表

捕获列表捕获的是调用该表达式函数内的局部非静态变量,对于那些函数内的静态变量和定义在函数外的变量,Lambda表达式可以直接使用。捕获列表的类型如表1-5所示。表1-5 捕获类型

有了捕获列表之后,就可以解决IsOdd断言问题了,实现方式如程序片段1-8所示。程序片段1-8 Lambda应用

上述Lambda表达式中捕获了odd变量,返回类型是bool。

编译器在解释 Lambda 表达式时,会解释成一个未命名类的未命名对象,该类包含了一个重载函数调用操作符的函数,如果在捕获列表中包含有值捕获参数时,那么在该类中会有一个相对应的成员参数,如上面的 Lambda 表达式中,编译器会解释类似,Lambda 表达式对应的类如程序片段1-9所示。程序片段1-9 Lambda表达式对应的类

默认情况下,Lambda表达式不会改变其捕获的值,所以函数调用操作符是const函数,如果Lambda表达式是mutable,那么函数调用操作符函数是非const函数。

2.返回值

如果Lambda表达式的函数体不只是一个return语句,那么这时就应该指定表达式的返回值了,它由一个箭头后面带一个返回类型来制定,如程序片段1-8所示,返回类型为bool。

对于 Lambda 表达式,通常只会使用在一个地方,且执行语句较少,如果有多个地方用到该功能,使用函数来实现会更方便些。另一种情况是,如果捕获列表为空,通常使用函数来实现比较直接。

如果一个断言要多于指定的参数,使用函数来实现该功能时,不能把该函数传递给find_if 这样的函数。后来引进了 Lambda 这样的表达式,那能不能直接使用函数来代替Lambda这样的表达式实现同样的功能呢?这就是下一小节将要介绍的库函数bind。1.3.2 bind函数

C++提供的库函数 bind,用于函数绑定的模版,它可以指定被绑定函数中的部分参数,也可以是全部参数,其形式如程序片段1-10所示。程序片段1-10 bind函数

其中:func 是原函数,arg_list 是 func 函数中的参数,是一个逗号分割的参数列表,其中参数可以用占位符来表示,_1 表示 func 函数的第一个参数,_2 表示该函数的第二个参数,以此类推,这些占位符可以交换顺序,它们位于std的placeholders命名空间下,f是一个新的可调用对象。对于bind函数的使用如程序片段1-11所示。程序片段1-11 bind函数使用

有了bind函数,同样可以解决程序片段1-8中的问题,实现如程序片段1-12所示。程序片段1-12 bind函数使用

bind函数指定了func函数中的第二个参数,而第一个参数是一个占位符。

默认情况下,bind 函数在不使用占位符时,参数是直接进行复制的。有时,某些绑定函数想通过引用传递或者有的参数是不能复制时,如程序片段1-13所示。程序片段1-13 带引用参数的函数

在这种情况下,C++引进了ref和cref函数。其中,cref是const引用,使用ref函数解决了os不能复制的问题,使用如程序片段1-14所示。程序片段1-14 bind函数使用引用参数

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载