2048小游戏开发
记得14年的时候吧,2040小游戏非常火爆,很多公司也做了个“升级版”,当时我们是使用cocos2d-x(c++)引擎进行开发的,各种换皮玩法。不过由于当时我也是个游戏开发新手,做出来的bug不少。这游戏虽然看着简单玩着也简单,但开发起来发现难点还是有的,比如cell移动动画,必须保证可以快速不间断的操作还得保证cell移动的位置都正确,还要保证新出现的cell位置正确。现在我们来用cocoscreator引擎实现一遍,顺便优化一下逻辑。
一、主要逻辑
我们通过维护两个4x4的数组来实现,数组a存数据(0表示空格子,非0表示对应的值), 每次操作时即时更新数组的值。数组b存真实显示在屏幕上可以做动画的格子节点,每次操作后立即更新节点在数组b中的位置(和数组a对应),但格子节点存在动画,显示的更新有滞后,需要移动动画结束后再根据当前所在的格子位置去数组a取值更新自己的值(比如节点n在数组b中的位置是(0,0),则其值应该是数组a[0] [0]的值)
二、具体实现
主要就是移动和判断是否可以移动的逻辑,当四个方向都不可以移动时则游戏结束。
1. 判断是否可以移动
上下左右的逻辑一样,我们拿向左移动来举例:
假设某一行是0 2 4 8四个格子,我们只需要从左侧第二个格子开始依次和前面的格子进行比较,如果前面的格子是0或者前面的格子的值和当前的格子的值相同,则该方向可以移动,否则不可以移动。因为2左侧是0,所以可以移动,代码如下:
canMoveLeft() {
for (let row = 3; row >= 0; row--) {
for (let col = 1; col <= 3; col++) {
if (this.board[row][col] != 0) {
if (this.board[row][col - 1] == 0 || this.board[row][col - 1] == this.board[row][col]) {
return true;
}
}
}
}
return false;
},
2. 移动与合并逻辑
这里还是拿向左合并举例,比如某一行是2 0 2 4,则合并后应该是4 4 0 0 而不是8 0 0 0,这个逻辑我看网上不少都错了,每个数字在每次移动过程中只能参与一次合并。循环每一行开始时都设置一个flag等于0,从左侧第1个数字开始向右取值,如果为0则继续看下一个,否则拿它依次和左侧第0+flag个开始比对直到比对到当前值的前一个,如果后者为0,则把当前值赋给后者,当前值设置为0,如果后者和当前值相同,则后者的值等于后者加当前值,然后当前值设为0,并统计分数。划重点,一担发生合并则flag要加1,下次比对过程中就不是从左侧第0个开始了,而是从左侧0+flag处开始,这个很容易忽略,代码如下:
moveLeft() {
cc.log("左滑动");
if (!this.canMoveLeft()) {
return;
}
for (let row = 3; row >= 0; row--) {
let tmp = 0;
for (let col = 0; col <= 3; col++) {
if (this.board[row][col] == 0) {
continue;
}
for (let k = 0 + tmp; k < col; k++) {
if (this.board[row][k] == 0 && this.noBlockHorizonal(row, k, col)) {
this.board[row][k] = this.board[row][col];
this.board[row][col] = 0;
this.moveActionHorizonal(row, col, k, false);
} else if (this.board[row][k] == this.board[row][col] && this.noBlockHorizonal(row, k, col)) {
this.score += this.board[row][col] * 2;
this.board[row][k] += this.board[row][col];
this.board[row][col] = 0;
tmp++;
this.moveActionHorizonal(row, col, k, true);
}
}
}
}
this.randomCell();
}