• 2048的制作


    1、html部分

     1 <!doctype html>
     2 <html>
     3  <head>
     4   <meta charset="UTF-8">
     5   <title>Document</title>
     6   <link rel="stylesheet" href="2048.css"/>
     7   <script src="2048.js"></script>
     8  </head>
     9  <body>
    10   <p>
    11     Top:<span id="top">0</span><br>
    12     Score:<span id="score">0</span>
    13   </p>
    14 <div id="gridPanel">
    15   <!--背景格-->
    16   <!--第一行-->
    17     <div id="g00" class="grid"></div>
    18     <div id="g01" class="grid"></div>
    19     <div id="g02" class="grid"></div>
    20     <div id="g03" class="grid"></div>
    21   <!--第二行-->
    22     <div id="g10" class="grid"></div>
    23     <div id="g11" class="grid"></div>
    24     <div id="g12" class="grid"></div>
    25     <div id="g13" class="grid"></div>
    26   <!--第三行-->
    27     <div id="g20" class="grid"></div>
    28     <div id="g21" class="grid"></div>
    29     <div id="g22" class="grid"></div>
    30     <div id="g23" class="grid"></div>
    31   <!--第四行-->
    32     <div id="g30" class="grid"></div>
    33     <div id="g31" class="grid"></div>
    34     <div id="g32" class="grid"></div>
    35     <div id="g33" class="grid"></div>
    36   <!--前景格-->
    37   <!--第一行-->
    38     <div id="c00" class="cell"></div>
    39     <div id="c01" class="cell"></div>
    40     <div id="c02" class="cell"></div>
    41     <div id="c03" class="cell"></div>
    42 
    43     <div id="c10" class="cell"></div>
    44     <div id="c11" class="cell"></div>
    45     <div id="c12" class="cell"></div>
    46     <div id="c13" class="cell"></div>
    47 
    48     <div id="c20" class="cell"></div>
    49     <div id="c21" class="cell"></div>
    50     <div id="c22" class="cell"></div>
    51     <div id="c23" class="cell"></div>
    52 
    53     <div id="c30" class="cell"></div>
    54     <div id="c31" class="cell"></div>
    55     <div id="c32" class="cell"></div>
    56     <div id="c33" class="cell"></div>
    57 </div>
    58   <div id="gameOver">
    59     <div><!--半透明背景--></div>
    60     <p><!--前景对话框-->
    61       Game Over!<br>
    62       Score:<span id="final">0</span><br>
    63       <a class="btn" onclick="game.start()">Try again!</a>
    64     </p>
    65   </div>
    66  </body>
    67 </html>

    2、css部分

     1 #gridPanel{
     2   width:480px; height:480px;
     3   margin:0 auto;
     4   background-color:#bbada0;
     5   border-radius:10px;
     6   position:relative;
     7 }
     8 .grid,.cell{
     9   width:100px; height:100px; border-radius:6px;
    10 }
    11 .grid{
    12   background-color:#ccc0b3;
    13   float:left;
    14   margin-left:16px;
    15   margin-top:16px;
    16 }
    17 .cell{ 
    18   position:absolute; 
    19   font-size:60px;
    20     text-align:center;
    21     line-height:100px;
    22     color:#fff;
    23 }
    24 [id^="c0"]{top:16px;}
    25 [id^="c1"]{top:132px;}
    26 [id^="c2"]{top:248px;}
    27 [id^="c3"]{top:364px;}
    28 
    29 .cell[id$="0"]{left:16px;}
    30 .cell[id$="1"]{left:132px;}
    31 .cell[id$="2"]{left:248px;}
    32 .cell[id$="3"]{left:364px;}
    33 
    34 .n2{background-color:#eee3da}
    35 .n4{background-color:#ede0c8}
    36 .n8{background-color:#f2b179}
    37 .n16{background-color:#f59563}
    38 .n32{background-color:#f67c5f}
    39 .n64{background-color:#f65e3b}
    40 .n128{background-color:#edcf72}
    41 .n256{background-color:#edcc61}
    42 .n512{background-color:#9c0}
    43 .n1024{background-color:#33b5e5}
    44 .n2048{background-color:#09c}
    45 .n4096{background-color:#a6c}
    46 .n8192{background-color:#93c}
    47 .n2,.n4{color:#776e65}
    48 .n1024,.n2048,.n4096,.n8192{font-size:40px}
    49 
    50 p{
    51   width:480px; margin:0 auto;
    52   font-size:40px; font-family:Arial; font-weight:bold;
    53   padding-top:15px;
    54 }
    55 #gameOver{display:none;
    56   width:100%; height:100%;
    57   position:absolute;
    58   top:0; left:0;
    59 }
    60 #gameOver>div{
    61   width:100%; height:100%;
    62   background-color:#555; opacity:0.5;
    63 }
    64 #gameOver>p{
    65   width:300px; height:200px;
    67   position:absolute;
    68   top:50%; left:50%;
    69   margin-left:-150px; margin-top:-100px;
    70 
    71   background-color:#fff;
    72   text-align:center;
    73   line-height:1.5em;
    74   border-radius:10px;
    75   border:1px solid #edcf72;
    76 }
    77 .btn{
    78   color:#fff; background-color:#9f8d77;
    79   border-radius:6px; 
    80   cursor:pointer;
    81   padding:10px;
    82 }

     

    3、js部分

      1     function getCookie(cookieName){
      2         var str=document.cookie;
      3         var i=-1;
      4         if((i=str.indexOf(cookieName+"="))!=-1){
      5             var start=i+cookieName.length+1;
      6             var end=str.indexOf(";",start);
      7             return str.slice(start,end==-1?str.length:end);
      8         }else{
      9             return null;
     10         }
     11     }
     12     function setCookie(cookieName,value){
     13         var date=new Date();
     14         date.setFullYear(date.getFullYear()+1);
     15         document.cookie="="+value+";expires"+date.toGMTString();
     16     }
     17 
     18 var game={
     19   data:null,//保存一个二维数组
     20   RN:4,//总行数
     21   CN:4,//总列数
     22   score:0,//游戏得分
     23   state:1,//游戏状态: 1是运行中,0是结束
     24   RUNNING:1,//运行中
     25   GAMEOVER:0,//结束
     26   //强调: 对象自己的方法要使用自己的属性,必须加this
     27   start:function(){//启动游戏
     28     this.state=this.RUNNING;//初始化游戏状态为运行中
     29     this.score=0;
     30     this.data=[];//初始化当前对象的data属性为空数组
     31     for(var r=0;r<this.RN;r++){//r从0开始,到<RN结束,每次增1
     32       this.data.push([ ]);//向data中压入一个空数组
     33       //c从0开始,到<CN结束,每次增1
     34       for(var c=0;c<this.CN;c++){
     35         this.data[r][c]=0;//在data中r行c列的位置保存一个0
     36       }
     37     }//(遍历结束)
     38     this.randomNum();//调用randomNum方法
     39     this.randomNum();//再调用randomNum方法
     40     this.updateView();//更新页面
     41     var me=this;//留住this
     42     //为当前页面绑定键盘事件: 
     43     document.onkeydown=function(e){//e: 事件对象
     44       if(me.state==me.RUNNING){
     45         switch(e.keyCode){
     46           case 37: me.moveLeft();break;
     47           case 38: me.moveUp();break;
     48           case 39: me.moveRight();break;
     49           case 40: me.moveDown();break;
     50         }
     51       }
     52     }//document.onkeydown();//this->document
     53   },//强调: 每个方法之间必须用逗号分隔
     54   isGameOver:function(){//判断游戏是否结束
     55     //遍历data中每个元素
     56     for(var r=0;r<this.RN;r++){
     57       for(var c=0;c<this.CN;c++){
     58         if(this.data[r][c]==0){//如果当前元素等于0
     59           return false;//返回false
     60         }
     61         //如果c<CN-1而且当前元素等于右侧元素
     62         if(c<this.CN-1
     63           &&this.data[r][c]==this.data[r][c+1]){
     64           return false;//返回false
     65         }
     66         //如果r<RN-1而且当前元素等于下方元素
     67         if(r<this.RN-1
     68           &&this.data[r][c]==this.data[r+1][c]){
     69           return false;//返回false
     70         }
     71       }
     72     }//(遍历结束)返回true
     73     return true;
     74   },
     75   move:function(fun){//定义所有移动中相同的代码
     76     //为data拍照,保存在before中
     77     var before=String(this.data);
     78     fun.call(this);
     79     //为data拍照,保存在after中
     80     var after=String(this.data);
     81     //如果before不等于after,就随机生成数,更新页面
     82     if(before!=after){
     83       this.randomNum();
     84       //如果调用isGameOver返回true
     85       if(this.isGameOver()){
     86         this.state=this.GAMEOVER;//修改游戏状态为GAMEOVER
     87       }
     88       this.updateView();
     89     }
     90   },
     91   moveDown:function(){//下移所有列
     92     this.move(function(){
     93       for(var c=0;c<this.CN;c++){//遍历data中每一列
     94         //调用moveUpInCol,传入c作为参数
     95         this.moveDownInCol(c);
     96       }//(遍历结束)
     97     });    
     98   },
     99   moveDownInCol:function(c){
    100     for(var r=this.RN-1;r>0;r--){
    101       var prevr=this.getPrevInCol(r,c);
    102       if(prevr==-1){break;}
    103       else{
    104         if(this.data[r][c]==0){
    105           this.data[r][c]=this.data[prevr][c];
    106           this.data[prevr][c]=0;
    107           r++;
    108         }else if(this.data[r][c]==this.data[prevr][c]){
    109           this.data[r][c]*=2;
    110           this.score+=this.data[r][c];
    111           this.data[prevr][c]=0;
    112         }
    113       }
    114     }
    115   },
    116   getPrevInCol:function(r,c){
    117     for(var prevr=r-1;prevr>=0;prevr--){
    118       if(this.data[prevr][c]!=0){return prevr}
    119     }
    120     return -1;
    121   },
    122   moveUp:function(){//上移所有列
    123     this.move(function(){
    124       for(var c=0;c<this.CN;c++){//遍历data中每一列
    125         //调用moveUpInCol,传入c作为参数
    126         this.moveUpInCol(c);
    127       }//(遍历结束)
    128     });
    129   },
    130   moveUpInCol:function(c){//上移第c列
    131     for(var r=0;r<this.RN-1;r++){//从上到下遍历每一行
    132       //调用getNextInCol,传入参数r,c,返回值保存在nextr
    133       var nextr=this.getNextInCol(r,c);
    134       //如果nextr等于-1,就退出循环
    135       if(nextr==-1){break;}
    136       else{//否则
    137         if(this.data[r][c]==0){//如果r行c列等于0
    138           //将nextr行c列赋值给r行c列
    139           this.data[r][c]=this.data[nextr][c];
    140           this.data[nextr][c]=0;//将nextr行c列置为0
    141           r--;
    142         }else if(this.data[r][c]==this.data[nextr][c]){
    143         //否则 如果r行c列等于nextr行c列
    144           this.data[r][c]*=2;//将r行c列*2
    145           this.score+=this.data[r][c];
    146           this.data[nextr][c]=0;//将nextr行c列置为0
    147         }
    148       }
    149     }
    150   },
    151   //查找r行c列下方下一个不等于0的位置
    152   getNextInCol:function(r,c){
    153     //nextr从r+1开始,到<RN结束,每次增1
    154     for(var nextr=r+1;nextr<this.RN;nextr++){
    155       //如果nextr行c列不等于0,就返回nextr
    156       if(this.data[nextr][c]!=0){return nextr}
    157     }//(遍历结束)就返回-1]
    158     return -1;
    159   },
    160   moveRight:function(){//右移所有行
    161     this.move(function(){
    162       for(var r=0;r<this.RN;r++){//遍历data中每一行
    163         //调用moveRightInRow,传入r作为参数
    164         this.moveRightInRow(r);
    165       }//(遍历结束)
    166     });
    167   },
    168   moveRightInRow:function(r){//右移第r行
    169     //从右向左遍历r行中每个元素,到>0结束
    170     for(var c=this.CN-1;c>0;c--){
    171       //调用getPrevInRow,传入r,c作为参数,返回值保存在prevc中
    172       var prevc=this.getPrevInRow(r,c);
    173       //如果prevc为-1,就退出循环
    174       if(prevc==-1){break;}
    175       else{//否则
    176         //如果data中r行c位置等于0
    177         if(this.data[r][c]==0){
    178           //将data中r行prevc位置的值赋值给data中r行c位置
    179           this.data[r][c]=this.data[r][prevc];
    180           //将data中r行prevc位置置为0
    181           this.data[r][prevc]=0;
    182           c++;
    183         }else if(this.data[r][c]==this.data[r][prevc]){
    184         //否则,如果data中r行c位置等于data中r行prevc位置
    185           this.data[r][c]*=2;//将data中r行c位置*2
    186           this.score+=this.data[r][c];
    187           //将data中r行prevc位置置为0
    188           this.data[r][prevc]=0;
    189         }
    190       }
    191     }
    192   },
    193   //查找r行c列左侧前一个不为0的位置s
    194   getPrevInRow:function(r,c){
    195     //prevc从c-1开始,到>=0结束,每次减1
    196     for(var prevc=c-1;prevc>=0;prevc--){
    197       //如果data中r行prevc位置不等于0
    198       if(this.data[r][prevc]!=0){
    199         return prevc;//返回prevc
    200       }
    201     }//(遍历结束)就返回-1
    202     return -1;
    203   },
    204   moveLeft:function(){//左移所有行
    205     this.move(function(){
    206       for(var r=0;r<this.RN;r++){
    207         //调用moveLeftInRow(r)左移第r行
    208         this.moveLeftInRow(r);
    209       }//(遍历结束)
    210     });
    211   },
    212   moveLeftInRow:function(r){//左移第r行
    213     //c从0开始,到<CN-1结束,每次增1
    214     for(var c=0;c<this.CN-1;c++){
    215       //查找c位置后,下一个不为0的位置,保存在nextc中
    216       var nextc=this.getNextInRow(r,c);
    217       //如果nextc是-1,就退出循环
    218       if(nextc==-1){break;}
    219       else{//否则
    220         if(this.data[r][c]==0){//如果data中r行c位置等于0
    221           //将data中r行nextc位置的值赋值给data中r行c位置
    222           this.data[r][c]=this.data[r][nextc];
    223           //将data中r行nextc位置置为0
    224           this.data[r][nextc]=0;
    225           c--;//下次还在当前位置开始
    226         }else if(this.data[r][c]==this.data[r][nextc]){
    227         //否则 如果data中r行c位置等于data中r行nextc位置
    228           this.data[r][c]*=2;//将data中r行c位置*2
    229           this.score+=this.data[r][c];//累加得分
    230           //将data中r行nextc位置置为0
    231           this.data[r][nextc]=0;
    232         }
    233       }
    234     }
    235   },
    236   //查找r行c列右侧下一个不为0的位置
    237   getNextInRow:function(r,c){
    238     //nextc从c+1开始,到<CN结束,nextc每次增1
    239     for(var nextc=c+1;nextc<this.CN;nextc++){
    240       //如果data中r行nextc位置的值!=0
    241       if(this.data[r][nextc]!=0){
    242         return nextc;//返回nextc
    243       }
    244     }//(遍历结束)就返回-1
    245     return -1;
    246   },
    247   //将data中的元素,更新到页面的格子div中
    248   updateView:function(){
    249     //r从0开始,到<RN结束,每次增1
    250     for(var r=0;r<this.RN;r++){
    251       //c从0开始,到<CN结束,每次增1
    252       for(var c=0;c<this.CN;c++){
    253         //查找id为c+r+c的div元素,保存在变量div中
    254         var div=document.getElementById("c"+r+c);
    255         //如果data中r行c列的等于0
    256         if(this.data[r][c]==0){
    257           div.innerHTML="";//设置div的内容为空字符串
    258           div.className="cell";//设置div的className为"cell"
    259         }else{//否则
    260           //设置div的内容为data中r行c列的值
    261           div.innerHTML=this.data[r][c];
    262           //设置div的className为"cell n"+data中r行c列的值
    263           div.className="cell n"+this.data[r][c];
    264         }
    265       }
    266     }
    267     //找到id为score的span,直接设置其内容为score属性值
    268     score.innerHTML=this.score;
    269     //设置id为gameOver的元素的display属性为:
    270       //如果state为GAMEOVER,就设置为"block",否则为"none"
    271     this.state==this.GAMEOVER
    272       &&(final.innerHTML=this.score);
    273     gameOver.style.display=
    274       this.state==this.GAMEOVER?"block":"none";
    275   },
    276   randomNum:function(){//在随机位置生成一个数字
    277     while(true){//反复生成数字(死循环)
    278       //在0~RN-1之间生成一个随机的行号,保存在r中
    279       var r=Math.floor(Math.random()*this.RN);
    280       //在0~CN-1之间生成一个随机的列号,保存在c中
    281       var c=Math.floor(Math.random()*this.CN);
    282       if(this.data[r][c]==0){//如果data中r行c列为0
    283         //随机生成一个数字保存在变量num中
    284         var num=Math.random();
    285         //设置data中r行c列的元素值为:
    286           //如果num<0.5,就设置2为,否则就设置为4
    287         this.data[r][c]=num<0.5?2:4;
    288         break;//退出循环
    289       }
    290     }
    291   },
    292 }
    293 //当页面加载后,自动启动
    294 window.onload=function(){game.start();}
  • 相关阅读:
    服务管理命令
    软件管理
    Qt软件打包与发布(windeployqt工具)
    03
    第一章 BP神经网络
    代理模式 与 Spring AOP
    java 回调机制
    HashTable 实现
    实现Singleton模式
    BST 汇总
  • 原文地址:https://www.cnblogs.com/chenzeyongjsj/p/5517587.html
Copyright © 2020-2023  润新知