相信不少人都玩過2048小遊戲,規則易懂、操做簡單,我曾經也「癡迷」於它,不到2048不罷休,最高成績合成了4096,如今正好拿它來練練手。javascript
我對於2048的實現,除了使用了現有2048小遊戲的配色,其它全部的代碼都是本身寫的,尤爲是上下左右移動時的邏輯部分,耗費了主要精力。css
在草稿紙上設計、思考邏輯:java
HTML:4x4的棋盤,上下左右方向鍵,開始新遊戲,分數算法
1 <div class="wrapper"> 2 <div class="square" id="s11"></div> 3 <div class="square" id="s12"></div> 4 <div class="square" id="s13"></div> 5 <div class="square" id="s14"></div> 6 <div class="square" id="s21"></div> 7 <div class="square" id="s22"></div> 8 <div class="square" id="s23"></div> 9 <div class="square" id="s24"></div> 10 <div class="square" id="s31"></div> 11 <div class="square" id="s32"></div> 12 <div class="square" id="s33"></div> 13 <div class="square" id="s34"></div> 14 <div class="square" id="s41"></div> 15 <div class="square" id="s42"></div> 16 <div class="square" id="s43"></div> 17 <div class="square" id="s44"></div> 18 <button class="direction" id="up" onclick="up()">↑</button> 19 <button class="direction" id="down" onclick="down()">↓</button> 20 <button class="direction" id="left" onclick="left()">←</button> 21 <button class="direction" id="right" onclick="right()">→</button> 22 <button id="new_game" onclick="new_game()">新遊戲</button> 23 <div id="score"></div> 24 <div id="game_over">遊戲結束!</div> 25 </div>
CSS:棋盤塊配色使用了現有2048配色app
1 <style type="text/css"> 2 .wrapper { 3 width: 420px; 4 height: 420px; 5 background-color: #C3C0B7; 6 margin: 0 auto; 7 border-radius: 15px; 8 position: relative; 9 } 10 .square { 11 float: left; 12 width: 90px; 13 height: 90px; 14 margin: 7.5px; 15 background-color:#FBEFE3; 16 border-radius: 7.5px; 17 color: #59503F; 18 text-align: center; 19 line-height: 90px; 20 font-size: 35px; 21 } 22 .direction { 23 width: 120px; 24 height: 75px; 25 border: none; 26 border-radius: 7.5px; 27 color: white; 28 background-color: #C6BFB9; 29 font-size: 45px; 30 font-weight: bolder; 31 line-height: 75px; 32 } 33 #new_game { 34 width: 120px; 35 height: 75px; 36 border: none; 37 border-radius: 15px; 38 background-color: #C6BFB9; 39 font-size: 30px; 40 color: #FFFBF7; 41 position: absolute; 42 top:430px; 43 left: 0px; 44 } 45 #up { 46 position: absolute; 47 top:430px; 48 left:150px; 49 } 50 #left { 51 position: absolute; 52 top:512px; 53 left:0px; 54 } 55 #right { 56 position: absolute; 57 top:512px; 58 left:300px; 59 } 60 #down { 61 position: absolute; 62 top:512px; 63 left:150px; 64 } 65 #game_over { 66 width: 300px; 67 height: 100px; 68 color: #FFFFFF; 69 border-radius:20px ; 70 background-color: burlywood; 71 font-size: 40px; 72 position: absolute; 73 top: 160px; 74 left: 60px; 75 text-align: center; 76 line-height: 100px; 77 visibility: hidden; 78 } 79 #score { 80 width: 120px; 81 height: 75px; 82 border-radius: 15px; 83 background-color: #C6BFB9; 84 font-size: 20px; 85 color: #FFFBF7; 86 position: absolute; 87 top:430px; 88 left: 300px; 89 text-align: center; 90 line-height: 75px; 91 } 92 </style>
JavaScript:包括標記變量,新遊戲加載函數,新數字生成函數,鍵盤事件綁定控制方向,以及最重要的各個方向的邏輯函數,具體的算法就不描述了,代碼通俗易懂。dom
1 <script type="text/javascript"> 2 var can_up = true; //可向上移動 3 var can_down = true; //可向下移動 4 var can_left = true; //可向左移動 5 var can_right = true; //可向右移動 6 //遊戲結束 7 function game_over() { 8 if(!can_up&&!can_down&&!can_left&&!can_right) { 9 document.getElementById("game_over").style.visibility = "visible"; 10 } 11 } 12 //開始新遊戲 13 function new_game() { 14 document.getElementById("game_over").style.visibility = "hidden"; 15 for(var i = 1;i < 5;i++) { 16 for(var j = 1;j < 5;j++) { 17 document.getElementById("s"+i+j).innerHTML = ""; 18 } 19 } 20 born(); 21 can_up = false; 22 can_down = false; 23 can_left = false; 24 can_right = false; 25 } 26 //鍵盤監聽 27 document.onkeydown = function(event) { 28 switch(event.keyCode) { 29 case 37: left();break; 30 case 38: up();break; 31 case 39: right();break; 32 case 40: down();break; 33 default: ; 34 } 35 } 36 //生成新數字2或者4 37 function born() { 38 var rand_num = Math.random(); 39 var new_num = (rand_num>0.5)?2:4; 40 while(true) { 41 var row = Math.ceil(Math.random()*4); 42 var col = Math.ceil(Math.random()*4); 43 var square = document.getElementById("s"+row+col); 44 if(square.innerHTML =="") { 45 square.innerHTML = new_num; 46 break; 47 } 48 } 49 } 50 //向上移動 51 function up() { 52 var new_square_num = []; 53 var target_square ; 54 var target_exist= false; 55 for(var i =1;i < 5;i++) { 56 for(var j = 2;j < 5;j++) { 57 var self_square = document.getElementById("s"+j+i); 58 if(self_square.innerHTML!="") { 59 for(var k =1;k < j;k++) { 60 var pre_square = document.getElementById("s"+(j-k)+i); 61 if(pre_square.innerHTML=="") { 62 target_square = pre_square ; 63 target_exist = true; 64 } 65 else if(self_square.innerHTML == pre_square.innerHTML && new_square_num[+((j-k).toString()+i)]==undefined ){ 66 pre_square.innerHTML = 2*self_square.innerHTML; 67 document.getElementById("score").innerHTML = +(document.getElementById("score").innerHTML) + (+pre_square.innerHTML); 68 self_square.innerHTML = ""; 69 new_square_num[+((j-k).toString()+i)] = 1; 70 can_up = true; 71 } 72 else { 73 break; 74 } 75 } 76 if(target_exist) { 77 target_square.innerHTML = self_square.innerHTML; 78 self_square.innerHTML = ""; 79 can_up = true; 80 target_exist = false; 81 } 82 } 83 } 84 new_square_num = []; 85 } 86 if(can_up) { 87 born(); 88 can_up = false; 89 } 90 91 } 92 //向下移動 93 function down() { 94 var new_square_num = []; 95 var target_square ; 96 var target_exist= false; 97 for(var i =1;i < 5;i++) { 98 for(var j = 3;j > 0;j--) { 99 var self_square = document.getElementById("s"+j+i); 100 if(self_square.innerHTML!="") { 101 for(var k =j+1;k < 5;k++) { 102 var pre_square = document.getElementById("s"+k+i); 103 if(pre_square.innerHTML=="") { 104 target_square = pre_square ; 105 target_exist = true; 106 } 107 else if(self_square.innerHTML == pre_square.innerHTML && new_square_num[+((k).toString()+i)]==undefined ){ 108 pre_square.innerHTML = 2*self_square.innerHTML; 109 document.getElementById("score").innerHTML = +(document.getElementById("score").innerHTML) + (+pre_square.innerHTML); 110 self_square.innerHTML = ""; 111 new_square_num[+((k).toString()+i)] = 1; 112 can_down = true; 113 target_exist = false; 114 } 115 else { 116 break; 117 } 118 } 119 if(target_exist) { 120 target_square.innerHTML = self_square.innerHTML; 121 self_square.innerHTML = ""; 122 can_down = true; 123 target_exist = false; 124 } 125 } 126 } 127 new_square_num = []; 128 } 129 if(can_down) { 130 born(); 131 can_down = false; 132 } 133 } 134 //向左移動 135 function left() { 136 var new_square_num = []; 137 var target_square ; 138 var target_exist= false; 139 for(var j =1;j < 5;j++) { 140 for(var i = 2;i < 5;i++) { 141 var self_square = document.getElementById("s"+j+i); 142 if(self_square.innerHTML!="") { 143 for(var k =1;k < i;k++) { 144 var pre_square = document.getElementById("s"+j+(i-k)); 145 if(pre_square.innerHTML=="") { 146 target_square = pre_square ; 147 target_exist = true; 148 } 149 else if(self_square.innerHTML == pre_square.innerHTML && new_square_num[+(j+(i-k).toString())]==undefined ){ 150 pre_square.innerHTML = 2*self_square.innerHTML; 151 document.getElementById("score").innerHTML = +(document.getElementById("score").innerHTML) + (+pre_square.innerHTML); 152 self_square.innerHTML = ""; 153 new_square_num[+(j+(i-k).toString())] = 1; 154 can_left = true; 155 target_exist = false; 156 } 157 else { 158 break; 159 } 160 } 161 if(target_exist) { 162 target_square.innerHTML = self_square.innerHTML; 163 self_square.innerHTML = ""; 164 can_left = true; 165 target_exist = false; 166 } 167 } 168 } 169 new_square_num = []; 170 } 171 if(can_left) { 172 born(); 173 can_left = false; 174 } 175 } 176 //向右移動 177 function right() { 178 var new_square_num = []; 179 var target_square ; 180 var target_exist= false; 181 for(var j =1;j < 5;j++) { 182 for(var i = 3;i > 0;i--) { 183 var self_square = document.getElementById("s"+j+i); 184 if(self_square.innerHTML!="") { 185 for(var k =i+1;k < 5;k++) { 186 var pre_square = document.getElementById("s"+j+k); 187 if(pre_square.innerHTML=="") { 188 target_square = pre_square ; 189 target_exist = true; 190 } 191 else if(self_square.innerHTML == pre_square.innerHTML && new_square_num[+(j.toString()+k)]==undefined ){ 192 pre_square.innerHTML = 2*self_square.innerHTML; 193 document.getElementById("score").innerHTML = +(document.getElementById("score").innerHTML) + (+pre_square.innerHTML); 194 self_square.innerHTML = ""; 195 new_square_num[+(j.toString()+k)] = 1; 196 can_right = true; 197 target_exist = false; 198 } 199 else { 200 break; 201 } 202 } 203 if(target_exist) { 204 target_square.innerHTML = self_square.innerHTML; 205 self_square.innerHTML = ""; 206 can_right = true; 207 target_exist = false; 208 } 209 } 210 } 211 new_square_num = []; 212 } 213 if(can_right) { 214 born(); 215 can_right = false; 216 } 217 } 218 //塗色 219 setInterval(function paint() { 220 for(var i = 1;i < 5;i++) { 221 for(var j = 1;j < 5;j++) { 222 var square = document.getElementById("s"+i+j); 223 switch(square.innerHTML) { 224 case "2" :square.style.backgroundColor = "#EEE4DA"; 225 square.style.color = "#766D64"; 226 break; 227 case "4" :square.style.backgroundColor = "#ECE0C8"; 228 square.style.color = "#786D67"; 229 break; 230 case "8" :square.style.backgroundColor = "#F2B179"; 231 square.style.color = "#F6F7F2"; 232 break; 233 case "16" :square.style.backgroundColor = "#F59565"; 234 square.style.color = "#FAF6F5"; 235 break; 236 case "32" :square.style.backgroundColor = "#F77B5F"; 237 square.style.color = "#FBF3F0"; 238 break; 239 case "64" :square.style.backgroundColor = "#F35F3B"; 240 square.style.color = "#FAF4F4"; 241 break; 242 case "128" :square.style.backgroundColor = "#EDCE71"; 243 square.style.color = "#F8FAF7"; 244 break; 245 case "256" :square.style.backgroundColor = "#EDCC61"; 246 square.style.color = "#FAF6F7"; 247 break; 248 case "512" :square.style.backgroundColor = "#ECC850"; 249 square.style.color = "#FAF4F6"; 250 break; 251 case "1024" :square.style.backgroundColor = "#EDC53F"; 252 square.style.color = "#F9F4FA"; 253 break; 254 case "2048" :square.style.backgroundColor = "#E9B501"; 255 square.style.color = "#FFFCB0"; 256 break; 257 case "4096" :square.style.backgroundColor = "#FCEDD8"; 258 square.style.color = "#524B39"; 259 break; 260 default:square.style.backgroundColor = "#FBEFE3"; 261 } 262 } 263 } 264 },10); 265 266 </script>
效果圖:ide
雖然小遊戲簡單,可是實現了也是本身的成果,也是一種進步!函數