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();
}