最近流行微信小游戏,我也心血来潮写了一个微信小程序版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表示
  1. // 比如棋盘数据如下
  2. var grid = [
  3. [2, 2, 0, 0],
  4. [0, 0, 0, 0],
  5. [0, 8, 4, 0],
  6. [0, 0, 0, 0]
  7. ];
  • 根据滑动方向生成4*4二维数组
  1. var list = [
  2. [0, 0, 2, 2], // 注意是0022不是2200,因为像右滑动所以从右边push入数组
  3. [0, 0, 0, 0],
  4. [0, 4, 8, 0],
  5. [0, 0, 0, 0]
  6. ];
相应代码(代码中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放到末尾
  1. list2 = [
  2. [2, 2, 0, 0],
  3. [0, 0, 0, 0],
  4. [4, 8, 0, 0],
  5. [0, 0, 0, 0]
  6. ];
相应代码:
  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
  1. list2 = [
  2. [4, 0, 0, 0],
  3. [0, 0, 0, 0],
  4. [4, 8, 0, 0],
  5. [0, 0, 0, 0]
  6. ];
相应代码:
  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并渲染数据到棋盘视图
  1. list = [
  2. [0, 0, 0, 4],
  3. [0, 0, 0, 0],
  4. [0, 0, 8, 4],
  5. [0, 0, 0, 0]
  6. ];
相应代码:
  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~

微信小程序版2048的更多相关文章

  1. 微信小程序版博客——开发汇总总结(附源码)

    花了点时间陆陆续续,拼拼凑凑将我的小程序版博客搭建完了,这里做个简单的分享和总结. 整体效果 对于博客来说功能页面不是很多,且有些限制于后端服务(基于ghost博客提供的服务),相关样式可以参考截图或 ...

  2. 七天开发进度(七)(微信小程序版(二)记账本)

    终于把小程序版弄完了,不过这并不能称之为是我的作品,因为我还没有彻底学会小程序,对JavaScript语言还有很多不会的地方,没有掌握, 这次的程序是通过学习网上的多个教程,多个案例结合拼凑模仿者人家 ...

  3. 七天开发进度(六)(微信小程序版(一))

    1. 今天主要根据网上教程学习了微信小程序的代码结构,和代码编写-Tabbar配置, 学习了app.js的App和Page方法, 认识了view组件,button组件,input组件,但是还没怎么应用 ...

  4. 重装了服务器,用的是centos/php微信小程序版,centos 命令大全

    centos 命令大全 1.关机 (系统的关机.重启以及登出 ) 的命令 shutdown -h now 关闭系统(1) init 0 关闭系统(2) telinit 0 关闭系统(3) shutdo ...

  5. 微信小程序代码大全 - 小程序开发福利

    小程序QQ交流群:131894955 小程序开发文档(Wepy) 小程序商城源码下载(weixin-app-shop) 小程序官网源码下载(weixin-app-cms) 微信管家平台JAVA版开源下 ...

  6. 史上最全的微信小程序代码大全

    --------------------- 本文来自 fenxiangjun 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/fenxiangjun/article/d ...

  7. 微信小程序开发(5) 2048游戏

    在这篇微信小程序开发教程中,我们将介绍如何使用微信小程序开发2048小游戏. 本文主要分为两个部分,小程序主体部分及小游戏页面部分 一.小程序主体部分 一个小程序主体部分由三个文件组成,必须放在项目的 ...

  8. 微信小程序(应用号)资源汇总整理

    微信小应用资源汇总整理 开源项目 WeApp - 微信小程序版的微信 wechat-weapp-redux-todos - 微信小程序集成Redux实现的Todo list wechat-weapp- ...

  9. 微信小程序实例源码大全

    微信小程序实例源码大全下载 微信小应用示例代码(phodal/weapp-quick)源码链接:https://github.com/phodal/weapp-quick 微信小应用地图定位demo( ...

随机推荐

  1. HBase跨地区机房的压测小程序——从开发到打包部署(图文版)

    今天做了一个跨地区机房的压测小程序,主要的思路就是基于事先准备好的rowkey文件,利用多线程模拟并发的rowkey查询,可以实现并发数的自由控制.主要是整个流程下来,遇到了点打包的坑,所以特意记录下 ...

  2. Git 进阶 —— 远程仓库

    一.远程仓库怎么玩 1. 自己搭建一个运行Git的服务器 Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上,但肯定有一台机器有着最原始的版本库,然后别的机器来克隆这个原始版本库,这 ...

  3. Django中Q查询及Q()对象

    问题 一般我们在Django程序中查询数据库操作都是在QuerySet里进行进行,例如下面代码: >>> q1 = Entry.objects.filter(headline__st ...

  4. powerdesigner的使用

    前言 做过建模和设计的人都知道,powerdesigner是个强大实用的工具:采用模型驱动方法,将业务与IT结合起来,可帮助部署有效的企业体系架构,并为研发生命周期管理提供强大的分析与设计技术.本文档 ...

  5. Struts2思维导图

    自己感觉自己的知识不是很扎实,所以昨天留时间复习知识,昨天边复习边画了一个思维导图.不知道自己画的对不对,还没有画完.有错的地方大家请和我说.希望自己能更加牢固的记住这些知识. 不说废话,开图.图有点 ...

  6. Xposed hook布局类资源文件的获取

    如题,可以hook状态栏,为系统状态栏添加一个TextView @Override public void handleInitPackageResources(XC_InitPackageResou ...

  7. 地址总线、数据总线、寻址能力、字长及cpu位数等概念之间的关系

    地址总线决定了CPU的寻址能力:数据总线的宽度与字长及CPU位数一致. 详细解释见下文: 1.地址总线与寻址能力 要存取数据或指令就要知道数据或指令存放的位置,地址寄存器存储的就是CPU当前要存取的数 ...

  8. windows 配置接收报文是否中断

    作用:网络编程的时候,编程接收报文,可以不用循环等待并判断是否报文接收完整.配置了windows禁用网络中端后,自己写的程序一次接收,便是整条报文. 步骤: 1."打开网络和共享中心&quo ...

  9. MySQL使用存储过程代替子查询

    摘要: 出处:黑洞中的奇点 的博客 http://www.cnblogs.com/kelvin19840813/ 您的支持是对博主最大的鼓励,感谢您的认真阅读.本文版权归作者所有,欢迎转载,但请保留该 ...

  10. 驱动开发入门——NTModel

    上一篇博文中主要说明了驱动开发中基本的数据类型,认识这些数据类型算是驱动开发中的入门吧,这次主要说明驱动开发中最基本的模型--NTModel.介绍这个模型首先要了解R3层是如何通过应用层API进入到内 ...