试玩地址 http://dryqiao.com/vue-2048/
项目地址 https://github.com/dryqiao/vue-2048
使用方法:
- git clone
- npm i
- npm run dev
实现思路如下:
用 vue-cli 搭建项目, 对这个项目可能有点笨重, 但是也懒的再搭一个
4X4 的方格用一个二维数组存放, 绑定好后只关心这个二维数组, 其他事交给 vue
监听键盘事件
2048 的核心部分就是移动合并的算法, 因为是一个 4X4 的矩阵, 所以只要实现左移的算法, 其他方向的移动只需要将矩阵旋转, 移动合并, 再旋转回来, 渲染 dom 即可
绑定不同数值的样式
分值计算, 以及用 localstorage 存放最高分
关键实现
- DOM
- <div class="box">
- <div class="row" v-for="row in list">
- <div class="col" :class="'n-'+col"v-for="col in row">{col}}</div>
- </div>
- </div>
主要的游戏部分的 DOM, 很简单, 用一个二维数组渲染, 并动态绑定样式
左移
主要由以下几种情况:
- 2 2 2 2 => 4 4 0 0
- 4 2 2 2 => 4 4 2 0
- 0 4 2 2=> 4 4 0 0
- 2 2 4 2 => 4 4 2 0
按单行数据举例,
遍历单行数组, 若存在数据, 记为 cell, 寻找 cell 往左可移到的最远空位置 farthest
判断 farthest 的左边是否存在, 不存在则直接移到到 farthest
若存在, 则判断 farthest - 1 的值和 cell 是否相同
相同 => 合并
不相同 => 移到 farthest 位置
移动完后, 清空 cell
下一轮
因为一轮移动中, 一个数只能合并一次, 所以每个格子要有 merged 参数来记录是否已经合并过.
主要代码:
- _list.forEach(item => {
- let farthest = this.farthestPosition(list, item)
- let next = list[farthest - 1]
- if (next && next === item.value && !_list[farthest - 1].merged) {
- // 合并
- list[farthest - 1] = next * 2
- list[item.x] = undefined
- item = {
- x: farthest - 1,
- merged: true,
- value: next * 2
- }
- this.score += next * 2
- } else {
- if (farthest != item.x) {
- list[farthest] = item.value
- list[item.x] = undefined
- item.x = farthest
- }
- }
- })
矩阵旋转
因为上移, 下移, 左移, 右移实际上是相同的, 写 4 遍也可以, 但是容易出错, 所以我直接旋转将矩阵旋转, 再进行移动.
以上移为例, 只要将矩阵逆时针旋转一次, 上移就变成了左移, 移动合并成之后, 只要再将矩阵逆时针旋转 4-1 次, 矩阵就和单纯上移一样了.
逆时针旋转算法:
- rotate(arr, n) {
- n = n % 4
- if (n === 0) return arr
- let tmp = Array.from(Array(this.size)).map(() => Array(this.size).fill(undefined))
- for (let i = 0; i <this.size; i++) {
- for (let j = 0; j < this.size; j++) {
- tmp[this.size - 1 - i][j] = arr[j][i]
- }
- }
- if (n> 1) tmp = this.rotate(tmp, n - 1)
- return tmp
- },
到这时候已经完成了 80% 了, 只要再完善一下, 加入分值, 重新开始等功能就可以了.
总结
以上所述是小编给大家介绍的 vue 实现 2048 小游戏功能思路详解, 希望对大家有所帮助, 如果大家有任何疑问请给我留言, 小编会及时回复大家的. 在此也非常感谢大家对脚本之家网站的支持!
来源: http://www.jb51.net/article/139777.htm