• 【2048小游戏】——原生js爬坑之遍历算法显示二维数组内容


    引言:做2048小游戏会将横纵方向的数字内容,存储在一个二维数组中,要将这个二维数组中的内容显示在页面上,就一定要用遍历算法来实现了。


    一、二维数组存储

     

    •  首先考虑用二维数组存储所有行数,列数  →  var  RN=4,CN=4;
    •  然后再定义一个变量data 来保存这个二维数组  →  var  data;
    •  游戏的所有主要执行程序都保存在start()函数下 → 启动游戏
    •  保存存有行数,列数的二维数组到data中    关键代码 ↓
    function  start(){
         data=[];     //创建空数组保存在data中
         for(var r=0;r<RN;r++){    //r从0到<RN
              data.push([]);      //向data中压入一个空的子数组
              for(var c=0;c<CN;c++){}       //c从0到<CN结束
                      data[r][c]=0;       //为data中r行c位置保存一个0
         ……
               }     
          }
    }
    start();  //调用start函数,游戏启动
    二、在二维数组中随机选一个位置生成2或4
    •  关键函数创建 →  function  randomNum(){ }
    •  生成横行和纵行的位置的随机数保存在r和c  →  0~RN-1之间,0~CN-1之间
    •  2048的游戏有一个重要特点,每移动一次数字会增加两个新的数字,并且这个数字不会覆盖掉原来的数字
    •  坑:只有在随机生成的位置处无数字,即data中r行c列的值为0时,才可以给data中r行c列随机保存一个2或4
    •  解决:反复执行上面的算法,直到条件满足,才保存这个随机的2或4
    •  坑:需要随机,且只能在2或4这两种情况中选择
    •  解决:因为Math.random()生成的随机数在0~1之间,且游戏要求又只有2种,可以依据判断生成的随机数是否<0.5来决定保存2或者是4,如果游戏要增加难度,希望其中一个数字的概率生成要大一点,那么这个0.5的数字即为出现概率控制的关键
    •  坑:2048的游戏每次增加的是两个新的数字
    •  解决:在调用随机生成函数randomNum()的时候,一定要调用两次,这样才可以生成两个数
    •  坑:这个时候页面上没有任何效果
    • 解决:因为现在还只是把数字保存在了内存中的二维数组里,还没有往页面上写,所以还需要再往页面上写,查的时候只能在控制台上查
    //在data中一个随机位置生成2或4
    function randomNum(){
        while(true){
            var r = parseInt(Math.random()*RN);
            var c = parseInt(Math.random()*CN);
            if(data[r][c]==0){
                data[r][c]=Math.random()<0.5?2:4;//0.5控制2和4的出现几率
                break;
            }
        }
    }
    三、遍历算法将数组元素填写到页面对应div

     

    • 关键函数创建 → function updateView(){ }
    • 遍历到二维数组的元素之后,要和页面的div对应上,关键 ↓
    1. 页面div起名的时候,c01即表示第0行第1列的div
    2. 在拿到二维数组的元素后,“c”+行号+列号,就组成了对应div的id
    3. 拼好id之后,按id找到对应的div元素
    • 遍历data的二维数组  两个for循环 → 外层循环控制行,内层循环控制列
    • 将遍历到的r行c列的值保存到div的内容  →  div.innerHTML = data[r][c];
    • 坑:二维数组中r行c列的值可能是还未获得随机数时的  0 ,依据2048游戏的规则,这个时候是不能保存到div中的
    • 解决:加判断,如果r行c列的值不为0,才将值保存到div中;否则,r行c列的值为0的对应div中的内容清除掉,因为二维数组里的元素为0,实际上有两种情况,一种是还从未有过值,但这种情况会随着游戏的行移动次数增加,逐渐减少,更多的是,这个位置里面曾经有过一个值,并且div上也有过数字,但是经过行的移动移走了,这个时候,就要立即把对应的r行c列的div的内容也清除掉,这样才能保证页面数字的变化显示与二维数字中的变化相同。
    • 给内容数值为  * 的div的class添加一个  n*,同时清除div本身的class属性  →  n*为css中对应数字的特定背景颜色class 
    //将data中的每个元素填写到页面的对应div中
    updateView();
    
    function updataView(){
        //遍历data
        for(var r=0;r<this.RN;r++){
            for(var c=0;c<this.CN;c++){
                var id = "c"+r+c;
                var div = document.getElementById(id);
                if(this.data[r][c]!=0){
                   div.innerHTML = data[r][c];
                   div.className = "n"+data[r][c];
                }else{
                   div.innerHTML = "";
                   div.className = "";
                }
            }
        }
        var span = document.getElementById("score");
        span.innerHTML=score;
    }  

     



    注:转载请注明出处

  • 相关阅读:
    Warning: (1260, 'Row xxx was cut by GROUP_CONCAT()')
    MySQL之text字段
    将 Python 程序打包成 .exe 文件
    mysql json数据类型
    iOS边练边学--iOS中的json数据解析
    iOS边练边学--NSURLConnection发送HTTP请求以及NSString和NSData的相互转换
    iOS边练边学--Http网络再学习,简单介绍
    iOS边练边学--多线程练习的多图片下载 以及 使用第三方框架(SDWebImage)的多图片下载
    iOS边练边学--iOS中的(ARC下)单粒模式(GCD实现)
    iOS边练边学--cocoaPods管理第三方框架--命令行方式实现
  • 原文地址:https://www.cnblogs.com/ljq66/p/7784971.html
Copyright © 2020-2023  润新知