• js+css 写出 简单2048游戏


    2048效果图

    新手写的,可能不是很完善,欢迎修改及探讨

      1 <!DOCTYPE html>
      2 <html lang="en">
      3     <head>
      4         <meta charset="UTF-8">
      5         <title>2048游戏</title>
      6         <style>
      7             .container{
      8                  600px;
      9                 height: 600px;
     10                 border: 2px solid #000;
     11                 background-color: white;
     12                 margin: auto;
     13             }
     14 
     15             .header{
     16                 font: bold 40px arial;
     17                 margin-left: 80px;
     18             }
     19             .header span, #gameOver span{
     20                 color: red;
     21             }
     22             
     23             #gameBody{
     24                  450px;
     25                 height: 450px;
     26                 margin-left: 80px;
     27                 padding: 5px 0 0 5px;
     28                 border-radius: 10px;
     29                 background-color: #bbada0;
     30             }
     31             
     32             .cell{
     33                  100px;
     34                 height: 100px;
     35                 margin: 5px;
     36                 background-color: #ccc0b3;
     37                 border-radius: 5px;
     38                 float: left;
     39                 font: 50px/100px arial;
     40                 text-align: center;
     41             }
     42             
     43             .n2{background-color: #eee3da}
     44             .n4{background-color: #ede0c8}
     45             .n8{background-color: #f2b179}
     46             .n16{background-color: #f59563}
     47             .n32{background-color: #f67c5f}
     48             .n64{background-color: #f65e3b}
     49             .n128{background-color: #edcf72}
     50             .n256{background-color: #edcc61}
     51             .n512{background-color: #9c0}
     52             .n1024{background-color: #33b5e5}
     53             .n2048{background-color: #09c}
     54             .n4096{background-color: #a6c}
     55             .n8192{background-color: #93c}
     56             .n2,.n4{color: #776e65}
     57             .n1024,.n2048,.n4096,.n8192{font-size: 40px}
     58             
     59             
     60             #gameOver{
     61                 display: none;
     62                 position: absolute;
     63                 top: 0;
     64                 left: 0;
     65                 right: 0;
     66                 bottom: 0;
     67                 background:rgba(55,55,55,0.5);
     68             }
     69             
     70             #gameOver p{
     71                  300px;
     72                 height: 200px;
     73                 position: absolute;
     74                 top: 50%;
     75                 left: 50%;
     76                 margin: -100px 0 0 -150px;
     77                 text-align: center;
     78                 border-radius: 10px;
     79                 border: 1px solid #edcf72;
     80                 font: bold 40px/65px arial;
     81                 background: #fff;
     82             }
     83             
     84             #gameOver .btn{
     85                 padding: 10px;
     86                 color:#fff;
     87                 background: #9f8d77;
     88                 border-radius: 6px;
     89                 text-decoration: none;
     90             }
     91         </style>
     92     </head>
     93     <body>
     94         <div class="container">
     95             <p class="header">SCORE:<span id="score">0</span></p>
     96             <div id="gameBody">
     97                         <div  class="cell" id="cell-00"></div>
     98                         <div  class="cell" id="cell-01"></div>
     99                         <div  class="cell" id="cell-02"></div>
    100                         <div  class="cell" id="cell-03"></div>
    101                         <div  class="cell" id="cell-10"></div>
    102                         <div  class="cell" id="cell-11"></div>
    103                         <div  class="cell" id="cell-12"></div>
    104                         <div  class="cell" id="cell-13"></div>
    105                         <div  class="cell" id="cell-20"></div>
    106                         <div  class="cell" id="cell-21"></div>
    107                         <div  class="cell" id="cell-22"></div>
    108                         <div  class="cell" id="cell-23"></div>
    109                         <div  class="cell" id="cell-30"></div>
    110                         <div  class="cell" id="cell-31"></div>
    111                         <div  class="cell" id="cell-32"></div>
    112                         <div  class="cell" id="cell-33"></div>
    113             </div>
    114             <div id="gameOver">
    115                 <p>
    116                     GAME OVER<br>
    117                     SCORE:<span id="final">0</span><br>
    118                     <a href="javascript:game.start();" class="btn">TRY AGAIN!</a>
    119                 </p>
    120             </div>
    121         </div>
    122         
    123         <script>
    124             //创建对象:属性+方法
    125             var game = {
    126                 //数组,保存数据
    127                 data:[],
    128                 //游戏得分:0
    129                 score:0,
    130                 //设置游戏状态:1-开始,0-结束
    131                 state:1,
    132                 //游戏状态:开始
    133                 RUNNING:1,
    134                 //游戏状态:结束
    135                 GAMEOVER:0,
    136                 
    137                 //游戏开始start()方法
    138                 start:function(){
    139                     //设置游戏状态为开始
    140                     this.state=this.RUNNING;
    141                     //初始化游戏得分为0
    142                     this.score=0;
    143                     //创建一个二维数组
    144                     for(var r = 0; r < 4; r++){
    145                         //创建一个一维数组,
    146                         var datacell = [];
    147                         //将一维数组值初始化为0
    148                         for(var c = 0;c < 4; c++){
    149                             datacell[c] = 0;
    150                         }
    151                         //将一维数组的值循环赋给数组data[],成功创建一个二维数组
    152                         this.data[r] = datacell;
    153                     }
    154                     
    155                     //调用函数随机生成两个数
    156                     this.randomNum();
    157                     this.randomNum();
    158                     //刷新页面,显示div的值
    159                     this.updateView();
    160                 },
    161                 
    162                 //随机生成两个数4或2
    163                 randomNum:function(){
    164                     while(true){
    165                         var r=Math.floor(Math.random()*this.data.length);
    166                         var c=Math.floor(Math.random()*this.data.length);
    167                         if(this.data[r][c]==0){
    168                             //随机生成2和4的概率相等
    169                             this.data[r][c]=Math.random()<0.5?2:4;
    170                             break;
    171                         }
    172                     }
    173                 },
    174                 
    175                 updateView:function(){
    176                     for(var r=0;r<this.data.length;r++){
    177                         for(var c=0;c<this.data.length;c++){
    178                             //判断数组中的数据,为0则不做任何操作,保持原来数据和类名不变
    179                             //动态获取标签的id:要求取id名时与数组下角标相对应
    180                             if(this.data[r][c]==0){
    181                                 document.getElementById("cell-"+r+c).innerHTML="";
    182                                 document.getElementById("cell-"+r+c).className="cell";
    183                             }else{
    184                                 //不为0,则将数组中数据显示在对应的div格子中
    185                                 document.getElementById("cell-"+r+c).innerHTML= this.data[r][c];
    186                                 //保持原来类名不变,并追加对应div类名(动态)
    187                                 document.getElementById("cell-"+r+c).className="cell n" + this.data[r][c];
    188                                 
    189                             }
    190                         }
    191                     }
    192                     //将分数显示在界面上方
    193                     document.getElementById("score").innerHTML=this.score;
    194                     var gameOver=document.getElementById("gameOver");
    195                     if(this.state==this.GAMEOVER){
    196                         //如果状态为GAMEOVER(即0,表示游戏结束,显示结束界面,并将最后分数显示在结束界面
    197                         gameOver.style.display="block";
    198                         document.getElementById("final").innerHTML=this.score;
    199                     }else{
    200                         //如果状态为1,表示游戏还未结束,隐藏结束界面
    201                         gameOver.style.display="none";
    202                     }
    203                 },
    204                 
    205                 //向左移动所有行
    206                 moveLeft:function(){
    207                     //判断字符串是否移动
    208                     //做移动操作前先将数组转换为字符串保存
    209                     var before=String(this.data);
    210                     //遍历行
    211                     for(var r=0;r<this.data.length;r++){
    212                         this.moveLeftRow(r);
    213                     }
    214                     //做移动操作后先将数组转换为字符串保存
    215                     var after=String(this.data);
    216                     //将移动操作前后的数组(字符串)作比较,如果不相等,即发生改变,则随机生成一个数
    217                     if(before!=after){
    218                         this.randomNum();
    219                         //随机生成一个数后,判断游戏是否结束,设置游戏状态
    220                         if(this.isGameOver()){
    221                             this.state=this.GAMEOVER;
    222                         }
    223                         //游戏未结束刷新页面,再显示随机生成数
    224                         this.updateView();
    225                     }
    226                 },
    227                 
    228                 //判断并向左移动指定行中的每个元素
    229                 moveLeftRow:function(r){
    230                     //0开始,遍历r行中每一个元素
    231                     for(var c=0;c<this.data.length-1;c++){
    232                         //获得当前元素下一个不为0的元素的下标nextc
    233                         var nextc=this.getNextRow(r,c)
    234                         //如果nextc=-1,说明右侧没有元素了,退出循环
    235                         if(nextc==-1) {
    236                             break;
    237                         }else if(this.data[r][c]==0){   //如果自己==0 则将下一个位置放入当前位置,下一个位置设置为零
    238                             this.data[r][c]=this.data[r][nextc];
    239                             this.data[r][nextc]=0;
    240                             //重新检查
    241                             c--;
    242                         }else if(this.data[r][c]==this.data[r][nextc]){// 如果当前位置的值==nextc的位置的值,将当前位置*=2;下一个位置设置为0
    243                             this.data[r][c]*=2;
    244                             //将当前值累加到score属性上
    245                             this.score+=this.data[r][c];
    246                             this.data[r][nextc]=0;
    247                         }
    248                     }
    249                 },
    250                 
    251                 //找当前位置右侧,下一个不为0的数
    252                 getNextRow:function(r,c){
    253                     //从c+1 遍历row行中剩余元素,
    254                     for(var i=c+1;i<this.data.length;i++){
    255                         //如果出现不为0的值,返回它的列数
    256                         if(this.data[r][i]!=0) {
    257                             return i;
    258                         }
    259                     }
    260                     //循环退出返回-1
    261                     return -1;
    262                 },
    263                     
    264                     
    265                 //向右移动所有行    
    266                 moveRight:function(){
    267                     var before=String(this.data);
    268                     for(var r=0;r<this.data.length;r++){
    269                         this.moveRightRow(r);
    270                     }
    271                     var after=String(this.data);
    272                     if(before!=after){
    273                         this.randomNum();
    274                         if(this.isGameOver()){
    275                             this.state=this.GAMEOVER;
    276                         }
    277                         this.updateView();
    278                     }
    279                 },
    280             
    281                 moveRightRow:function(r){
    282                     for(var c=this.data.length-1;c>0;c--){
    283                         var prec=this.getPreRow(r,c)
    284                         if(prec==-1){
    285                             break;
    286                         }else if(this.data[r][c]==0){
    287                             this.data[r][c]=this.data[r][prec];
    288                             this.data[r][prec]=0;
    289                             c++;
    290                         }else if(this.data[r][c]==this.data[r][prec]){
    291                             this.data[r][c]*=2;
    292                             this.score+=this.data[r][c];
    293                             this.data[r][prec]=0;
    294                         }
    295                     }
    296                 },
    297                 
    298                 getPreRow:function(r,c){
    299                     for(var i=c-1;i>=0;i--){
    300                         if(this.data[r][i]!=0) return i;    
    301                         }
    302                         return -1;
    303                 },
    304                     
    305                 moveUp:function(){
    306                     var before=String(this.data);
    307                     for(var c=0;c<this.data.length;c++){
    308                         this.moveUpCol(c);
    309                     }
    310                     var after=String(this.data);
    311                     if(before!=after){
    312                         this.randomNum();
    313                         if(this.isGameOver()){
    314                             this.state=this.GAMEOVER;
    315                         }
    316                         this.updateView();
    317                     }
    318                 },
    319                 
    320                 //向上移动所有列
    321                 moveUpCol:function(c){
    322                     for(var r=0;r<this.data.length-1;r++){
    323                         var nextr=this.getNextCol(r,c)
    324                         if(nextr==-1) {break;
    325                         }else if(this.data[r][c]==0){
    326                             this.data[r][c]=this.data[nextr][c];
    327                             this.data[nextr][c]=0;
    328                             r--;
    329                         }else if(this.data[r][c]==this.data[nextr][c]){
    330                         this.data[r][c]*=2;
    331                         this.score+=this.data[r][c];
    332                         this.data[nextr][c]=0;
    333                     }
    334                     }
    335                 },
    336                     
    337                 getNextCol:function(r,c){
    338                     for(var i=r+1;i<this.data.length;i++){
    339                         if(this.data[i][c]!=0) return i;    
    340                     }
    341                     return -1;
    342                 },
    343                 
    344                 //向下移动所有列
    345                 moveDown:function(){
    346                     var before=String(this.data);
    347                     for(var c=0;c<this.data.length;c++){
    348                         this.moveDownCol(c);
    349                     }
    350                     var after=String(this.data);
    351                     if(before!=after){
    352                         this.randomNum();
    353                         if(this.isGameOver()){
    354                             this.state=this.GAMEOVER;
    355                         }
    356                         this.updateView();
    357                     }
    358                 },
    359                 
    360                 moveDownCol:function(c){
    361                     for(var r=this.data.length-1;r>0;r--){
    362                         var prer=this.getPreCol(r,c)
    363                         if(prer==-1) {
    364                             break;
    365                         }
    366                         else if(this.data[r][c]==0){
    367                             this.data[r][c]=this.data[prer][c];
    368                             this.data[prer][c]=0;
    369                             r++;
    370                         }else if(this.data[r][c]==this.data[prer][c]){
    371                             this.data[r][c]*=2;
    372                             this.score+=this.data[r][c];
    373                             this.data[prer][c]=0;
    374                         }
    375                     }
    376                 },
    377                 
    378                 getPreCol:function(r,c){
    379                     for(var i=r-1;i>=0;i--){
    380                         if(this.data[i][c]!=0) return i;    
    381                     }
    382                     return -1;
    383                 },
    384                 
    385                 isGameOver:function(){
    386                     //游戏结束条件:
    387                     //1.数组中所有数据均不为0;
    388                     //2.数组中每一行数据相邻位置值不相等
    389                     //3.数组中每一列数据相邻位置值不相等
    390                     for(var c=0;c<this.data.length;c++){
    391                         for(var r=0;r<this.data.length;r++){
    392                             //判断所有不为0
    393                             if(this.data[r][c]==0){
    394                                 return false;
    395                             }
    396                             if(c<3){
    397                                 if(this.data[r][c]==this.data[r][c+1]){
    398                                     return false;
    399                                 }
    400                             }
    401                             if(r<3){
    402                                 if(this.data[r][c]==this.data[r+1][c]){
    403                                     return false;
    404                                 }
    405                             }
    406                         }
    407                     }
    408                     return true;
    409                 }
    410             }
    411             
    412             //调用函数开始游戏
    413             game.start();
    414             document.onkeydown=function(event){
    415                 //按下左键或者字母键a,向左移动
    416                 if(event.keyCode==37 || event.keyCode==65 ){
    417                     game.moveLeft();
    418                 }
    419                 //按下向上键或者字母键w,向上移动
    420                 if(event.keyCode==38 || event.keyCode==87 ){
    421                     game.moveUp();
    422                 }
    423                 //按下右键或者字母键d,向右移动
    424                 if(event.keyCode==39 || event.keyCode==68 ){
    425                     game.moveRight();
    426                 }
    427                 //按下向下键或者字母键s,向下移动
    428                 if(event.keyCode==40 || event.keyCode==83 ){
    429                     game.moveDown(); 
    430                 }
    431                 //按下空格键重新开始游戏
    432                 if(event.keyCode==32 ){
    433                     game.start();
    434                 }
    435                 
    436             }
    437             
    438         </script>
    439     </body>
    440 </html>!
  • 相关阅读:
    python自动发邮件库yagmail
    Vmware改成bridge方式联网
    centos7 更新Firefox版本
    无法应用转换程序,请检查指定的转换程序路径是否有效
    python中list/tuple/dict/set的区别
    Python中的*arg和**kwarg
    centos7.4下搭建JDK+Tomcat+Nginx+Mysql+redis+Mongodb+maven+Git+Jenkins
    用 Apache Derby 进行 ODBC 编程
    Derby 命令
    Python与数据库
  • 原文地址:https://www.cnblogs.com/wcx-20151115-hzz/p/10110607.html
Copyright © 2020-2023  润新知