用到的技术:HTML、CSS、原生JAVASCRIPT
用到的JS知识点:
事件监听器、多维数组等
效果:
思路:
利用table标签画出框架,建立一个多维数组来存储每个td里的数字,添加一个全局键盘事件监听器,监听键盘上下左右键。
根据用户按下的方向键,来操作多维数组,操作完成后再显示到td的innerHTML中。
方法解释:
show() 将多维数组中的数字赋值给td中的innerHtml,如果该位置的数字为0,那就不显示
innitial() 初始化,在第一行随机产生一开始的数字
generate() 遍历所有单元格,随机在一个位置生成一个新的“2”
move() 最难写的一个方法,也是本游戏的核心
它根据用户输入来操作数组:比如用户按了“上”方向键,首先从上到下将每个单元格与上方单元格比较,
如果相等,那么上方单元格的值乘以2,该单元格值为零。
处理完成后,玩过2048的都知道,0是不占空的,所以需要将所有非零数字向上方移动。
这里使用的方法是建立一个临时数组,将所有非零数字存到临时数组中,再将临时数组的每个值传回位置。
其它3个方向上,根据遍移动的方向调整代码即可
代码实现:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>2048</title> <style rel="stylesheet" type="text/css"> div{ margin:0px auto; width: 440px; height: 440px; } table{ border: 2px red solid; position:relative; } td{ border:2px red solid; width: 100px; height:100px; text-align: center; font-size:60px; font-weight: bolder; position: relative; transition: transform 0.2s; } h1{ text-align: center; } p{ text-align: center; } </style> </head> <body> <div> <h1>2048低配版</h1> <p>操作说明:使用键盘方向键控制</p> <table> <tr> <td>2</td> <td>2</td> <td>2</td> <td>4</td> </tr> <tr> <td>0</td> <td>0</td> <td>0</td> <td>0</td> </tr> <tr> <td>0</td> <td>0</td> <td>0</td> <td>0</td> </tr> <tr> <td>2</td> <td>0</td> <td>0</td> <td>2</td> </tr> </table> </div> <script type = "text/javascript"> var rowscols = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]; var maintable = document.getElementsByTagName("table")[0]; document.addEventListener("keyup",keyboardListener,false); function show(){ for(j in maintable.rows){ for(i in maintable.rows[j].cells){ if(rowscols[j][i]==0){ maintable.rows[j].cells[i].innerHTML = " " }else{ maintable.rows[j].cells[i].innerHTML = rowscols[j][i]; } } } } function innitial(){ for(i in rowscols[0]){ rowscols[0][i] = ((Math.floor(Math.random()*10))%3)*2; } } function generate(){ for(j in maintable.rows){ for(i in maintable.rows[j].cells){ if(rowscols[j][i]==0&&Math.random()>0.8){ rowscols[j][i] = 2; return true; } } } return false; } function move(inputChar){ if(inputChar == "U"){ for(var i = 0;i<4;i++){ for(var j = 1;j<=3;j++){ if(rowscols[j-1][i] == rowscols[j][i]){ rowscols[j-1][i]*=2; rowscols[j][i] = 0; } } var tempArray = [0,0,0,0]; var tempIndex = 0; for(var j = 0;j<=3;j++){ if(rowscols[j][i]!=0){ tempArray[tempIndex] = rowscols[j][i]; tempIndex++; } } for(j = 0;j<4;j++){ rowscols[j][i] = tempArray[j]; } } } if(inputChar == "D"){ for(var i = 0;i<4;i++){ for(var j = 2;j>=0;j--){ if(rowscols[j+1][i] == rowscols[j][i]){ rowscols[j][i]*=2; rowscols[j+1][i] = 0; } } var tempArray = [0,0,0,0]; var tempIndex = 3; for(var j = 3;j>=0;j--){ if(rowscols[j][i]!=0){ tempArray[tempIndex] = rowscols[j][i]; tempIndex--; } } for(j = 3;j>=0;j--){ rowscols[j][i] = tempArray[j]; } } } if(inputChar == "L"){ for(var j = 0;j<4;j++){ for(var i = 1;i<=3;i++){ if(rowscols[j][i-1] == rowscols[j][i]){ rowscols[j][i-1]*=2; rowscols[j][i] = 0; } } var tempArray = [0,0,0,0]; var tempIndex = 0; for(var i = 0;i<=3;i++){ if(rowscols[j][i]!=0){ tempArray[tempIndex] = rowscols[j][i]; tempIndex++; } } for(i = 0;i<4;i++){ rowscols[j][i] = tempArray[i]; } } } if(inputChar == "R"){ for(var j = 0;j<4;j++){ for(var i = 2;i>=0;i--){ if(rowscols[j][i+1] == rowscols[j][i]){ rowscols[j][i+1]*=2; rowscols[j][i] = 0; } } var tempArray = [0,0,0,0]; var tempIndex = 3; for(var i = 3;i>=0;i--){ if(rowscols[j][i]!=0){ tempArray[tempIndex] = rowscols[j][i]; tempIndex--; } } for(i = 3;i>=0;i--){ rowscols[j][i] = tempArray[i]; } } } } function addColor(){ for(var j = 0;j<4;j++){ for(var i = 0;i<4;i++){ switch(Math.log2(rowscols[j][i])){ case 1: maintable.rows[j].cells[i].style.color = "red"; break; case 2: maintable.rows[j].cells[i].style.color = "blue"; break; case 3: maintable.rows[j].cells[i].style.color = "green"; break; case 4: maintable.rows[j].cells[i].style.color = "orange"; break; case 5: maintable.rows[j].cells[i].style.color = "aqua"; break; case 6: maintable.rows[j].cells[i].style.color = "violet"; break; case 7: maintable.rows[j].cells[i].style.color = "pink"; break; } } } } function keyboardListener(event){ switch(event.keyCode){ case 37: move("L"); generate(); show(); addColor(); break; case 38: move("U"); generate(); show(); addColor(); break; case 39: move("R"); generate(); show(); addColor(); break; case 40: move("D"); generate(); show(); addColor(); break; } } innitial(); generate(); show(); addColor(); </script> </body> </html>
由于时间有限,以下功能将在以后慢慢实现:
根据数字长度调整字体大小。
移动时的视觉反馈。
添加音效。
新产生的数字,要有效果。
游戏达到2048时胜利。
无法移动时失败。