前言
2048是之前火过一段时间的休闲数字消除类游戏,它的玩法很简单,上手很容易,可是想到要得到高分却很难,看似简单的游戏却有着很多得分的技巧,想当初这个游戏也曾是陪伴我大学课堂的游戏之一。虽然在得分上有着很多的技巧,但对于开发来说,这其实是一件相当容易的事情,仔细分析之后就可能大概理清楚这种消除游戏的逻辑。
游戏分析
这款游戏仔细想想就差不多清楚它的大致的思路,游戏中只有方块这一个我们操作的对象,这个对象包含了所在行,所在列,以及方块显示的数字三个属性,这三个属性足以表达游戏中的所有效果。除了方块,其他的就是游戏中必不可少的背景图层,开始及结束场景等。由于游戏中需要将4x4的方块们整齐排列,因此还需要一个四行四列的表格,来呈现我们的游戏效果。
滑动逻辑
游戏中最主要的操作就是通过手指触摸屏幕进行滑屏操作,带动场景中的方块整体移动,并且遇到相同数字的方块进行合并。滑动的逻辑就是遍历场景中所有的方块,每一个方块在滑动方向进行移动,如果前方没有方块,方块就一直滑动,如果前方有方块,判断自己的数字与这个方块的数字是否相同,相同进行合并操作,不相同则停在当前位置。
游戏实现
在对游戏逻辑进行了分析之后,就可以用代码进行实现了,编码,其实就是一个将游戏逻辑转换为机器语言的过程而已。
方块类
首先,我们需要一个类来存储方块的长度和宽度,代码如下:
1 | // 保存方块长度方块 |
方块类是对场景中可操的方块的封装,包括所在行,所在列,显示数字三个属性,代码如下:
1 | var Tiled = cc.Node.extend({ |
当然仅仅有以上三个属性是不够的,我们还需要在方块的构造函数中绘制方块的背景、绘制方块显示的数字、以及随机设定方块的行列坐标。
1 | var Tiled = cc.Node.extend({ |
除此之外,每个方块应该还要包含一个newTile方法、moveTo方法和updateNum方法,分别封装随机创建方块、移动方块和更新方块数字三个功能。
在updateNum方法中,我们主要做两件事,更新方块显示数字和更新方块背景颜色(在方块的背景色上,我还专门上网搜了几种颜色搭配,恩,感觉很有艺术美,哈哈),代码如下:
1 | updateNum: function () { |
方块的移动方法和创建方法,我在这里先写成一样,因为还没有对方块的创建和移动做区别,如果要做优化,可以在移动时加入移动的动画,在创建加入创建的动画,代码如下:
1 | moveTo: function (row, col) { |
游戏场景类
所有的游戏操作及操作反馈都在游戏场景类中进行,游戏场景类将封装好的方块类放到游戏逻辑中,通过玩家操作给予一定的操作反馈。游戏场景类中主要接受玩家的滑动操作,并在接收到滑动操作后将所有的方块类进行移动或合并。
游戏场景类中需要isMove,startX,startY,以及tiles四个属性:第一个是控制玩家触摸操作的标识变量,避免重复调用移动方法;中间两个为记录玩家手指滑动的距离,当距离查过一定的长度之后,才判断玩家进行了滑动操作;最后一个变量是一个数组,用于存储在4x4的表格中的方块的信息。
有了以上四个属性之后,就可以在构造函数中进行初始化了,代码如下:
1 | var tiles = null;// 存储方块信息 |
在初始化完之后,我们就可以在场景的onEnter方法中绘制场景了,绘制的内容包括游戏背景以及随机初始化两个方块,代码如下:
1 | onEnter: function () { |
其中drawBg方法中,绘制了五条垂直直线以及五条水平直线,来作为方块所在的4x4的表格,代码如下:
1 | drawBg: function () { |
可以看到,在onEnter中,注册了触摸事件,这个触摸事件就用于接受玩家的操作,在TouchBegan事件中记录触摸开始时的点,在TouchMoved中记录当前移动到的点,当触摸距离超过一定长度时,判定玩家进行了滑动操作,并通过触摸点来判断玩家滑动的举例,代码如下:
1 | touchbegan: function (touch, event) { |
触动滑动操作后,开始执行滑动逻辑,每次滑动之后,会随机创建一个新的方块,在newTiled方法中,除了创建新方块之外,还需要判断游戏是否结束,代码如下:
1 | newTiled: function () { |
方块的滑动,就是2048这款游戏最主要的逻辑了,我们在滑动的时候,需要遍历tiles数组所有不是null的元素,并将这个元素按照滑动方向进行移动,一直遍历到数组的最大长度,也就是将滑动到表格的边缘,如果中途遇到了方块,并且数字与自己相同,就进行合并,合并是将自己删除,将遇到的方块数字乘以2,如果中途遇到的方块的数字与自己不同,此方块的滑动就停止,使其停在当前的位置,滑动分为上下左右四个逻辑,代码分别如下:
1 | moveUp: function () { |
至此,我们就基本实现了2048游戏的主要逻辑。
开始/结束场景类
为了游戏框架的完整,我们还是创建一个开始场景类和结束场景类,代码分别如下:
开始场景类
1 | var HelloWorldLayer = cc.Layer.extend({ |
结束场景类
1 | /** |
运行效果
最后的运行效果如下
通过CVP平台的项目托管可看到实际运行效果,地址如下:
http://www.cocoscvp.com/usercode/ea72822aeed0546b537b4226954a11be87a7f152/
源代码
所有源代码均上传到github,欢迎交流学习,地址:
https://github.com/hjcenry/2048