开发 | 「小游戏」开发难?不妨先从 2048 入手试试看
作者: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
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 表示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):
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 放到末尾
list2 = [[
2
,2
,0
,0
],[
0
,0
,0
,0
],[
4
,8
,0
,0
],[
0
,0
,0
,0
]];
相应代码:
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;}将相同值的单元格加起来,并将后面的一个单元格值变为 0list2 = [
[
4
,0
,0
,0
],[
0
,0
,0
,0
],[
4
,8
,0
,0
],[
0
,0
,0
,0
]];
相应代码:
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 并渲染数据到棋盘视图
list = [[
0
,0
,0
,4
],[
0
,0
,0
,0
],[
0
,0
,8
,4
],[
0
,0
,0
,0
]];
相应代码:
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 单元格填满且任意一个单元格上下左右没有相同值的单元格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. 根据游戏结果给出相应提示
原文地址:
http://juejin.im/post/5a6690dd518825732c53ace5
关注「知晓程序
」微信公众号,回复「开发
」,让你的小程序性能再上一层楼。▽ 点击「
阅读原文
」,发现更多优质小程序。
- 我们的宇宙可能是虚拟的,也许只是智者开发的一款虚拟游戏而已
- 过年别一个人玩手机了,叫上家人一起来玩小游戏吧!
- 央视《开讲啦!》论右脑开发的重要性!
- 大揭秘!春节刷爆朋友圈的这款小游戏,竟是这样做出来的…
- 开发区东区禁放倡议书
- 开发区东区节前慰问送温暖
- 中国和菲律宾将商讨如何共同开发南海油气资源
- 过年别一个人玩手机了,叫上家人一起来玩「小游戏」吧!
- 《骑马与砍杀2》新开发日志公布!三大帝国特色介绍
- 《战争机器》开发商新作疑被泄露《完美黑暗》重启