vue实现2048小游戏
演示
直接上demo
游戏规则
参考:2048 (游戏) - 维基百科
- 《2048》在4×4的网格上进行。玩家可以使用上、下、左、右四个方向键移动所有方块。但在部分情形下,某些方向不可移动。
- 游戏开始时,网格上会出现两个数值为2或4的方块。
- 每次移动后,另一个数值为2或4的新方块会随机出现在空方格上。
- 方块会沿着指定的方向滑动,直到被其它方块或网格边缘阻挡。
- 如果两个相同数值的方块碰撞,它们将合并成一个方块,其数值等于两个方块的数值之和。
- 如果三个数值相同的方块碰撞,则只会合并靠近终点方向的两个方块,距起点最近的方块的数值不变。
- 若一行或一列中的方块数值均相同,则沿着该行或该列滑动会合并前两个和后两个方块。
- 在同一移动过程中,新生成的方块不能再与其他方块合并。
- 数值较高的方块会发出柔和的光芒;但随着得分增加,光芒会不断变暗。
- 方块数值都是2的幂,最大为131072。
- 界面右上方的记分牌会记录玩家的分数。玩家的初始分数为零,每当两个方块合并时,分数会增加,得分取决于合并后方块的数值。
游戏玩法就是上下左右操作,相应地滑动、合并、创建新块
完善游戏还有一些附加功能,比如计分、撤回、重新开始、游戏结束等,demo暂不考虑这些
分析
游戏数据是一个4*4的矩阵
对于一个左划操作:
- 滑动:将矩阵的每一行向左移动
- 合并:如果相邻的两个方块的值相同,合并成一个方块,只合并一次
对于其它方向的操作,可以通过矩阵的转置、反转来归为左划操作。完成数据处理后再转换回来即可
代码实现
完整demo见第一节的演示👆
- “行”的移动处理:
// 移动,例如:[2,null,2,2] -> [2,2,2,null]
function moveToLeft(row) {
let count = 0
// 遍历数组,将有效值依次从头(count)开始赋值到原数组上
row.forEach((cell, colIdx) => {
if (!cell) return
row[colIdx] = null
row[count++] = cell
})
}
- “行”的合并处理:
// 合并,例如:[2,2,2,null] -> [4,2,null,null], [2,2,2,2] -> [4,4,null,null]
function mergeToLeft(row) {
let count = 0
// 遍历数组,连续两个相同有效值合并。将合并值或原值依次从头(count)开始赋值到原数组上
for (let i = 0; i < row.length; i++) {
const cell = row[i]
if (!cell) continue
row[i] = null
// 合并
if (cell === row[i + 1]) {
row[i + 1] = null
const newCell = cell * 2
row[count++] = newCell
i++
} else {
row[count++] = cell
}
}
}
其实完全可以一次遍历完成移动与合并,但可能会更复杂,难以理解
JUST FOR FUN
最后,这是个人开发部署的一个在线2048游戏