引擎在 3.0 后,在保持引擎整个框架结构不变的前提下,较前一个版本还是发生了比较大的变化,其中包括类名、回调函数、事件响应机制等,并且增加了 C++11 标准的一些知识。在 2.x 中以宏出现的功能函数和结构,在 3.x 版本中都通过类的封装来实现,这样使得程序更加简洁,使初学者更加容易理解。在本小节中,将介绍主要的一些变化,使 2.x 编程者很快过渡到3.x版本。
引擎中,各个类对应的头文件(.h)和执行文件(.cpp)虽然在命名上没有变化,但是里面定义的类在命名上发生了变化,去掉了之前的 CC 前缀。例如,要在界面上显示一张图片,实现程序如程序片段1-1所示。
程序片段1-1 显示图片代码
代码中,setPosition函数是设置图片的位置,setAnchorPoint是设置图片的锚点,然后通过addChild函数把这张图片加入场景中进行渲染。这些函数,在后面的章节中将会介绍。在这里,我们看到创建图片的类从CCSprite 变成了Sprite,去掉了CC 前缀,这里只是介绍了Sprite的变化,还有CCDirector变成了Director、CCScene变成了Scene等。
单件类中对于用来获取它的实例函数,由share方式变成了get方式,在2.x中的获取和销毁实例方法如表1-1所示。
表1-1 2.x中单件类方法
可以看出,在 2.x 中的每个单类,获取和销毁它对应实例的方法都不一样。而在 3.x 中统一为:获取实例方法是 getInstance,销毁实例方法是 destroyInstance。不过,引擎为了迎合2.x程序员的习惯,在3.x中同样可以使用2.x的调用方式。
宏定义与常量的变化如表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),那么常量和功能函数可以直接在类里面定义,不用定义多个宏和全局函数来实现相应功能。
在 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回调等。
在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 绑定的对象,重载了函数调用操作符的类。