JQuery實現1024小遊戲

最近用Jqery寫了一個1024小遊戲,因爲是第一次寫小遊戲,因此就選了一個基礎的沒什麼難度遊戲。具體實現以下:css

首先在開發時將整個遊戲分紅兩層(自認爲),底層是遊戲的數據結構以及對數據的操做,上層是顯示出來的用戶界面。底層選擇使用一個4x4的二維數組,整個遊戲的數據操做都圍繞着這個二維數組進行。數組

【一】遊戲基礎界面

 1 <div id="game">
 2         <div id="header">
 3             <h1>1024</h1>
 4             <button id="newGame">開始新的遊戲</button>
 5             <p>分數:<span id="score">0</span>&nbsp;&nbsp;&nbsp;&nbsp;最高分:<span id="maxScore">0</span></p>
 6             <div id="movescore"><p>+16</p></div>
 7         </div>
 8         <div id="container">
 9             <div class="cell" id="cell-0-0"></div>
10             <div class="cell" id="cell-0-1"></div>
11             <div class="cell" id="cell-0-2"></div>
12             <div class="cell" id="cell-0-3"></div>
13             <div class="cell" id="cell-1-0"></div>
14             <div class="cell" id="cell-1-1"></div>
15             <div class="cell" id="cell-1-2"></div>
16             <div class="cell" id="cell-1-3"></div>
17             <div class="cell" id="cell-2-0"></div>
18             <div class="cell" id="cell-2-1"></div>
19             <div class="cell" id="cell-2-2"></div>
20             <div class="cell" id="cell-2-3"></div>
21             <div class="cell" id="cell-3-0"></div>
22             <div class="cell" id="cell-3-1"></div>
23             <div class="cell" id="cell-3-2"></div>
24             <div class="cell" id="cell-3-3"></div>
25         </div>
26         <div class="gameover">
27             <div id="gameoverText">
28                 <p></p>
29             </div>
30             <p id="gameoverScore"></p>
31             <div id="reStart">
32                 <button id="reStartBtn">再玩一次</button>
33             </div>
34         </div>
35      </div>

CSS:數據結構

 1 *{
 2  margin: 0;
 3  padding: 0;
 4         }
 5  #game{
 6  font-family: Arial;
 7  margin: 0 auto;
 8  text-align: center;
 9         }
10  #header{
11  margin: 20px;
12         }
13  #header a{
14  font-family: Arial;
15  text-decoration: none;/*設置 h一、h二、h三、h4 元素的文本修飾*/
16  display: block;
17  color: white;
18  margin: 20px auto;
19  width: 125px;
20  height: 35px;
21  text-align: center;
22  line-height: 40px;
23  background-color: #8f7a66;
24  border-radius: 10px;
25  font-size: 15px;
26         }
27  #header p{
28  font-family: Arial;
29  font-size: 20px;
30         }
31  #container{
32  width: 460px;
33  height: 460px;
34  background-color: #bbada0;
35  margin: 0 auto;
36  border-radius: 10px;
37  position: relative;
38  padding: 20px;
39         }
40  .cell{
41  width: 100px;
42  height: 100px;
43  border-radius: 6px;
44  background-color: #ccc0b3;
45  position: absolute;
46  font-size: 3.5em;
47  font-weight:700;
48  text-align: center;
49  line-height:100px;
50         }
51  #newGame{
52  width: 120px;
53  height: 30px;
54  border-radius: 5px;
55  border: 1px solid rgb(143,122,102);
56  background-color: rgb(143,122,102);
57  color: white;
58  margin-top: 10px;
59  margin-bottom: 10px;
60         }
61  .gameover{
62  width: 100%;
63  height: 500px;
64  background-color: rgba(255,255,255,0.5);
65  position: absolute;
66  top:153px;
67  display: none;
68         }
69  #gameoverText{
70  font-size: 4em;
71  font-weight: 600;
72  color: #363636;
73  text-align: center;
74  opacity: 1;
75  padding-top: 10%;
76         }
77  #reStartBtn{
78  width: 100px;
79  height: 40px;
80  border-radius: 5px;
81  border: 1px solid rgb(143,122,102);
82  background-color: rgb(143,122,102);
83  color: white;
84  margin-top: 3%;
85         }
86  #gameoverScore{
87  font-size: 1.5em;
88         }
89  #movescore{
90  position: absolute;
91  text-align: center;
92  padding-left: 45%;
93  top:110px;
94  font-weight: 600;
95  display: none;
96         }

此時界面的16個格子是重疊在一塊兒的,給每一個格子寫css比較麻煩,因此經過js循環進行設置:dom

1 //初始化繪製表格
2 function printTab(){ 3     for(var i=0;i<4;i++){ 4         for(var j=0;j<4;j++){ 5             var cell=$('#cell-'+i+'-'+j); 6             cell.css({top:(20+i*120),left:(20+j*120)}); 7  } 8  } 9 }

不一樣的數字顯示不一樣的背景顏色與文字顏色:ide

 1           function getBackgroundColor(number){  2                 switch (number) {  3                     case 2:return "#eee4da";break;  4                     case 4:return "#ede0c8";break;  5                     case 8:return "#f2b179";break;  6                     case 16:return "#f59563";break;  7                     case 32:return "#f67c5f";break;  8                     case 64:return "#f65e3b";break;  9                     case 128:return "#edcf72";break; 10                     case 256:return "#edcc61";break; 11                     case 512:return "#9c0";break; 12                     case 1024:return "#33b5e5";break; 13                     case 2048:return "#09c";break; 14                     case 4096:return "#a6c";break; 15                     case 8192:return "#93c";break; 16  } 17  } 18             // 設置相應數字的文字顏色
19             function getColor(number){ 20                 if (number <= 4) { 21                     return "#776e65"
22  } 23                 return "white"; 24             }

每次操做後根據當前二維數組進行重繪畫面:函數

 1 //根據二維數組繪製畫面
 2 function rePrint(checkerboard){  3     for(var i=0;i<4;i++){  4         for(var j=0;j<4;j++){  5             if(checkerboard[i][j]!=0){  6                 var printCell=$('#cell-'+i+'-'+j);  7                 printCell.css('background-color',getBackgroundColor(checkerboard[i][j]));  8                 printCell.css('color',getColor(checkerboard[i][j]));  9  printCell.text(checkerboard[i][j]); 10                 if(checkerboard[i][j]>=1024){ 11                     printCell.css('font-size','2.5em'); 12                     printCell.css('font-weight','500'); 13  } 14             }else{ 15                 var printCell=$('#cell-'+i+'-'+j); 16                 printCell.css('background-color','#ccc0b3'); 17                 printCell.css('color','black'); 18                 printCell.text(''); 19  } 20  } 21  } 22 }

 【二】遊戲邏輯

除了須要定義一個二維數組checkerboard,還須要定義一個存總分的變量score,一個存每次操做得分的變量addScore,一個記錄鍵盤是否能夠操做的變量ableKeyDown,0能夠響應鍵盤操做,1禁止鍵盤操做。動畫

①遊戲初始化

初始化封裝成一個函數方便後續的【開始新的遊戲】以及【再玩一次】功能。spa

 1 //初始化遊戲 
 2 function newgame(){  3     ableKeyDown=0;  4     score=0;  5     checkerboard=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];  6     $('#score').text('0');  7     $('#maxScore').text(window.localStorage.getItem("maxScore"));  8  rePrint(checkerboard);  9  randNum(checkerboard); 10  randNum(checkerboard); 11 }

②在隨即位置生成2或4

根據遊戲規則,在遊戲剛開始時會在兩個隨即位置分別生成2或4,在每次操做後若遊戲沒結束,會在一個空的位置隨機生成一個2或4,將這一功能封裝成一個函數,Math.random()生成的隨機數範圍是[0,1),因爲二維數組範圍是[0,3],因此經過Math.floor(Math.random()*4)將獲得0-3的隨機數。另外須要隨機獲得2或4,定義一個數組initRandNum=[2,4],只需隨機獲得initRandNum[0]或initRandNum[1]便可,因此同理使用Math.floor(Math.random()*2)隨機獲得1或2便可。3d

 1 function randNum(checkerboard){//在隨機位置隨機產生2或4  2         var randX = Math.floor(Math.random()*4);  3         var randY = Math.floor(Math.random()*4);  4         var initRandNum=[2,4];  5         var randNum=Math.floor(Math.random()*2);  6         var randVal=initRandNum[randNum];  7         while(true){  8             if(checkerboard[randX][randY]==0){  9                 break; 10             }else{ 11                 var randX = Math.floor(Math.random()*4); 12                 var randY = Math.floor(Math.random()*4); 13  } 14  } 15         checkerboard[randX][randY]=randVal; 16  printRandNum(randX,randY,randVal);//將randNum()繪製出來 17 }

在獲得上述隨即位置的2或4後須要將其繪製出來:code

1 function printRandNum(randX,randY,randVal){ 2     var printRandCell=$('#cell-'+randX+'-'+randY); 3     printRandCell.css('background-color',getBackgroundColor(randVal)); 4     printRandCell.css('color',getColor(randVal)); 5  printRandCell.text(randVal); 6 }

③遊戲中最重要的兩個函數

即判斷當前可否移動的函數以及如何移動合併的函數。

1)--------判斷可否移動,以左移爲例

根據對遊戲的觀察發如今兩中狀況下能夠移動,一是存在某個不爲零的方塊,該數字左邊爲空,即其左邊的數組值爲0;二是存在某個不爲零的方塊,,該數字左邊與其相同,即其左邊的數組值與其相等。對二維數組進行循環,若知足上述條件就返回1,便可以移動。

 1 function canMoveLeft(checkerboard){  2     for(var i=0;i<4;i++){  3         for(var j=0;j<4;j++){  4             if(checkerboard[i][j]!=0){  5                 if(j!=0){  6                     if(checkerboard[i][j-1]==0||checkerboard[i][j-1]==checkerboard[i][j]){  7                         return 1;  8                         break;  9  } 10  } 11  } 12  } 13  } 14 }

2)--------移動合併函數,以左移爲例

這個應該是遊戲中最重要的函數,根據遊戲規則,1)若一個非零方塊左邊所有爲空,它將移動到最左邊,若左邊的某個不爲0,它將移動到這個不爲0方塊的右邊;2)若一個非零方塊與左邊的數字相同,它將移動到左邊並與之合併相加;3)若一個非零方塊與左邊的數字相同,他與左邊合併後的值恰巧與再左邊的數相同,此時應該只進行第一次合併,不進行第二次合併。例如當前一排是4,2,2,0,其移動後結果應該是4,4,0,0,而不是8,0,0,0。

第三點尤其重要,最開始因爲忽略了這點寫出來後結果是不對的。我真對3)的解決辦法是,在每次循環一行時初始化一個長度爲4的數組var tag=[0,0,0,0],若某個數在這次循環制相加過一次,就在tag相應位置置爲1,再而後在每次合併前作一次判斷,若該tag爲1,則不進行相加。

 1 function moveLeft(checkerboard){  2     addscore=0;  3     for(var i=0;i<4;i++){  4         var tag=[0,0,0,0];  5         for(var j=1;j<4;j++){ 7             if(checkerboard[i][j]!=0){  8                 if(checkerboard[i][j-1]==0){//左邊爲空時
 9                     for(k=j-1;k>=0;k--){ 10                         if(checkerboard[i][k]!=0){ 11                             checkerboard[i][k+1]=checkerboard[i][j]; 12                             checkerboard[i][j]=0; 13                             if(checkerboard[i][k+1]==checkerboard[i][k]){//移動後與左邊相等
14                                 if(tag[k]==0&&tag[k+1]==0){ 15                                     checkerboard[i][k]+=checkerboard[i][k+1]; 16                                     score += checkerboard[i][k]; 17                                     addscore+=checkerboard[i][k]; 18                                     tag[k]=1;20                                     checkerboard[i][k+1]=0; 21  } 22  } 23                             break; 24                         }else if(k==0){//左邊全空
25                             checkerboard[i][0]=checkerboard[i][j]; 26                             checkerboard[i][j]=0; 27                             break; 28  } 29  } 30                 }else if(checkerboard[i][j-1]==checkerboard[i][j]){//左邊相等時
31                     if(tag[j-1]==0&&tag[j]==0){ 32                         checkerboard[i][j-1]+=checkerboard[i][j]; 33                         score += checkerboard[i][j-1]; 34                         addscore+=checkerboard[i][j-1]; 35                         tag[j-i]=1;37                         checkerboard[i][j]=0; 38  } 39  } 40  } 41  } 42  } 43     rePrint(checkerboard);//中止移動後重繪畫面
44 }

值得注意的是,爲了計算遊戲的總分以及每次操做的得分,須要在每次合併後對addScore和score進行計算。

右移、上移、下移與左移邏輯基本相同,只需對左移代碼稍做修改便可。

④關於分數

1 //更新分數
2 function updateScore(num){ 3     $('#score').text(num); 4 }

在每次得分後會在總分位置產生一個加分動畫

 

 1 //分數動畫 
 2 function movescore(score){  3     if(score>0){  4         $('#movescore p').text('+'+score);  5         $('#movescore').css('top','110px');  6         $('#movescore').show();  7         var top;  8         var topVal=110;  9         var opacityVal=1; 10         var timer=null; 11         timer=setInterval(function(){ 12             topVal-=5; 13             opacityVal-=0.1; 14             top=topVal+'px'; 15             $('#movescore').css('top',top); 16             $('#movescore').css('opacity',opacityVal); 17             if(topVal<50){ 18  clearInterval(timer); 19                 $('#movescore').hide(); 20  } 21         },40); 22  } 23 }

⑤遊戲結束

若二維數組中某一項等於1024遊戲結束,顯示最終得分,並設置鍵盤不可繼續操做;或者當前沒法繼續移動遊戲結束,顯示最終得分。

 1 //遊戲結束函數
 2 function gameOver(checkerboard){  3     if(canMoveLeft(checkerboard)!=1&&canMoveRight(checkerboard)!=1&&canMoveUp(checkerboard)!=1&&canMoveDown(checkerboard)!=1){  4         $('.gameover').show();  5         $('#gameoverText p').text('Game Over !');  6         $('#gameoverScore').text('最終得分'+score);  7         if(score>window.localStorage.getItem("maxScore")){  8             window.localStorage.setItem("maxScore",score);  9             $('#maxScore').text(window.localStorage.getItem("maxScore")); 10  } 11  } 12     for(var i=0;i<4;i++){ 13         for(var j=0;j<4;j++){ 14             if(checkerboard[i][j]==1024){ 15                 ableKeyDown=1;//鍵盤不可操做
16                 $('.gameover').show(); 17                 $('#gameoverText p').text('Congratulations!'); 18                 $('#gameoverScore').text('最終得分'+score); 19                 if(score>window.localStorage.getItem("maxScore")){ 20                     window.localStorage.setItem("maxScore",score); 21                     $('#maxScore').text(window.localStorage.getItem("maxScore")); 22  } 23                 break; 24  } 25  } 26  } 27 }

⑥開始新遊戲&再玩一次

1 //開始新遊戲
2 $('#newGame').click(function(){ 3  newgame(); 4 }); 5 //再玩一次
6 $('#reStartBtn').click(function(){ 7     $('.gameover').hide(); 8  newgame(); 9 });
相關文章
相關標籤/搜索