前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >开发 | 「小游戏」开发难?不妨先从 2048 入手试试看

开发 | 「小游戏」开发难?不妨先从 2048 入手试试看

作者头像
知晓君
发布2018-07-26 15:11:35
3630
发布2018-07-26 15:11:35
举报
文章被收录于专栏:知晓程序知晓程序
作者:windlany

最近流行微信「跳一跳」小游戏,我也心血来潮写了一个微信小程序版 2048,本篇文章主要分享实现 2048 的算法以及注意的点,一起来学习吧!

算法

  • 生成 4*4 棋盘视图
  • 随机生成 2 或 4 填充两个单元格
  • 记录用户 touch 时的起始位置和结束位置,以此判断滑动方向
  • 根据滑动方向移动单元格,并进行相同值合并
  • 用户一次滑动完成后重复执行步骤 2
  • 判断游戏是否结束,并根据游戏结果产生不同提示

难点

  • 确定滑动方向
  • 用户滑动时,相同格子合并,并移到滑动方向一侧

视图实现

1. 用 WXML + WXSS 生成棋盘视图

2. 用 wx:for 将数据渲染到每个单元格

逻辑实现

1. 页面加载完毕随机用数字 2 或 4 填充两个单元格

2. 判断用户滑动方向

  • 使用 touchStart 事件函数获取起始位置 touchStartX、touchStartY
  • 使用 touchMove 事件函数获取终点位置 touchEndX、touchEndY
代码语言:javascript
复制
var disX = this.touchStartX - this.touchEndX;
var absdisX = Math.abs(disX);
var disY = this.touchStartY - this.touchEndY;
var absdisY = Math.abs(disY);  

// 确定移动方向
// 0:上, 1:右, 2:下, 3:左
var direction = absdisX > absdisY ? (disX < 0 ? 1 : 3) : (disY < 0 ? 2 : 0);

3. 根据滑动方向(假设向右滑动)移动表格以及相同项合并

将 2048 的棋盘生成 4*4 的二维数组 list,为空的空格用 0 表示

代码语言:javascript
复制
var grid = [
    [2, 2, 0, 0],
    [0, 0, 0, 0],
    [0, 8, 4, 0],
    [0, 0, 0, 0]
];

根据滑动方向生成 4*4 二维数组

代码语言:javascript
复制
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):

代码语言:javascript
复制
formList(dir) {  // 根据滑动方向生成list的四个数组
  var list = [[], [], [], []];
  for (var i = 0; i < this.size; i++)
    for (var j = 0; j < this.size; j++) {
      switch (dir) {
        case 0:
          list[i].push(this.board.grid[j][i]);
          break;
        case 1:
          list[i].push(this.board.grid[i][this.size - 1 - j]);
          break;
        case 2:
          list[i].push(this.board.grid[this.size - 1 - j][i]);
          break;
        case 3:
          list[i].push(this.board.grid[i][j]);
          break;
      }
    }
  return list;
}

将 list 的每一个小数组中的数字提到前面,0 放到末尾

代码语言:javascript
复制
list2 = [
    [2, 2, 0, 0],
    [0, 0, 0, 0],
    [4, 8, 0, 0],
    [0, 0, 0, 0]
];

相应代码:

代码语言:javascript
复制
changeItem(item) {  // 将 [0, 2, 0, 2] 改为 [2, 2, 0, 0]
    var cnt = 0;
    for(var i = 0; i < item.length; i++)
      if(item[i] != 0)
        item[cnt++] = item[i];
    for(var j = cnt; j < item.length; j++) 
      item[j] = 0;
    return item;
  }

将相同值的单元格加起来,并将后面的一个单元格值变为 0

代码语言:javascript
复制
list2 = [
    [4, 0, 0, 0],
    [0, 0, 0, 0],
    [4, 8, 0, 0],
    [0, 0, 0, 0]
];

相应代码:

代码语言:javascript
复制
combine(list) { // 滑动时相同的合并
  for (var i = 0; i < list.length; i++)  // 数字靠边
    list[i] = this.changeItem(list[i]);

  for (var i = 0; i < this.size; i++) {
    for (var j = 1; j < this.size; j++) {
      if (list[i][j - 1] == list[i][j] && list[i][j] != "") {
        list[i][j - 1] += list[i][j];
        list[i][j] = "";
      }
    }
  }
  for (var i = 0; i < list.length; i++)  // 再次数字靠边
    list[i] = this.changeItem(list[i]);
  return list;
}

将 list2 回退为 list 并渲染数据到棋盘视图

代码语言:javascript
复制
list = [
    [0, 0, 0, 4],
    [0, 0, 0, 0],
    [0, 0, 8, 4],
    [0, 0, 0, 0]
];

相应代码:

代码语言:javascript
复制
move(dir) {
  // 0:上, 1:右, 2:下, 3:左
  var curList = this.formList(dir);
  var list = this.combine(curList);
  var result = [[], [], [], []];

  for (var i = 0; i < this.size; i++)
    for (var j = 0; j < this.size; j++) {
      switch (dir) {
        case 0:
          result[i][j] = list[j][i];
          break;
        case 1:
          result[i][j] = list[i][this.size - 1 - j];
          break;
        case 2:
          result[i][j] = list[j][this.size - 1 - i];
          break;
        case 3:
          result[i][j] = list[i][j];
          break;
      }
    }
  this.board.grid = result;
  this.setDataRandom();

  return result;
}

4. 重复步骤 1

5. 判断游戏是否结束

判断标准:4*4 单元格填满且任意一个单元格上下左右没有相同值的单元格

代码语言:javascript
复制
isOver() {  // 游戏是否结束,结束条件:可用格子为空且所有格子上下左右值不等
  this.board.__proto__ = this.bproto;
  if (!this.board.cellEmpty()) {
    return false;
  } else {
    for (var i = 0; i < this.size; i++) // 左右不等
      for (var j = 1; j < this.size; j++) {
        if (this.board.grid[i][j] == this.board.grid[i][j - 1])
          return false;
      }
    for (var j = 0; j < this.size; j++)  // 上下不等
      for (var i = 1; i < this.size; i++) {
        if (this.board.grid[i][j] == this.board.grid[i - 1][j])
          return false;
      }
  }
  return true;
}

6. 根据游戏结果给出相应提示

原文地址: https://juejin.im/post/5a6690dd518825732c53ace5

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-01-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 知晓程序 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档