2048 小游戏 Demo
这也是博主第一次用JS写小游戏,之前有写过一些动态的效果,但是逻辑性较强的游戏方面,的确我很薄弱,所以目前的实际效果似乎并不完善,还存在小小的bug....
全部代码如下所示:
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <link href="2048.css" type="text/css" rel="stylesheet"> 6 <title></title> 7 </head> 8 <body> 9 <p id="score"> SCORE:<span id="scoreNum"></span></p> 10 <div id="gridPanel"> 11 <div id="c00"></div> 12 <div id="c01"></div> 13 <div id="c02"></div> 14 <div id="c03"></div> 15 16 <div id="c10"></div> 17 <div id="c11"></div> 18 <div id="c12"></div> 19 <div id="c13"></div> 20 21 <div id="c20"></div> 22 <div id="c21"></div> 23 <div id="c22"></div> 24 <div id="c23"></div> 25 26 <div id="c30"></div> 27 <div id="c31"></div> 28 <div id="c32"></div> 29 <div id="c33"></div> 30 </div> 31 <div id="gameOver"> 32 <p> 33 朋友 , 你输了,哈哈哈<br/> 34 SCORE:<span id="final">0</span><br/><br/> 35 <a href="javascript:start()">TRY AGAIN</a> 36 </p> 37 </div> 38 <script src="2048.js"> 39 40 </script> 41 </body> 42 </html>
css代码:
1 #gridPanel{ 2 width: 480px;height: 480px; 3 margin: 0 auto; 4 border-radius: 10px; 5 background: #b2dcb7; 6 } 7 div>div{ 8 width: 100px;height: 100px; 9 border-radius: 6px; background: #c3ffc8; 10 float: left;margin-top: 16px;margin-left: 16px; 11 color: white;font-size: 60px;text-align: center; 12 line-height: 100px; 13 } 14 .n2{ 15 background-color: #88db75; 16 } 17 .n4{ 18 background-color: #55c377; 19 } 20 .n8{ 21 background-color: #a0f644; 22 } 23 .n16{ 24 background-color: #29c2a3; 25 } 26 .n32{ 27 background-color: #b5df3f; 28 } 29 .n64{ 30 background-color: #b4eb5b; 31 } 32 .n128{ 33 background-color: #04e083; 34 } 35 .n256{ 36 background-color: #c6ffd2; 37 } 38 .n512{ 39 background-color: #22dae5; 40 } 41 .n1024{ 42 background-color: #99c988; 43 } 44 .n2048{ 45 background-color:green; 46 } 47 .n4096{ 48 background-color: #ff1318; 49 } 50 .n2,.n4{ 51 color: #1e201b; 52 } 53 .n1024,.n2048,.n4096{ 54 font-size: 40px; 55 } 56 p{ 57 width: 480px; 58 margin: 0 auto; 59 font-size: 40px; 60 font-weight: bold; 61 padding-top: 15px; 62 color: red; 63 } 64 #scoreNum{ 65 font-size: 40px; 66 font-weight: bold; 67 padding-top: 15px; 68 color: red; 69 } 70 #gameOver{ 71 position: absolute; 72 top:0px; 73 left: 0px; 74 right: 0; 75 bottom: 0; 76 background: rgba(5,5,5,.5); 77 display: none; 78 } 79 #gameOver p{ 80 width: 500px; 81 height: 300px; 82 background: white; 83 position: absolute; 84 /*top: 0;left: 0;*/ 85 /*right: 0;*/ 86 /*bottom: 0;*/ 87 /*margin: auto;*/ 88 top: 50%; 89 left: 50%; 90 margin-top:-150px; 91 margin-left: -250px; 92 text-align: center; 93 line-height: 1.5em; 94 border-radius: 10px; 95 border: 1px solid saddlebrown; 96 97 } 98 #gameOver a{ 99 padding: 10px ; 100 text-decoration: none; 101 color: white; 102 background-color: black; 103 }
JS代码:
1 /* 2 * 定义数组data 3 * 声明两个变量RN,CN 4 * 创建一个空数组 5 * 遍历这个数组,从R开始,到RN结束 6 * 压入一个空数组 7 * 从C开始,到CN结束 8 * 向data中压入一个0 9 * 手动输入data.join("\n"); 10 * */ 11 var data = null; 12 var RN = 4, CN = 4; 13 var score=0;//得分 14 status=0,GAMEOVER=0,RUNNING=1; 15 function start() { 16 //把游戏状态设置为运行中; 17 status=RUNNING; 18 score=0; 19 data = []; 20 for (var r = 0; r < RN; r++) { 21 data.push([]); 22 for (var c = 0; c < CN; c++) { 23 data[r].push(0); 24 } 25 } 26 randomNum(); 27 randomNum(); 28 updateView(); 29 console.log(data.join("\n")); 30 document.onkeydown=function(e){ 31 console.log(e.keyCode); 32 switch (e.keyCode){ 33 case 37: 34 moveLeft(); 35 break; 36 case 38: 37 moveUp(); 38 break; 39 case 39: 40 moveRight(); 41 break; 42 case 40: 43 moveDown(); 44 break; 45 46 } 47 } 48 } 49 50 function randomNum() { 51 while (true) { 52 53 //在随机位置产生 data[r][c].MAth.random()*RN; 54 var r = parseInt(Math.random() * RN); 55 var c = parseInt(Math.random() * CN); 56 //随机生成2和4 57 if (data[r][c] == 0) { 58 data[r][c] = Math.random() > 0.5 ? "2" : "4"; 59 break; 60 } 61 //console.log(r,c); 62 } 63 } 64 //刷新页面 65 function updateView(){ 66 //遍历data 67 //用id查找对应的div var div=document.getElementById("c"+r+c); 68 //divID.className="";div.className="n"+data[r][c]; 69 //设置div 70 //如果r行c列为零,则把div内容清除 var r="";(空字符串) 71 //否则就等于data[r][c]; 72 for(var r=0;r<RN;r++){ 73 for(var c=0;c<CN;c++){ 74 var divID=document.getElementById("c"+r+c); 75 if(data[r][c]==0){ 76 divID.innerHTML=""; 77 divID.className=""; 78 }else{ 79 divID.innerHTML=data[r][c]; 80 divID.className="n"+data[r][c]; 81 } 82 } 83 } 84 document.getElementById("scoreNum").innerHTML=score; 85 var gameOverDiv=document.getElementById("gameOver"); 86 var scoreSpan=document.getElementById("final"); 87 if(status==GAMEOVER){ 88 gameOverDiv.style.display="block"; 89 scoreSpan.innerHTML=score; 90 }else{ 91 gameOverDiv.style.display="none"; 92 } 93 } 94 function moveLeft(){ 95 //var before=String(data); 96 for(var r=0;r<RN;r++){ 97 moveLeftInRow(r); 98 } 99 randomNum(); 100 if(isGameOver()){ 101 status=GAMEOVER; 102 }; 103 updateView(); 104 //左移后的样子 105 //var after=String(data); 106 //if(before!=after){ 107 // 108 //} 109 } 110 //行内左移一行 111 function moveLeftInRow(r){ 112 for(var c=0;c<CN-1;c++){ 113 var nextc=getNextInRow(r,c); 114 if(nextc !=-1){ 115 if(data[r][c]==0){ 116 console.log(1); 117 data[r][c]= data[r][nextc]; 118 data[r][nextc]=0; 119 c--; 120 }else if(data[r][c]==data[r][nextc]){ 121 console.log(2); 122 data[r][c]= data[r][c]*2; 123 score+=data[r][c]; 124 data[r][nextc]=0; 125 } 126 }else if(nextc==-1){break;} 127 } 128 } 129 function getNextInRow(r,c){ 130 //nextc从c+1,到CN-1结束; 131 //如果r行c列的位置不为零, 132 //就返回给nextc 133 for(var nextc=c+1;nextc<=CN-1;nextc++){ 134 if(data[r][nextc]!=0){ 135 return nextc; 136 } 137 } 138 return -1; 139 } 140 141 //右移 142 function moveRight(){ 143 //var before=String(data); 144 for(var r=0;r<RN;r++){ 145 moveRightInRow(r); 146 } 147 randomNum(); 148 if(isGameOver()){ 149 status=GAMEOVER; 150 }; 151 152 updateView(); 153 //var after=String(data); 154 //if(before!=after){ 155 // 156 //} 157 }; 158 function moveRightInRow(r){ 159 for(var c=CN-1;c>0;c--){ 160 var prec=getPreInRow(r,c); 161 if(prec !=-1){ 162 if(data[r][c]==0){ 163 console.log(1); 164 data[r][c]= data[r][prec]; 165 data[r][prec]=0; 166 c++; 167 }else if(data[r][c]==data[r][prec]){ 168 console.log(2); 169 data[r][c]= data[r][c]*2; 170 score+=data[r][c]; 171 data[r][prec]=0; 172 } 173 }else if(prec==-1){break;} 174 } 175 }; 176 function getPreInRow(r,c){ 177 for(var prec=c-1;prec>=0;prec--){ 178 if(data[r][prec]!=0){ 179 return prec; 180 } 181 } 182 return -1; 183 }; 184 185 //上移 186 function moveUp(){ 187 //var before=String(data); 188 for(var c=0;c<CN;c++){ 189 moveUpInCol(c); 190 } 191 randomNum(); 192 if(isGameOver()){ 193 status=GAMEOVER; 194 }; 195 196 updateView(); 197 //左移后的样子 198 //var after=String(data); 199 //if(before!=after){ 200 // 201 //} 202 }; 203 function moveUpInCol(c){ 204 for(var r=0;r<RN-1;r++){ 205 var nextr=getNextCol(r,c); 206 if(nextr !=-1){ 207 if(data[r][c]==0){ 208 console.log(1); 209 data[r][c]= data[nextr][c]; 210 data[nextr][c]=0; 211 r--; 212 }else if(data[r][c]==data[nextr][c]){ 213 console.log(2); 214 data[r][c]= data[r][c]*2; 215 score+=data[r][c]; 216 data[nextr][c]=0; 217 } 218 }else if(nextr==-1){break;} 219 } 220 }; 221 function getNextCol(r,c){ 222 for(var nextr=r+1;nextr<=RN-1;nextr++){ 223 if(data[nextr][c]!=0){ 224 return nextr; 225 } 226 } 227 return -1; 228 }; 229 230 //下移 231 232 function moveDown(){ 233 //var before=String(data); 234 for(var c=0;c<CN;c++){ 235 moveDownInCol(c); 236 } 237 randomNum(); 238 if(isGameOver()){ 239 status=GAMEOVER; 240 }; 241 updateView(); 242 //var after=String(data); 243 //if(before!=after){ 244 // 245 //} 246 }; 247 function moveDownInCol(c){ 248 for(var r=RN-1;r>0;r--){ 249 var prer=getPreCol(r,c); 250 if(prer !=-1){ 251 if(data[r][c]==0){ 252 console.log(1); 253 data[r][c]= data[prer][c]; 254 data[prer][c]=0; 255 r++; 256 }else if(data[r][c]==data[prer][c]){ 257 console.log(2); 258 data[r][c]= data[r][c]*2; 259 score+=data[r][c]; 260 data[prer][c]=0; 261 } 262 }else if(prer==-1){break;} 263 } 264 }; 265 function getPreCol(r,c){ 266 for(var prer=r-1;prer>=0;prer--){ 267 if(data[prer][c]!=0){ 268 return prer; 269 } 270 } 271 return -1; 272 }; 273 274 //判断游戏结束 275 function isGameOver(){ 276 for(var r=0;r<RN;r++){ 277 for(var c=0;c<CN;c++){ 278 if(data[r][c]==0){ 279 return false; 280 } 281 if(c<CN-1 && data[r][c]==data[r][c+1]){ 282 return false; 283 } 284 if(r<RN-1 && data[r][c]==data[r+1][c]){ 285 return false; 286 } 287 } 288 } 289 return true; 290 291 } 292 293 start();
不足之处,望各位指正
想要这样一间小木屋,夏天挫冰吃瓜,冬天围炉取暖.