https://github.com/cocos2d/cocos-docs/blob/master/tutorial/how-to-make-a-sushicrash-game-by-cocos2dx/part1/zh.md 欢迎大家斧正错误,提交pr。
一直以来,消除类游戏以其简单明快的节奏、浓厚的趣味性和智慧性而被广大玩家所喜爱。其分支三消类游戏更是倍受广大游戏玩家的推崇,最近的candycrush、开心消消乐、天天爱消除等三消游戏火的那是一个一塌糊涂啊。下面,我们就将和大家一起探讨一下如何制作一款属于自己的仿candycrush三消游戏——“sushicrush”。
引擎版本:本教程使用当前最新版本的 cocos2d-x-3.0rc0 引擎。
效果图:

游戏框架:为了使项目的代码结构清晰,好的前期规划是很有必要的,下图是该节游戏工程的主要类结构,先从整体看一下,项目的组织结构,然后我们会对其内部实现做些解说。
其中:
appdelegate.cpp:程序入口,分辨率适配设置。
playlayer.cpp:游戏场景层,游戏中所有的node节点都在其内,它同时负责管理sushisprite。
sushisprite.cpp:寿司精灵层,即游戏中可被消除和操作的对象。
在本章节教程中,我们将主要完成以下功能:
分辨率适配
寿司的创建、布局和下落
appdelegate.cpp是cocos2d-x自动生成的一个类,它控制着游戏的生命周期,是cocos2d-x游戏的通用入口文件,类似于一般 windows 工程中主函数所在的文件。打开appdelegate.cpp文件,在applicationdidfinishlaunching()函数中我们可以设置第一个启动的游戏场景:
为了能更好的适应各种分辨率大小和屏幕宽高比的移动终端设备,游戏的开始,我们还是先来看看分辨率的适配设置。
打开appdelegate.cpp文件,在applicationdidfinishlaunching函数里面添加如下代码,以便我们的游戏,能够更好的适应不同的运行环境。
设计分辨率是通过setdesignresolutionsize(width, height, resolutionpolicy)方法来设置的,第一,二个参数分别是设计分辨率的宽度和高度,第三个参数是你想要的模式。这里设置的分辨率大小是开发时为基准的屏幕分辨率大小。
模式有五种:
exact_fit 整个游戏内容都会在屏幕内可见,并且不用提供比例系数。x,y会被拉伸,使内容铺满屏幕,所以可能会出现形变,所有的应用程序看起来可能会是拉伸或者压缩的。
no_border 一个方向铺满屏幕,另外一个方向超出屏幕,不会变形,但是可能有一些裁剪。
show_all 该模式会尽可能按原始宽高比放大游戏世界,同时使得游戏内容全部可见。内容不会形变,不过可能会出现两条黑边,即屏幕中会有留白。
fixed_width 该模式会横向放大游戏世界内的内容以适应屏幕的宽度,纵向按原始宽高比放大。
fixed_height 与上一中模式相反。
setsearchpaths()方法设置资源搜索路径,这里w640是搜索的文件夹名。
setcontentscalefactor()方法设置内容缩放因子,顾名思义,就是设置整个游戏内容放大或者缩小的比例系数。
sushisprite类继承于sprite,用来创建单个的寿司精灵,下面是它的类定义:
cc_synthesize的定义如下:
cc_synthesize的作用是定义一个保护型的变量,并声明一个getfunname函数和setfunname函数,你可以用getfunname函数得到变量的值,用setfunname函数设置变量得值。
参数vartype是变量的类型,m_row是变量名,funname是要声明函数的“后半截”名字,如:cc_synthesize(int, m_row, row)的作用是声明一个int型的m_row变量和一个函数名为getrow以及setrow的函数。
寿司精灵的创建:
arc4random()方法获取随机数比较精确,并且不需要生成随即种子,arc4random() % total_sushi是获得 0 ~ total_sushi - 1之间的整数。
playlayer是游戏的主场景,同时也负责管理sushisprite,在该章教程中,playlayer里我们只实现了寿司的布局和它的下落。下面我们会详细讲解,先看看playlayer的初始化:
上面的初始化函数中有以下几点需要说明一下:
plist 和 pvr.ccz文件
spriteframecache和spritebatchnode
寿司矩阵起始点的初始化
寿司精灵如何布局
游戏中一般会有比较多的图片资源,如果有很多很多的资源,那加载这些资源是非常费时间和内存的,所以如何高效地使用图片资源对于一款游戏是相当重要的。在cocos2d中,我们一般会将图片资源打包成一张大图,这样加载图片不仅节省了空间,而且还提升了速度。
打开texturepacker,界面如下图所示。
texturepacker工具的每个设置项都给出了相应的提示信息,这里就不一一介绍。接下来,你就可以根据提示把本章节所需要的6张寿司图片资源打包了。导出的时候勾选 output-》texture format-》zlib compr.pvr,然后单击publish按钮进行导出,这样就会导出我们需要的plist 和 pvr.ccz文件了。
plist文件是图片信息的属性列表文件。
pvr图像是专门为ios设备上面的powervr图形芯片指定的图像容器。它们在ios设备上非常好用,因为可以直接加载到显卡上面,而不需要经过中间的转化。pvr.ccz文件则是pvr文件格式的压缩格式,使用这种图片格式的好处有两点:1、可以使你的应用程序更小,因为图片是被压缩过了的。2、你的游戏能够启动地更快。
上面,我们用texturepacker工具打包生成了plist和pvr.ccz文件,那么下一步,我们就该获取plist中的信息了。
cocos2d中spriteframecache通常用来处理plist文件,并能与spritebatchnode结合使用来达到批处理渲染精灵的目的。
精灵帧缓存类spriteframecache
精灵帧缓存类spriteframecache 用来存储精灵帧,缓存精灵帧有助于提高程序的效率。 spriteframecache是一个单例模式,不属于某个精灵,是所有精灵共享使用的。
精灵批处理节点spritebatchnode
当你需要渲染显示两个或两个以上相同的精灵时,如果逐个渲染精灵,每一次渲染都会调用 opengl es 的 draw 函数,这样做自然降低了渲染效率。不过幸好,cocos2d为开发者提供了一个spritebatchnode类,它能一次渲染多个精灵。并可以用来批处理这些精灵,比如我们游戏中的寿司精灵。用spritebatchnode作为父层来创建子精灵,并且使用它来管理精灵类,这样可以提高程序的效率。
在init()方法中调用spriteframecache的addspriteframeswithfile方法,传入plist文件名称,它会从plist属性列表文件的元数据部分获取各个纹理的纹理名,载入到纹理缓存中。并解析属性列表文件,使用spriteframe对象来内部地跟踪所有精灵的信息。
在cocos2d中高效使用图片总结:
使用texturepacker打包图片成pvr.ccz文件,使用spritebatchnode优化绘制,使用spriteframecache缓存读取,使用spritewithframename获取单张图片。
在游戏中,我们用来存储sushisprite的数据结构是一个指针数组,其实它也就相当于一个矩阵。寿司矩阵的起始点其实就是寿司精灵开始布局的起始点,在我们的游戏教程中,它位于屏幕的左下角,它由左下角的点开始逐行逐列的初始化寿司精灵。计算该点的公式如下:
其原理可简单描述为下图所示的过程(只以计算m_matrixleftbottomx的值为例,即x轴方向坐标值):
看原理图其实就已经一目了然了,上图n代表的是横向布局的寿司精灵数,m_matrixleftbottomx的值 = ( 屏幕的宽 - 寿司的宽*n个寿司 - ( n-1 )*寿司之间的间隙) / 2。
加载完寿司精灵图片,计算好寿司精灵布局的起始点以后,我们就可以开始寿司精灵的布局和它的下落显示了,下面是代码行:
我们先来看怎样获取指定行列精灵在屏幕上的坐标值,即positionofitem(row, col)方法的实现。同样附上原理图,方便理解。
上图矩阵的起始点已知(m_matrixleftbottomx,m_matrixleftbottomy),计算第row行col列的寿司精灵的坐标值。
需要说明的是,精灵图片的锚点默认在图片的中心位置,锚点关系到纹理贴图的位置。例如:如果把一个精灵设置在(0,0)点的位置,那么它的锚点也就会和(0,0)点重合,在屏幕上也就只能显示四分之一的精灵。所以往往为了避免这种问题,在贴精灵图片的时候我们会加上它宽高的一半。
言归正传,结合上面的原理图,你将很容易理解(x, y)是如何计算的。
最后,寿司精灵的创建和下落方法:createanddropsushi(row, col)。
寿司精灵的创建一幕了然,它的下落是通过让寿司精灵执行moveto动作来实现的,具体方法是把寿司精灵的起点设置在比终点(可以通过positionofitem方法获取)高size.height / 2的地方,再让其以一定的速度从起点移动到终点。原理如下图所示:
至此,我们第一章的内容久讲完了。
在下一章中,我们将实现初次掉落的消除检查,并自动消除三个连在一起的寿司,然后掉落新的寿司补齐空缺。