拖了一个假期的2048,今天终于完成网页版本的了
开心!!!
刚开始觉得挺难的,无从下手
但是imooc老师特别仔细的讲每一个细节,怎么想,怎么写
一步一步,虽然经常被自己蠢哭,但是还是完成了!开心!!
遇到了很多坑。。。
1.跟着老师一步步走还好,老师写完moveleft之后,让我们自己写其他三个move函数
本以为自己都理解了,可以写,但是!!!right根本就运行不出来,直接死机!
后来,看老师的代码,发现其实自己根本没有弄清楚循环的细节,一步步仔细看原来少了个=。蠢哭!
2.有个bug,说重复移动。这是个很抽象的问题,我一开始根本不知道怎么办,老师说可以转化成很多小问题,如果它累加移动,那我们就设个函数记录累加的次数就可以啊。原来!感觉写代码就是天马行空的写,怎么写都可以。哈哈哈哈哈
3.写完还要考虑性能的问题,比如当初就写了个死循环生成随机位置。后来就会比较慢,怎么解决呢?设函数,记录次数!如果好多次都没有找到,就手动生成。
4.用户体验也是我们需要考虑的问题,比如你生成太快,没有过渡,那么动画效果就不好,那么我们就settimeout。代码不只是写出功能来就大功告成了,用户体验也很重要!
5.就是自己改的bug啦~score设计的是全局变量,所以newgame之后还会是原来的score,怎么办?设函数!自己加了个clearscore,清零分数值,再告诉前台要改就OK啦,就是一些语法要熟练用啊
6.把数字改成“小白-》实习生-》程序猿-》。。。。”这个我原来以为很难啊,其实,很简单!怎么改?设函数!增加了一个getnumbercontent,把首先把randnumber用这个函数转化一下,再用switch转化一下,最后别忘记告诉前台去改展示的文字,大功告成!
<!DOCTYPE html> <html> <head> <title>2048 GAME</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="2048.css"> <script type="text/javascript" src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js" ></script> <link href="http://libs.baidu.com/bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet"> <script src="http://libs.baidu.com/bootstrap/2.3.2/js/bootstrap.min.js"></script> <script type="text/javascript" src="support2048.js"></script> <script type="text/javascript" src="showanimation2048.js"></script> <script type="text/javascript" src="main2048.js"></script> </head> <body > <div id="background"> <header> <h1>2048</h1> <a href="javascript:newgame();" id="newgamebutton">New Game</a> <h4>score:<span id="score">0</span></h4> </header> <div id="grid-container"> <div class="grid-cell" id="grid-cell-0-0"></div> <div class="grid-cell" id="grid-cell-0-1"></div> <div class="grid-cell" id="grid-cell-0-2"></div> <div class="grid-cell" id="grid-cell-0-3"></div> <div class="grid-cell" id="grid-cell-1-0"></div> <div class="grid-cell" id="grid-cell-1-1"></div> <div class="grid-cell" id="grid-cell-1-2"></div> <div class="grid-cell" id="grid-cell-1-3"></div> <div class="grid-cell" id="grid-cell-2-0"></div> <div class="grid-cell" id="grid-cell-2-1"></div> <div class="grid-cell" id="grid-cell-2-2"></div> <div class="grid-cell" id="grid-cell-2-3"></div> <div class="grid-cell" id="grid-cell-3-0"></div> <div class="grid-cell" id="grid-cell-3-1"></div> <div class="grid-cell" id="grid-cell-3-2"></div> <div class="grid-cell" id="grid-cell-3-3"></div> </div> </div> </body> </html>
main.js
var board = new Array(); var score =0; var hasConflicted=new Array(); $(document).ready(function(){ newgame(); }); function newgame(){ //初始化棋盘格 init(); // clear score clearscore(); //随机产生数字 generateOneNumber(); generateOneNumber(); } function init(){ for(var i=0;i<4;i++) for(var j=0;j<4;j++){ var gridCell=$("#grid-cell-"+i+'-'+j); gridCell.css('top',getPosTop(i,j)); gridCell.css('left',getPosLeft(i,j)); } for(var i=0;i<4;i++){ board[i]=new Array(); hasConflicted[i]=new Array(); for(var j=0;j<4;j++){ board[i][j]=0; hasConflicted[i][j]=false; } } updateBoardView(); score=0; } function updateBoardView(){ $(".number-cell").remove(); for(var i=0;i<4;i++) for(var j=0;j<4;j++){ $("#grid-container").append('<div class="number-cell" id="number-cell-'+i+'-'+j+'"></div>'); var theNumberCell = $("#number-cell-"+i+'-'+j); if (board[i][j]==0){ theNumberCell.css('width','0px'); theNumberCell.css('height','0px'); theNumberCell.css('top',getPosTop(i,j)+50); theNumberCell.css('left',getPosLeft(i,j)+50); }else{ theNumberCell.css('width','100px'); theNumberCell.css('height','100px'); theNumberCell.css('top',getPosTop(i,j)); theNumberCell.css('left',getPosLeft(i,j)); theNumberCell.css('background-color',getNumberBackgroundColor(board[i][j])); theNumberCell.css('color',getNumberColor(board[i][j])); theNumberCell.text(getNumberContent(board[i][j])); } hasConflicted[i][j]=false; } } function generateOneNumber(){ if(nospace(board)){ return false; }else{ //随机一个positon var randx =parseInt(Math.floor(Math.random()*4) ); var randy =parseInt(Math.floor(Math.random()*4) ); var times=0; while (times<50) { if(board[randx][randy]==0){ break; }else { var randx =parseInt(Math.floor(Math.random()*4) ); var randy =parseInt(Math.floor(Math.random()*4) ); times++; } } //优化循环 自动生成超过50次,就手动生成位置 if(times==50) { for(var i=0;i<4;i++){ for(var j=0;j<4;j++){ if (board[i][j]==0) { randx=i; randy=j; } } } } //随机一个number var randNumber =Math.random()<0.5?2:4; //随机位置显示随机数字 board[randx][randy]=randNumber; showNumberWithAnimation(randx,randy,randNumber); return true; } } $(document).keydown(function(event){ switch (event.keyCode) { case 37://left if(moveLeft()){ setTimeout("generateOneNumber()",210); setTimeout("isgameover()",300); } break; case 38://up if(moveUp()){ setTimeout("generateOneNumber()",210); setTimeout("isgameover()",300); } break; case 39://right if(moveRight()){ setTimeout("generateOneNumber()",210); setTimeout("isgameover()",300); } break; case 40://down if(moveDown()){ setTimeout("generateOneNumber()",210); setTimeout("isgameover()",300); } break; default: break; } }); function isgameover(){ if(nospace(board) && nomove(board)){ gameover(); }else { return false; } } function gameover(){ alert("gameover!"); } function moveLeft(){ if(!canMoveLeft(board)){ return false; } for(var i=0;i<4;i++) for(var j=1;j<4;j++){ if(board[i][j]!=0){ for(var k=0;k<j;k++){ if(board[i][k]==0 && noBlockHorizontal(i,k,j,board)){ //move showMoveAnimation(i,j,i,k); board[i][k]=board[i][j]; board[i][j]=0; continue; }else if(board[i][k]==board[i][j] && noBlockHorizontal(i,k,j,board) && !hasConflicted[i][k]){ //move showMoveAnimation(i,j,i,k); //add board[i][k]+=board[i][j]; board[i][j]=0; //add score score += board[i][k]; updateScore(score); hasConflicted[i][k]=true; continue; } } } } updateBoardView(); return true; } function moveRight(){ if(!canMoveRight(board)){ return false; } for(var i=0;i<4;i++) for(var j=2;j>=0;j--){ if(board[i][j]!=0){ for(var k=3;k>j;k--){ if(board[i][k]==0 && noBlockHorizontal(i,j,k,board)){ //move showMoveAnimation(i,j,i,k); board[i][k]=board[i][j]; board[i][j]=0; continue; }else if(board[i][k]==board[i][j] && noBlockHorizontal(i,j,k,board) && !hasConflicted[i][k]){ //move showMoveAnimation(i,j,i,k); //add board[i][k]+=board[i][j]; board[i][j]=0; score+=board[i][k]; updateScore(score); hasConflicted[i][k]=true; continue; } } } } updateBoardView(); return true; } function moveUp(){ if(!canMoveUp(board)){ return false; } for(var j=0;j<4;j++) for(var i=1;i<4;i++){ if(board[i][j]!=0){ for(var k=0;k<i;k++){ if(board[k][j]==0 && noBlockVertical(j,k,i,board)){ //move showMoveAnimation(i,j,k,j); board[k][j]=board[i][j]; board[i][j]=0; continue; }else if(board[k][j]==board[i][j] && noBlockVertical(j,k,i,board) && !hasConflicted[k][j]){ //move showMoveAnimation(i,j,k,j); //add board[k][j]+=board[i][j]; board[i][j]=0; score+=board[k][j]; updateScore(score); hasConflicted[i][k]=true; continue; } } } } updateBoardView(); return true; } function moveDown(){ if(!canMoveDown(board)){ return false; } for(var j=0;j<4;j++) for(var i=2;i>=0;i--){ if(board[i][j]!=0){ for(var k=3;k>i;k--){ if(board[k][j]==0 && noBlockVertical(j,k,i,board)){ //move showMoveAnimation(i,j,k,j); board[k][j]=board[i][j]; board[i][j]=0; continue; }else if(board[k][j]==board[i][j] && noBlockVertical(j,k,i,board) && !hasConflicted[k][j]){ //move showMoveAnimation(i,j,k,j); //add board[k][j]+=board[i][j]; board[i][j]=0; score+=board[k][j]; updateScore(score); hasConflicted[i][k]=true; continue; } } } } updateBoardView(); return true; } support2048.js
function getPosTop(i,j) { return 20+120*i; } function getPosLeft(i,j) { return 20+120*j; } function getNumberBackgroundColor(number) { switch(number){ case 2:return '#FCD6BC';break; case 4:return '#F8A1B2';break; case 8:return '#EF4E88';break; case 16:return '#FBD75E';break; case 32:return '#A8C065';break; case 64:return '#76A2B5';break; case 128:return '#47183E';break; case 256:return '#1C4150';break; case 512:return '#88CAD0';break; case 1024:return '#405DAD';break; case 2048:return '#C7C47B';break; case 4096:return '#008080';break; case 8192:return '#FF0000';break; } return "black"; } function getNumberContent(number){ switch(number){ case 2:return "小白";break; case 4:return "实习生";break; case 8:return "程序猿";break; case 16:return "项目经理";break; case 32:return "构架师";break; case 64:return "技术经理";break; case 128:return "高级经理";break; case 256:return "技术总监";break; case 512:return "副总裁";break; case 1024:return "CTO";break; case 2048:return "总裁";break; } return "无业游民"; //console.log('number'); } function getNumberColor(number){ if (number<=4) return '#776e65'; return 'white'; } function nospace(board){ for(var i=0;i<4;i++) for(var j=0;j<4;j++){ if(board[i][j]==0){ return false; }else{ return true; } } } function nomove(board){ if(canMoveLeft(board)||canMoveRight(board)||canMoveUp(board)||canMoveDown(board)){ return false; }else { return true; } } function canMoveLeft(board){ for(var i=0;i<4;i++) for(var j=1;j<4;j++){ if(board[i][j]!=0){ if(board[i][j-1]==0||board[i][j-1]==board[i][j]){ return true; } } } return false; } function canMoveRight(board){ for(var i=0;i<4;i++) for(var j=2;j>=0;j--){ if(board[i][j]!=0){ if(board[i][j+1]==0||board[i][j+1]==board[i][j]){ return true; } } } return false; } function canMoveUp(board){ for(var j=0;j<4;j++) for(var i=1;i<4;i++){ if(board[i][j]!=0){ if(board[i-1][j]==0||board[i-1][j]==board[i][j]){ return true; } } } return false; } function canMoveDown(board){ for(var j=0;j<4;j++) for(var i=2;i>=0;i--){ if(board[i][j]!=0){ if(board[i+1][j]==0||board[i+1][j]==board[i][j]){ return true; } } } return false; } function noBlockHorizontal(row,col1,col2,board){ for(var i=col1+1;i<col2;i++ ){ if(board[row][i]!=0){ return false; } } return true; } function noBlockVertical(col,row1,row2,board){ for(var i=row1+1;i<row2;i++ ){ if(board[i][col]!=0){ return false; } } return true; } showanimation.js
function showNumberWithAnimation(i,j,randNumber){ var numberCell = $("#number-cell-"+i+'-'+j); numberCell.css('background-color',getNumberBackgroundColor(randNumber)); numberCell.css('color',getNumberColor(randNumber)); numberCell.text(getNumberContent(randNumber) ); numberCell.animate({ width:"100px", height:"100px", top:getPosTop(i,j), left:getPosLeft(i,j) },50); } function clearscore(){ score=0; $("#score").text(score); } function showMoveAnimation(fromx,fromy,tox,toy){ var numberCell=$("#number-cell-"+fromx+'-'+fromy); numberCell.animate({ top:getPosTop(tox,toy), left:getPosLeft(tox,toy) },200); } function updateScore(score){ $("#score").text(score); } 2048.css
#background { position:fixed; top:0; left:0; z-index:-10; width:100%; height:100%; background: #ffa5a5; background: -moz-linear-gradient(top, #ffa5a5 20%, #fff 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(20%,#ffa5a5), color-stop(100%,#fff)); background: -webkit-linear-gradient(top, #ffa5a5 20%,#fff 100%); background: linear-gradient(top, #ffa5a5 20%,#fff 100%); } header{ display: block; width: 500px; margin: 0 auto; text-align: center; } #newgamebutton{ border-radius: 5px; padding: 5px; background-color: #EF4E88; font-size: 25px; color: #fff; display: inline-block; } #grid-container{ width: 460px; height: 460px; padding: 20px; margin: 10px auto; background: #E6E6E6; border-radius: 10px; position: relative; } .grid-cell{ width: 100px; height: 100px; border-radius: 6px; position: absolute; background-color: #ffffff; } .number-cell{ border-radius: 6px; position: absolute; line-height: 100px; font-size: 20px; text-align: center; }