除了前几节介绍的一些类外,引擎中还有一些类是在程序的编写过程中经常用到的,这一节我们将把它们放在一起来介绍。
为了提高渲染的速度,Cocos2d-x中引入了SpriteBatchNode类,所有被加入到该节点的子节点,在渲染时,只进行一次 OpenGL 的调用。但是,为了实现这种功能,也有如下的一些限制。
(1)一个 SpriteBatchNode 节点只能使用一张纹理,只有那些使用这张纹理创建的节点才能被加入。
(2)被加入到SpriteBatchNode节点的子节点只能是Sprite或者它的子类。
(3)对于所有子节点,它们的抗锯齿属性要一致,即要么都开启抗锯齿,要么都关闭。
SpriteBatchNode 继承自 Node 节点,为了使用它,首先通过纹理和指定图片文件来创建它的对象,然后使用同样的图片文件来创建 Sprite 或者子类的对象,将这些对象作为子节点加入SpriteBatchNode节点对象中,具体的使用方式如程序片段2-50所示。
程序片段2-50 SpriteBatchNode节点的使用
程序片段2-50创建了5个Sprite节点,然后将它们加入SpriteBatchNode节点中,通过改变for循环中5的值为1~5这个范围的任何值,左下角的GL calls的值都不会改变,所有Sprite 节点都只进行一次 OpenGL 调用。所以无论生成多少个 Sprite 节点,只要它是作为SpriteBatchNode的子节点,则OpenGL的调用次数都不会改变。
对于射击类游戏,子弹的渲染可以加入到一个 SpriteBatchNode 节点中。对于类似这样的应用,都可以使用这个节点的方式来实现,而且还可以把各个小图拼接成一张大图,用大图来生成SpriteBatchNode节点,其他Sprite的创建取大图中取对应的小图,然后作为子节点加入。
在 2.x 中,引擎使用 DrawPrimitives 命名空间下的函数进行绘图操作。在 3.x 中引入DrawNode 节点类,这种绘图方式比前者快,对于同一个节点对象绘制的图形,它在一个批次内完成。两者都可以实现点、线段、三角形、矩形、贝塞尔曲线等的绘制,对于 DrawNode 类绘制的图形,具体函数如表2-14所示。
表2-14 DrawNode类绘制函数
表2-14中的部分函数,有对应绘制实心图形的函数,如多边形函数drawPolygon、矩形函数 drawSolidRect 和圆 drawSolidCircle 等,可以指定实心图形的填充颜色。颜色的默认混合模式是 ALPHA_PREMULTIPLIED,即原混合函数为 GL_ONE,目标混合函数为 GL_ONE_MINUS_SRC_ALPHA。对于这些函数的使用,如程序片段2-51所示。
程序片段2-51 DrawNode函数的使用
程序片段 2-51 介绍了 DrawNode 类大部分函数的使用,实心函数的使用与其差不多。对于pDrawNode 对象,可以调用clear 函数清除前面绘制的图形,接着绘制其他图形。程序片段执行效果如图2-21所示。
图2-21 DrawNode函数绘制图
图 2-21 中,三角形的绘制是实心的;矩形和圆都是空心的;第三列是二次和三次贝塞尔曲线图;最右边的是Cardinal Spline和Catmull Rom曲线,这两条曲线的控制点只是在 Y 方向上偏移了 80 个像素,绘制图形大致一样。读者如果有兴趣,可以使用 DrawPrimitives命名空间下的函数来实现同样的图形绘制,这些函数虽然被遗弃,但同样是可以调用的。
Scale9Sprite 类是一种可伸缩的图片精灵,使用九宫格的图片来创建它,这种图片可以很小,如64×64、128×128或者其他尺寸(对图片的尺寸没有什么要求),显示的最终大小是通过函数 setContentSize 或者 setPreferredSize 控制的。可以设置这种精灵的显示状态(NORMAL 或者 GRAY),GRAY 是灰度显示这种精灵,美工制作九宫格的图片后,就可以使用该类来创建它,具体实现如程序片段2-52所示。
程序片段2-52 Scale9Sprite类的使用
从程序片段2-52中可以看出,Scale9Sprite 的使用和Sprite的使用没有太大的区别。这种精灵经常用在那些边上有轮廓、中间是一个纯色的界面中,如游戏界面的背景、文本框输入的背景等。
游戏中,有些地方需要输入一些内容,如玩家注册、聊天系统等,这种功能可以通过EditBox 控件来实现。它是一个文本输入框,可以设置文本输入模式、标识和弹出键盘的返回类型,具体如程序片段2-53所示。
程序片段2-53 EditBox输入模式和标识类
对于弹出键盘的类型,它存储在 KeyboardReturnType 类中,其值可以为 DEFAULT、DONE、SEND、SEARCH或GO。对于EditBox类,应该有相应的函数来设置这些参数,具体如表2-15所示。
表2-15 EditBox函数
键盘从弹出到关闭,在这之间会调用一些函数,它们在 EditBoxDelegate 类中有声明,包括4个函数,如表2-16所示。
表2-16 EditBoxDelegate类函数
一般在要使用EditBox的类中,让它继承自EditBoxDelegate。在子类中,表中的前3个函数可以不必实现,但 editBoxReturn 在 EditBoxDelegate 类中是一个抽象函数,所以在子类中必须实现。
EditBox对象的创建是基于Scale9Sprite的,可以设置文本输入框的3种状态,分别是正常、按下和禁用,这3种状态的图片对应3种状态的Scale9Sprite 对象。对于EditBox 的使用,如程序片段2-54所示。
程序片段2-54 EditBox的使用
图2-22 EditBox效果图
函数 create 的第一个参数指定了文本框的大小。在继承了EditBoxDelegate的类中重写editBoxReturn函数,在该函数中捕获输入的内容,输入内容前后的对比效果如图2-22所示。
为了把自己玩的游戏或者游戏成果分享给好友,往往会把游戏的当前页面截屏,然后进行分享,捕鱼达人3就有这个功能。RenderTexture类可以实现这个功能,它可以把当前场景中的内容渲染到一张纹理上,具体实现如程序片段2-55所示。
程序片段2-55 游戏截屏实现
程序片段 2-55 中,首先创建一个屏幕大小的渲染目标,然后在 beginWithClear 和 end之间添加要渲染的对象,最后通过 saveToFile 函数保存纹理。其中,保存的文件格式可以是PNG或者JPG,文件默认的保存路径是计算机的文档目录下。