html部分
<p> <!--TOP:<span id="top">0</span><br>--> SCORE:<span id="score">0</span> </p> <div id="playground"> <div id="c00" class="cell"></div> <div id="c01" class="cell"></div> <div id="c02" class="cell"></div> <div id="c03" class="cell"></div> <div id="c10" class="cell"></div> <div id="c11" class="cell"></div> <div id="c12" class="cell"></div> <div id="c13" class="cell"></div> <div id="c20" class="cell"></div> <div id="c21" class="cell"></div> <div id="c22" class="cell"></div> <div id="c23" class="cell"></div> <div id="c30" class="cell"></div> <div id="c31" class="cell"></div> <div id="c32" class="cell"></div> <div id="c33" class="cell"></div> </div> <div id="gameOver"><!-- 半透明遮罩 --> <p> GAME OVER!<br> SCORE: <span id="final"></span><br> <a class="btn" οnclick="game.start()">Try again!</a> </p> </div>
css部分
#playground{ width: 480px; height:480px; margin:0 auto; //对象上下间距为0,左右自动 background:#bbada0; border-radius:10px; position:relative; } .cell{ width:100px; height:100px; border-radius:6px; background: #ccc0b3; position:absolute; line-height:100px; font-size:60px; text-align:center; color:#fff; } [id^="c0"]{top:16px;} [id^="c1"]{top:132px;} [id^="c2"]{top:248px;} [id^="c3"]{top:364px;} [id$="0"]{left:16px;} [id$="1"]{left:132px;} [id$="2"]{left:248px;} [id$="3"]{left:364px;} .n2{background-color:#eee3da} .n4{background-color:#ede0c8} .n8{background-color:#f2b179} .n16{background-color:#f59563} .n32{background-color:#f67c5f} .n64{background-color:#f65e3b} .n128{background-color:#edcf72} .n256{background-color:#edcc61} .n512{background-color:#9c0} .n1024{background-color:#33b5e5} .n2048{background-color:#09c} .n4096{background-color:#a6c} .n8192{background-color:#93c} .n2,.n4{color:#776e65} .n1024,.n2048,.n4096,.n8192{font-size:40px} p{ width:480px; margin:0 auto; font-size:40px; font-family:Arial; font-weight:bold; padding-top:15px; } #gameOver{ position:absolute; left:0;right:0;top:0;bottom:0; background:rgba(55,55,55,.5); } #gameOver>p{ width:300px; height:200px; background:#fff; position:absolute; top:50%;left:50%; margin-top:-100px; margin-left:-150px; text-align:center; line-height:1.5em; border-radius:10px; border:1px solid #edcf72; } #gameOver .btn{ padding:10px; color:#fff; background-color:#9f8d77; border-radius:6px; cursor:pointer; }js部分
var game={ RN:4,CN:4, data:null, score:0, state:1, GAMEOVER:0, RUNNING:1, start:function(){ this.state=this.RUNNING; this.score=0; this.data=[]; for(var r=0;r<this.RN;r++){ this.data[r]=new Array(this.CN);//this.data.push([]); for(var c=0;c<this.CN;c++){ this.data[r][c]=0; } } this.randomNum();//生成第一个随机数 this.randomNum();//生成第二个随机数 this.updateView();// document.onkeydown = function(e){ //用户按下一个键盘按键时发生 switch(e.keyCode){ case 37: this.moveLeft();break; case 38: this.moveTop();break; case 39: this.moveRight();break; case 40: this.moveDown();break; } }.bind(this); //用onkeydown外的this替换内部的this console.log(this.data.join("\n")); }, randomNum:function() //在一个随机位置生成2或4 { while (true) { var r = Math.floor(Math.random() * this.RN); var c = Math.floor(Math.random() * this.CN); if (this.data[r][c] === 0) { this.data[r][c] = Math.random() < 0.5 ? 2 : 4; break; } } }, updateView:function(){ //更新数据 for(var r=0;r<this.RN;r++){ for(var c=0;c<this.CN;c++){ var div=document.getElementById("c"+r+c); if(this.data[r][c]!=0){ div.innerHTML=this.data[r][c]; div.className="cell n"+this.data[r][c]; }else{ div.innerHTML=""; div.className="cell"; } } } document.getElementById("score").innerHTML=this.score; document.getElementById("gameOver").style.display=this.state===this.GAMEOVER?"block":"none"; this.state===this.GAMEOVER&&( document.getElementById("final").innerHTML=this.score ); }, moveLeft:function(){ var before=String(this.data); for(var r=0;r<this.RN;r++){ this.moveLeftInRow(r); } var after=String(this.data); if(after!=before){ this.randomNum(); this.isGameOver()&&(this.state=this.GAMEOVER); this.updateView(); } }, moveLeftInRow:function(r){ //左移1行 for(var c=0;c<this.CN-1;c++){ //c从0开始,遍历data中r行,到<CN-1结束 var nextc=this.getNextInRow(r,c); //找data中r行c列右侧下一个不为0的位置nextc if(nextc==-1){break;} //如果nextc是-1,就退出循环 else{ //否则 if(this.data[r][c]==0){ //如果r行c列为0 this.data[r][c]=this.data[r][nextc]; //将r行nextc列的值赋值给r行c列 this.data[r][nextc]=0; //将r行nextc列的值置为0 c--; //c留在原地 }else if(this.data[r][c]==this.data[r][nextc]){ //否则,如果r行c列等于r行nextc列 this.data[r][c]*=2; //将r行c列的值*2 this.score+=this.data[r][c]; //将r行c列的新值累加到score属性上 this.data[r][nextc]=0; //将r行nextc列的值置为0 } } } }, getNextInRow:function(r,c){ for(var i=c+1;i<this.CN;i++){ if(this.data[r][i]!=0) return i; } return -1; }, moveRight:function(){ this.xExchangge(); this.moveLeft(); this.xExchangge(); this.updateView(); }, moveTop:function(){ this.middleExchange(); this.moveLeft(); this.middleExchange(); this.updateView(); }, moveDown:function(){ this.middleExchange(); this.moveRight(); this.middleExchange(); this.updateView(); }, xExchangge:function(){ for(var i=0;i<4;i++){ for(var j=0;j<2;j++){ this.data[i][j]^=this.data[i][3-j]; this.data[i][3-j]^=this.data[i][j]; this.data[i][j]^=this.data[i][3-j]; } } }, middleExchange:function(){ for(var i=0;i<4;i++){ for(var j=i+1;j<4;j++){ this.data[i][j]^=this.data[j][i]; this.data[j][i]^=this.data[i][j]; this.data[i][j]^=this.data[j][i]; } } }, isGameOver:function(){ for(var r=0;r<this.RN;r++){ for(var c=0;c<this.CN;c++){ //如果当前元素是0或c<this.CN-1且当前元素等于右侧元素或r<this.RN-1且当前元素等于下方元素 if(this.data[r][c]==0|| c<this.CN-1 &&this.data[r][c]==this.data[r][c+1]|| r<this.RN-1 &&this.data[r][c]==this.data[r+1][c]){ return false; } } } return true; } }; game.start();