zoukankan      html  css  js  c++  java
  • 微信小程序版2048

    最近流行微信小游戏,我也心血来潮写了一个微信小程序版2048,本篇文章主要分享实现2048的算法以及注意的点,一起来学习吧!(源码地址见文章末尾)
     
    算法
    1、生成4*4棋盘视图
    2、随机生成2或4填充两个单元格
    3、记录用户touch时的起始位置和结束位置,以此判断滑动方向
    4、根据滑动方向移动单元格,并进行相同值合并
    5、用户一次滑动完成后重复执行步骤2
    6、判断游戏是否结束,并根据游戏结果产生不同提示
    难点
    1、确定滑动方向
    2、用户滑动时相同格子合并,并移到滑动方向一侧
    实现
     
    视图实现
    1、用wxml+wxss生成棋盘视图
    2、用wx:for将数据渲染到每个单元格
     
    逻辑实现
    1、页面加载完毕随机用数字2或4填充两个单元格
    2、判断用户滑动方向
    • 使用touchStart事件函数获取起始位置touchStartX、touchStartY,touchMove获取终点位置touchEndX、touchEndY
    1 var disX = this.touchStartX - this.touchEndX; 
    2 var absdisX = Math.abs(disX); 
    3 var disY = this.touchStartY - this.touchEndY; 
    4 var absdisY = Math.abs(disY); 
    5 // 确定移动方向 
    6 // 0:上, 1:右, 2:下, 3:左 
    7 var direction = absdisX > absdisY ? (disX < 0 ? 1 : 3) : (disY < 0 ? 2 : 0);
    3、根据滑动方向(假设向右滑动)移动表格以及相同项合并
    • 将2048的棋盘生成4*4的二维数组list,为空的空格用0表示
    // 比如棋盘数据如下 
    var grid = [
        [2, 2, 0, 0], 
        [0, 0, 0, 0], 
        [0, 8, 4, 0], 
        [0, 0, 0, 0] 
    ];
    • 根据滑动方向生成4*4二维数组
    var list = [ 
        [0, 0, 2, 2], // 注意是0022不是2200,因为像右滑动所以从右边push入数组 
        [0, 0, 0, 0], 
        [0, 4, 8, 0], 
        [0, 0, 0, 0] 
    ];
    相应代码(代码中this.board.grid为上面的初始grid):
     1 formList(dir) {  // 根据传入的滑动方向生成list的四个数组
     2     var list = [[], [], [], []];
     3     for(var i = 0; i < this.size; i++)
     4       for(var j = 0; j < this.size; j++) {
     5         switch(dir) {
     6           case 0:
     7             list[i].push(this.board.grid[j][i]);
     8             break;
     9           case 1:
    10             list[i].push(this.board.grid[i][this.size-1-j]);
    11             break;
    12           case 2:
    13             list[i].push(this.board.grid[this.size-1-j][i]);
    14             break;
    15           case 3:
    16             list[i].push(this.board.grid[i][j]);
    17             break;
    18         }
    19       }
    20     return list;
    21   }
    • 将list的每一个小数组中的数字提到前面,0放到末尾
    list2 = [ 
        [2, 2, 0, 0], 
        [0, 0, 0, 0], 
        [4, 8, 0, 0], 
        [0, 0, 0, 0] 
    ];
    相应代码:
    1 changeItem(item) {  // 将 [0, 2, 0, 2] 改为 [2, 2, 0, 0]
    2     var cnt = 0;
    3     for(var i = 0; i < item.length; i++)
    4       if(item[i] != 0)
    5         item[cnt++] = item[i];
    6     for(var j = cnt; j < item.length; j++) 
    7       item[j] = 0;
    8     return item;
    9   }
    • 将相同值的单元格加起来,并将后面的一个单元格值变为0
    list2 = [ 
        [4, 0, 0, 0], 
        [0, 0, 0, 0], 
        [4, 8, 0, 0], 
        [0, 0, 0, 0] 
    ];
    相应代码:
     1 combine(list) { // 滑动时相同的合并
     2     for(var i = 0; i < list.length; i++)  // 数字靠边
     3       list[i] = this.changeItem(list[i]);
     4 
     5     for(var i = 0; i < this.size; i++) { 
     6       for(var j = 1; j < this.size; j++) {
     7         if(list[i][j-1] == list[i][j] && list[i][j]!=0) {
     8           list[i][j-1] += list[i][j];
     9           list[i][j] = 0; 
    10         }
    11       }
    12     }
    13     for (var i = 0; i < list.length; i++)  // 再次数字靠边,避免0220变成0400的情况发生
    14       list[i] = this.changeItem(list[i]);
    15 
    16     return list;
    17   }
    • 将list2回退为list并渲染数据到棋盘视图
    list = [ 
        [0, 0, 0, 4], 
        [0, 0, 0, 0], 
        [0, 0, 8, 4], 
        [0, 0, 0, 0] 
    ];
    相应代码:
     1 move(dir) {
     2     // 0:上, 1:右, 2:下, 3:左
     3     var curList = this.formList(dir);
     4 
     5     var list = this.combine(curList); 
     6     var result = [[],[],[],[]];
     7 
     8     for(var i = 0; i < this.size; i++)
     9       for(var j = 0; j < this.size; j++) {
    10         switch (dir) {
    11           case 0:
    12             result[i][j] = list[j][i];
    13             break;
    14           case 1:
    15             result[i][j] = list[i][this.size-1-j];
    16             break;
    17           case 2:
    18             result[i][j] = list[j][this.size-1-i];
    19             break;
    20           case 3:
    21             result[i][j] = list[i][j];
    22             break;
    23         }
    24       } 
    25     this.board.grid = result;
    26     this.setDataRandom();  // 移动一次之后随机用2或4填充两个单元格
    27 
    28     return result;
    29   }
    4、重复步骤1
    5、判断游戏是否结束
    • 判断标准:4*4单元格填满且任意一个单元格上下左右没有相同值的单元格
     1 isOver() {  // 游戏是否结束,结束条件:可用格子为空且所有格子上下左右值不等
     2   for (var i = 0; i < this.size; i++) // 左右不等
     3     for (var j = 1; j < this.size; j++) {
     4       if (this.board.grid[i][j] == this.board.grid[i][j - 1])
     5         return false;
     6     }
     7   for (var j = 0; j < this.size; j++)  // 上下不等
     8     for (var i = 1; i < this.size; i++) {
     9       if (this.board.grid[i][j] == this.board.grid[i - 1][j])
    10         return false;
    11     }
    12   return true;
    13 } 
    6、根据游戏结果给出相应提示
     
    po一个源码地址:windlany/2048有兴趣的可以fork一下,求star~
  • 相关阅读:
    【java开发需要的环境资源以及开发工具】慢慢更新
    【如何编写有质量代码】【转】
    base——JavaSE&&JavaEE&&JavaME的区别【Java中常用的包结构】
    Mysqlsql——And【sql语句之为何用and一个字段两个值得不到表中的数据】
    Struts2——执行流程
    base——本地资源路径&&网络资源路径&&正反斜杠在Java中的用法
    base——new File(String Path)加载资源问题
    2019-06-11_Python中文编码
    2019-06-11-Python简介
    2019-06-05 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.taotao.search.mapper.SearchItemMapper.getItemList
  • 原文地址:https://www.cnblogs.com/wind-lanyan/p/8365185.html
Copyright © 2011-2022 走看看