先放個效果圖吧

首先,先把html結構搭好,新建一個html檔案,設定好標題2048,按鈕New Game以及score:0,這里按鈕是用a標簽來將javascript中的newgame函式給傳進來,score后面的分數由于是動態的,所以給它添加一個span標簽,并加上一個id,代碼如下
<header>
<h1>2048</h1>
<a href="javascript:newgame();" id="newgamebutton">New Game</a> <!-- 點擊a標簽后,執行一個js的自定義函式newgame() -->
<p>score: <span id="score">0</span></p>
</header>
然后將所有的格子布置好,這里是用div標簽來表示每個格子,后續將會用相對定位,絕對定位以及js中的函式來撰寫每個格子的位置,代碼如下
<div id="grid_container">
<div class="grid_cell" id="grid_cell_0_0"></div>
<div class="grid_cell" id="grid_cell_0_1"></div>
<div class="grid_cell" id="grid_cell_0_2"></div>
<div class="grid_cell" id="grid_cell_0_3"></div>
<div class="grid_cell" id="grid_cell_1_0"></div>
<div class="grid_cell" id="grid_cell_1_1"></div>
<div class="grid_cell" id="grid_cell_1_2"></div>
<div class="grid_cell" id="grid_cell_1_3"></div>
<div class="grid_cell" id="grid_cell_2_0"></div>
<div class="grid_cell" id="grid_cell_2_1"></div>
<div class="grid_cell" id="grid_cell_2_2"></div>
<div class="grid_cell" id="grid_cell_2_3"></div>
<div class="grid_cell" id="grid_cell_3_0"></div>
<div class="grid_cell" id="grid_cell_3_1"></div>
<div class="grid_cell" id="grid_cell_3_2"></div>
<div class="grid_cell" id="grid_cell_3_3"></div>
</div>
現在html結構已經搭完了,開始撰寫css樣式,新建一個css檔案,這里css樣式其實沒什么好講的,各塊內容多大字號,什么背景顏色,padding,margin為多少都是看自己喜好,該居中的居中,我設的大盒子長寬為500px,每個格子長寬為100px,代碼如下
header {
margin: 0 auto;
width: 500px;
text-align: center;
}
header h1 {
font-family: Arial;
font-size: 40px;
font-weight: bold;
}
#newgamebutton {
/* 為了設定各方向的padding和margin,將其變成塊元素 */
display: block;
margin: 20px auto;
width: 100px;
color: white;
background-color: #8f7a66;
text-decoration: none;
padding: 10px;
border-radius: 10px;
font-family: Arial;
}
#newgamebutton:hover {
background-color: #9f8b77;
}
header p {
font-family: Arial;
font-size: 25px;
margin: 20px auto;
}
#grid_container {
width: 460px;
height: 460px;
padding: 20px;
margin: 30px auto;
border-radius: 10px;
background-color: #bbada0;
/* 給大盒子設定相對定位 */
position: relative;
}
.grid_cell {
width: 100px;
height: 100px;
border-radius: 6px;
background-color: #ccc0b3;
/* 給小盒子設定絕對定位 */
position: absolute;
}
css樣式設定完后,就可以開始撰寫js程式了,新建一個js檔案,
首先先想清楚我們需要設定什么,從頭開始看,我們用a標簽定義了一個按鈕,在a標簽中呼叫了一個js的函式newgame,那么點擊New Game按鈕會發生什么呢?初始化,以及產生兩個亂數,
初始化中又有什么功能?每一個格子的數字全部初始化為0(0這個數字可以自己隨便取),那么我們就需要定義一個陣列專門存放數字,并且分數score也歸零,
var board = []; //存放數字的陣列
var score = 0; //存放得分
var hasConflicted = []; //存放是否沖突的陣列
此處我們定義了一個陣列hasConflicted ,現在先不講,等到最后所有功能完成了我們再講,另外我們之前給每個格子設定了絕對定位,但是還沒設定具體的位置,那么在此處一并設定了,代碼如下
$(function () {
newgame();
})
// 初始化
function newgame() {
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
var gridCell = $("#grid_cell_" + i + "_" + j); // 定義變數gridCell來撰寫每個格子的位置
gridCell.css("top", getPosTop(i, j));
gridCell.css("left", getPosLeft(i, j)); //只需定義格子的左上角即可
}
}
for (var i = 0; i < 4; i++) {
board[i] = [];
hasConflicted[i] = [];
for (var j = 0; j < 4; j++) {
board[i][j] = 0; //把board定義為二維陣列來更方便地表達出每個格子,board為0即這個格子沒有數字,不為0即有數字
hasConflicted[i][j] = false; //初始化時需要將每個格子是否沖突的屬性定義為false
}
}
updateBoardView(); //定義此函式來將數字放到該格子中
generateOneNumber(); //每次初始化游戲都會隨機產生兩個數字
generateOneNumber();
score = 0; //初始化
}
先看第一段回圈,此處定義了一個變數gridCell來方便撰寫每個格子的位置,然后又呼叫了兩個函式getPosTop和getPosLeft,

可以看到每個格子的頂部距離大盒子的頂部都是20px+120px乘縱坐標數,同理,左端也是20px+120px乘橫坐標數,因此代碼如下
function getPosTop(i, j) {
return 20 + i * 120; //每個格子的上方與大盒子頂端的距離
}
function getPosLeft(i, j) {
return 20 + j * 120; //每個格子的左邊與大盒子左邊的距離
}
再接著看newgame函式,由于board是存放每個格子的數字的陣列,因此它是一個二維陣列,所以第二個回圈就是完成這件事的,此處我是將board初始化為0來代表這個格子沒有數字,大家也可以定義為其他數字,hasConflicted最后再講,
然后就是定義了一個函式updateBoardView,這個函式是用來將每個數字放到相應的格子中去的,所以我們每次進行上下左右的操作時,都要呼叫該函式,代碼如下
function updateBoardView() {
$(".number_cell").remove(); //由于每一次操作都要呼叫該函式,所以每次呼叫之前都要先將上次操作后產生的數字清除
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
$("#grid_container").append("<div class='number_cell' id='number_cell_" + i + "_" + j + "'>"); //給每個格子添加數字
var theNumberCell = $("#number_cell_" + i + "_" + j); //定義該變數來撰寫每個格子中數字的css樣式
if (board[i][j] == 0) {
theNumberCell.css("width", "0"); //當該位置沒有數字時,寬高設為0就行
theNumberCell.css("height", "0");
theNumberCell.css("top", getPosTop(i, j));
theNumberCell.css("left", getPosLeft(i, j));
} else {
theNumberCell.css("width", "100px");
theNumberCell.css("height", "100px");
theNumberCell.css("top", getPosTop(i, j));
theNumberCell.css("left", getPosLeft(i, j));
theNumberCell.css("background-color", getNumberBackgroundColor(board[i][j])); //定義該函式來存放不同數字的背景顏色
theNumberCell.css("color", getNumberColor(board[i][j])); //定義該函式來存放不同數字的顏色
theNumberCell.text(board[i][j]); //將數字值賦予給相應的格子
}
hasConflicted[i][j] = false; //由于每一次操作都要呼叫該函式,所以每次呼叫之前都要先將每個格子是否沖突的屬性定義為false
}
}
}
我們剛說了,每一次操作都要呼叫該函式,那么相應的,每一次操作后,每個格子中的數字都要先刪掉,然后再賦值,第一行就是完成這件事,
然后由于不同的格子有不同的數字,所以我們得定義一個變數theNumberCell來方便撰寫,要定義該變數,我們就得先給每個格子設定一個number_cell的類和id,所以我們先動態添加一個html標簽,
添加完標簽后,定義變數theNumberCell,然后又由于沒有數字的格子和有數字的格子樣式不一樣,所以此處分開討論,
當該位置沒有數字時(即board=0),也就是不顯示數字,那么寬高設為0就行,位置的話我們之前設定了兩個位置函式,這里直接呼叫就行,當該位置有數字時,寬高設為100px,位置照樣呼叫位置函式,背景顏色和數字的顏色我們定義了兩個函式,最后將該數字放到該格子中去就行,
這里新加了一堆div標簽,所以我們再給它們添加一下css樣式,代碼如下
.number_cell {
font-family: Arial;
font-size: 30px;
font-weight: bold;
line-height: 100px;
text-align: center;
border-radius: 6px;
position: absolute;
}
背景顏色和數字顏色的函式我就直接給代碼了,沒什么好說的
function getNumberBackgroundColor(number) {
switch (number) {
case 2:
return "#eee4da";
break;
case 4:
return "#ede0c8";
break;
case 8:
return "#f2b179";
break;
case 16:
return "#f59563";
break;
case 32:
return "#f67c5f";
break;
case 64:
return "#f65e3b";
break;
case 128:
return "#edcf72";
break;
case 256:
return "#edcc61";
break;
case 512:
return "#9c0";
break;
case 1024:
return "#33b5e5";
break;
case 2048:
return "#09c";
break;
case 4096:
return "#a6c";
break;
case 8192:
return "#93c";
break;
}
return "black";
}
function getNumberColor(number) {
if (number <= 4) {
return "#776e65";
} else {
return "white";
}
}
回到newgame函式中,那么現在updateBoardView這個函式也講完了,之后的就是隨機生成兩個數字的函式,代碼如下
function generateOneNumber() {
if (nospace(board)) { //先判斷還有沒有空位置
return false;
} else {
//隨機生成一個位置
var randx = parseInt(Math.floor(Math.random() * 4));
var randy = parseInt(Math.floor(Math.random() * 4));
var times = 0;
while (times < 50) {
if (board[randx][randy] == 0) {
break; //判斷該位置是否有數字,若沒有,則直接跳出回圈,若有,則繼續生成randx和randy
} else {
randx = parseInt(Math.floor(Math.random() * 4));
randy = parseInt(Math.floor(Math.random() * 4));
}
times++;
}
if (times == 50) {
for (var i = 0; i < 4; i++) { //若演算法運行了50次后仍然沒有找到空位置,則人工采用for回圈來找
for (var j = 0; j < 4; j++) {
if (board[i][j] == 0) {
randx = i;
randy = j;
}
}
}
}
//隨機生成一個數字(2或者4)
var randNumber = Math.random() < 0.5 ? 2 : 4; //當亂數小于0.5時,取2,否則取4
//把數字放進空位置
board[randx][randy] = randNumber;
showNumberWithAnimation(randx, randy, randNumber); //給生成數字的動作添加影片
return true;
}
}
要想生成數字,首先得判斷一下還有沒有空位置,此處呼叫了一個新函式,怎么判斷有沒有空位置呢?遍歷所有的格子,如果有格子的數字為0,那么就有空位置,全部遍歷完都沒有為0的數字的話,就沒有空位置,代碼如下
function nospace(board) {
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
if (board[i][j] == 0) {
return false;
}
}
}
return true;
}
回到generateOneNumber函式中,判斷完后,就該生成數字了,生成數字有兩步,先隨機生成一個空位置,再隨機生成一個數字,
先來看第一步,怎么隨機生成一個空位置呢?由于每個格子的坐標都是從0開始的(從html處撰寫的grid_cell的id也可以看出),所以坐標值的話就隨機取[0,1,2,3]即可,此處采用Math.random(),該陳述句代表隨機生成0到1的數,所以將它*4后再取floor即可,由于此處生成的還是浮點型資料,我們采用一個parseInt將其改成整型資料,
范圍取好后,再決定隨機取哪個位置,此處我們定義一個變數times來代表回圈次數,設定一個步數50步,回圈中,我們就采用一個if陳述句便可以完成,該位置沒有數字就跳出回圈,有數字就繼續尋找,如果50步仍然沒有找到空位置,那么我們就人為地利用兩個for回圈來尋找,
隨機位置生成后,再隨機生成數字,此處我們仍然使用Math.random()陳述句來完成,如果隨機生成的數字小于0.5,就取2,否則就取4.
最后就是將該亂數字放進該隨機位置,并且此處我們使用了一個影片來顯示該數字,代碼如下
function showNumberWithAnimation(i, j, randNumber) {
var numberCell = $("#number_cell_" + i + "_" + j);
numberCell.css({
"background-color": getNumberBackgroundColor(randNumber), //當numberCell從沒有數字變到有數字,或者從一個數字變成另一個數字時,該numberCell的css樣式要發生改變
"color": getNumberColor(randNumber)
});
numberCell.text(randNumber);
numberCell.animate({
"width": "100px",
"height": "100px",
"top": getPosTop(i, j),
"left": getPosLeft(i, j)
}, 50);
}
傳入了3個引數,橫縱坐標值以及該位置的數字,首先定義一個變數numberCell,由于該位置從沒有數字變成有數字時,或者從一個數字變成另一個數字時,css樣式會發生改變,所以此處仍然要定義一波該變數的背景顏色以及數字顏色,直接呼叫這兩個函式就行,最后就是自定義影片了,寬高和位置照舊,然后賦予一個50ms的時間來完成該影片,
至此,generateOneNumber函式完成,再回到newgame函式中,最后還初始化了一個score,將其變為0,newgame函式也完成,這時我們已經完成了整個頁面的布局,效果圖應該是和最開始放的那張圖一樣,
然后我們要撰寫的就是操作上下左右的程式了,首先撰寫一個鍵盤keydown的事件,代碼如下
$(document).keydown(function (event) {
switch (event.keyCode) { //鍵盤敲擊事件,此處為keyCode不是keycode
case 37: //左
if (moveLeft()) {
setTimeout("generateOneNumber()", 210); //先要判斷是否能夠向左動,向左動了后會隨機產生一個數字,并判斷游戲是否結束
setTimeout("isgameover()", 300);
}
break;
case 38: //上
if (moveTop()) {
setTimeout("generateOneNumber()", 210);
setTimeout("isgameover()", 300);
}
break;
case 39: //右
if (moveRight()) {
setTimeout("generateOneNumber()", 210);
setTimeout("isgameover()", 300);
}
break;
case 40: //下
if (moveDown()) {
setTimeout("generateOneNumber()", 210);
setTimeout("isgameover()", 300);
}
break;
default:
break;
}
})
這里首先要注意的是keyCode處的C是大寫的,這個bug我當初找了好久…
先看向左動,首先寫了一個if陳述句,如果可以向左動的話,那么會隨機產生一個數字,并且需要判斷會不會游戲結束,這個setTimeout我們留到后面一起講,
先來看看moveLeft這個函式,代碼如下
function moveLeft() {
if (canMoveLeft(board)) {
for (var i = 0; i < 4; i++) {
for (var j = 1; j < 4; j++) {
if (board[i][j] != 0) {
for (var k = 0; k < j; k++) {
if (board[i][k] == 0 && noBlockHorizontal(i, k, j, board)) { //尋找可以移動到的位置board[i][k]
showMoveAnimation(i, j, i, k); //添加移動時的影片
board[i][k] = board[i][j];
board[i][j] = 0;
continue;
} else if (board[i][k] == board[i][j] && noBlockHorizontal(i, k, j, board) && !hasConflicted[i][k]) {
showMoveAnimation(i, j, i, k);
board[i][k] += board[i][j];
board[i][j] = 0;
score += board[i][k]; //分數疊加
updateScore(score); //將分數動態傳回#score
hasConflicted[i][k] = true; //每一次移動后都要將該位置是否存在沖突的屬性設為true
continue;
}
}
}
}
}
setTimeout("updateBoardView()", 200); //由于每一次操作,board都會發生變化,所以每一次操作都要呼叫updateBoardView()
return true;
} else {
return false;
}
}
首先要判斷能不能向左動,此處我們分析一下,最左邊的那一列格子是肯定不能向左動的,所以我們只需要遍歷右邊的那三列就行,所以定義了一個新函式,代碼如下
function canMoveLeft(board) {
for (var i = 0; i < 4; i++) {
for (var j = 1; j < 4; j++) {
if (board[i][j] != 0) {
if (board[i][j - 1] == 0 || board[i][j - 1] == board[i][j]) { //當board[i][j]處左邊的格子沒有數字或者數字和它自身相等時,該格子可以左移
return true;
}
}
}
}
return false;
}
可以看到先遍歷右邊的三列,如果某個位置有數字的話,它什么情況下可以左移呢?如果它左邊那個格子沒有數字或者數字和它相等的話,是不是就可以左移了,該函式即可完成,
回到moveLeft函式,當可以左移時,我們就需要進行左移的操作了,照樣我們遍歷右邊的三列,先找到某個有數字的位置board[i][j],然后它要左移的話是不是得先找到一個格子可以讓它左移,所以此處給出一個for回圈來尋找j左邊的所有格子,再來一一判斷,
如果找到了某個格子沒有數字,并且他們倆之間沒有障礙物,此時就可以進行左移的操作了,沒有障礙物的函式代碼如下
function noBlockHorizontal(row, col1, col2, board) {
for (var i = col1 + 1; i < col2; i++) {
if (board[row][i] != 0) {
return false;
}
}
return true;
}
就是尋找某一行的兩列之間有沒有數字為0,遍歷一遍就行,再回到moveLeft函式,此處我們給移動的動作添加了一個影片,代碼如下
function showMoveAnimation(fromx, fromy, tox, toy) {
var numberCell = $("#number_cell_" + fromx + "_" + fromy);
numberCell.animate({
"top": getPosTop(tox, toy),
"left": getPosLeft(tox, toy)
}, 200);
}
就是簡單的用到了四個坐標值而已,然后添加了200ms的時間來完成該影片,
再回到moveLeft函式,添加完影片后,將board[i][k]處的數字由0變成board[i][j]的數字,并且board[i][j]自己的數字變為0 ,
然后當board[i][k]處的數字等于board[i][j]的數字時,照樣先添加一個影片,然后board[i][k]處的數字加上board[i][j]的數字,board[i][j]的數字也變為0,分數同時也會疊加,并且分數要動態地傳回score中,所以此處定義了一個函式,代碼如下
function updateScore(score) {
$("#score").text(score);
}
再回到moveLeft函式,hasConflicted后面再講,我們之前講過,每做一次操作就需要呼叫updateBoardView函式,所以在此處回圈完后,呼叫一次該函式,此處設定了一個200ms的setTimeout,是因為我們在showMoveAnimation函式中給影片添加的完成時間是200ms,如果我們不給updateBoardView添加一個200ms的延遲的話,就會發現影片還沒完成,數字就已經顯示出來了,
至此,moveLeft就已經講完了,后面的moveRight,moveTop,moveDown大家可以自己試著寫一下,就不細講了,此處我給出moveRight的代碼
function moveRight() {
if (canMoveRight(board)) {
for (var i = 0; i < 4; i++) {
for (var j = 2; j >= 0; j--) {
if (board[i][j] != 0) {
for (var k = 3; k > j; k--) {
if (board[i][k] == 0 && noBlockHorizontal(i, j, k, board)) {
showMoveAnimation(i, j, i, k);
board[i][k] = board[i][j];
board[i][j] = 0;
continue;
} else if (board[i][k] == board[i][j] && noBlockHorizontal(i, j, k, board) && !hasConflicted[i][k]) {
showMoveAnimation(i, j, i, k);
board[i][k] += board[i][j];
board[i][j] = 0;
score += board[i][k];
updateScore(score);
hasConflicted[i][k] = true;
continue;
}
}
}
}
}
setTimeout("updateBoardView()", 200);
return true;
} else {
return false;
}
}
此處有一個地方稍微需要思考一下,為什么在第二個for回圈處j是從大往小寫,而不是跟moveLeft處一樣從小到大遍歷?
答案揭曉!如果此處是從小到大遍歷的話,我們玩的時候會發現一個問題,當左邊兩列或者三列有數字時,這時我們按右鍵,會發現最左邊的那一列不會右移,為什么呢?因為j從0開始回圈的話,演算法會發現最左邊一列的右邊有數字,無法右移,所以右移的演算法應該要先從最右邊開始遍歷,等右邊的數字移動完了再移動左邊的,
同理,下面的那個定義k的for回圈也就得跟著從大往小變化,
當其他的幾個操作撰寫完之后,我們在鍵盤keydown事件中還撰寫了一個isgameover函式,此時來定義它,代碼如下
function isgameover() {
if (nospace(board) && nomove(board)) {
alert("game over"); //當沒有空位且不能移動時游戲結束
}
}
什么時候會gameover呢?當所有的格子都有數字且都不能移動時,游戲就結束了,我這里就簡答地寫了一個彈窗,nomove函式的代碼如下
function nomove(board) {
if (canMoveLeft(board) || canMoveRight(board) || canMoveTop(board) || canMoveDown(board)) {
return false;
}
return true;
}
我們之前已經定義了判斷是否可以左移右移上移下移的函式,這里直接呼叫就行,
現在理論上是可以玩了,但是我們玩的時候還會發現一個問題,例如現在某一行數字是這樣的,2,2,4,8,這時我們按左移的話,如果是原版2048,這里會變成4,4,8,0,但是我們撰寫的程式會直接變成16,0,0,0,所以我們得撰寫一個功能讓某個格子在一次操作時該格子的數字只能變化一次,
就是我們之前已經出現過的hasConflicted,當時我是說后面再講,首先我們先定義一個空陣列
var hasConflicted = []; //存放是否沖突的陣列
由于它也是每個格子都有的屬性,所以也得把它變成一個二維陣列,這是newgame函式的代碼
// 初始化
function newgame() {
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
var gridCell = $("#grid_cell_" + i + "_" + j); // 定義變數gridCell來撰寫每個格子的位置
gridCell.css("top", getPosTop(i, j));
gridCell.css("left", getPosLeft(i, j)); //只需定義格子的左上角即可
}
}
for (var i = 0; i < 4; i++) {
board[i] = [];
hasConflicted[i] = [];
for (var j = 0; j < 4; j++) {
board[i][j] = 0; //把board定義為二維陣列來更方便地表達出每個格子,board為0即這個格子沒有數字,不為0即有數字
hasConflicted[i][j] = false; //初始化時需要將每個格子是否沖突的屬性定義為false
}
}
updateBoardView(); //定義此函式來將數字放到該格子中
generateOneNumber(); //每次初始化游戲都會隨機產生兩個數字
generateOneNumber();
score = 0; //初始化
}
初始化當然要將它的屬性設為false,也就是這個格子還沒有變化過,然后我們為了防止上述問題的出現,就得在每次操作時加上一個判定
function moveLeft() {
if (canMoveLeft(board)) {
for (var i = 0; i < 4; i++) {
for (var j = 1; j < 4; j++) {
if (board[i][j] != 0) {
for (var k = 0; k < j; k++) {
if (board[i][k] == 0 && noBlockHorizontal(i, k, j, board)) { //尋找可以移動到的位置board[i][k]
showMoveAnimation(i, j, i, k); //添加移動時的影片
board[i][k] = board[i][j];
board[i][j] = 0;
continue;
} else if (board[i][k] == board[i][j] && noBlockHorizontal(i, k, j, board) && !hasConflicted[i][k]) {
showMoveAnimation(i, j, i, k);
board[i][k] += board[i][j];
board[i][j] = 0;
score += board[i][k]; //分數疊加
updateScore(score); //將分數動態傳回#score
hasConflicted[i][k] = true; //每一次移動后都要將該位置是否存在沖突的屬性設為true
continue;
}
}
}
}
}
setTimeout("updateBoardView()", 200); //由于每一次操作,board都會發生變化,所以每一次操作都要呼叫updateBoardView()
return true;
} else {
return false;
}
}
可以看到在else if中最后還加了一個!hasConflicted[i][k],意思是該位置還沒有變化過,可以移動,然后將它的屬性設為true,這時該位置在這一次回圈時就已經不能再變化了,這時上述問題就已經解決好了,那么在這次操作完后在哪將它的屬性由true變回false呢?我們不是呼叫了一個updateBoardView函式了嘛,在這里將它設定回去就可以了,一定要記得設定回去,不然下次操作這個位置就不能變化了,
function updateBoardView() {
$(".number_cell").remove(); //由于每一次操作都要呼叫該函式,所以每次呼叫之前都要先將上次操作后產生的數字清除
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
$("#grid_container").append("<div class='number_cell' id='number_cell_" + i + "_" + j + "'>"); //給每個格子添加數字
var theNumberCell = $("#number_cell_" + i + "_" + j); //定義該變數來撰寫每個格子中數字的css樣式
if (board[i][j] == 0) {
theNumberCell.css("width", "0"); //當該位置沒有數字時,寬高設為0就行
theNumberCell.css("height", "0");
theNumberCell.css("top", getPosTop(i, j));
theNumberCell.css("left", getPosLeft(i, j));
} else {
theNumberCell.css("width", "100px");
theNumberCell.css("height", "100px");
theNumberCell.css("top", getPosTop(i, j));
theNumberCell.css("left", getPosLeft(i, j));
theNumberCell.css("background-color", getNumberBackgroundColor(board[i][j])); //定義該函式來存放不同數字的背景顏色
theNumberCell.css("color", getNumberColor(board[i][j])); //定義該函式來存放不同數字的顏色
theNumberCell.text(board[i][j]); //將數字值賦予給相應的格子
}
hasConflicted[i][j] = false; //由于每一次操作都要呼叫該函式,所以每次呼叫之前都要先將每個格子是否沖突的屬性定義為false
}
}
}
最后我們之前還有個地方沒講,之前講鍵盤keydown事件時還設定了兩個setTimeout
$(document).keydown(function (event) {
switch (event.keyCode) { //鍵盤敲擊事件,此處為keyCode不是keycode
case 37: //左
if (moveLeft()) {
setTimeout("generateOneNumber()", 210); //先要判斷是否能夠向左動,向左動了后會隨機產生一個數字,并判斷游戲是否結束
setTimeout("isgameover()", 300);
}
break;
case 38: //上
if (moveTop()) {
setTimeout("generateOneNumber()", 210);
setTimeout("isgameover()", 300);
}
break;
case 39: //右
if (moveRight()) {
setTimeout("generateOneNumber()", 210);
setTimeout("isgameover()", 300);
}
break;
case 40: //下
if (moveDown()) {
setTimeout("generateOneNumber()", 210);
setTimeout("isgameover()", 300);
}
break;
default:
break;
}
})
這里不加setTimeout的話,會導致已經彈窗游戲結束了,最后一個數字還沒有生成,所以給它加一個時間,分別設定為210ms和300ms,這時就大功告成了,
第一次寫這么長的博客,廢話有點多,觀眾老爺們湊合著看吧,有錯誤的話歡迎大家指出來,共同進步!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/249126.html
標籤:其他
上一篇:開博宣言
下一篇:藍牙耳機NBTC認證怎么辦
