前言前段时间发现网上有很多收费或公开课都有教用 js 做 2048 小游戏的,然后自己就也想动手做一个,做这个小游戏主要是为了锻炼自己的逻辑能力,也算是对之前一些学习的总结吧 注:实现方法完全是自己边玩 2048 边想的,所有些乱还请见谅另外配色方案是在某个 2048 游戏截屏,然后用 ps 吸取的,非本人原创代码中有很多都可以使用数组相关的方法来代替,这里是为了自己理解数组方法是什么原理由于时间关系本次不做详解游戏逻辑随机位置生成数字 2 或 4按方向键,有挨着的相同的数字就合并成新的数字按方向键,数字会移动到对应方向的最边上(按左,数字全部移动到左边)每次按方向键,合并完成后,会在没有数字的随机位置都会生成新的数字 2 或 4当前分数等于当前所有数字相加当有数字达到 2048 游戏结束项目相关这个版本是用原生 ES6 写的,只实现了游戏逻辑中的 1,2,3,4; 第一版地址:https://github.com/yhtx1997/S…之后是打算用 vue 重新写一遍,并且完善下,因为长时间用原生,导致 vue 有些生疏,借此机会重新温习下项目代码采用二维数组进行数据的管理,默认全部为零let arr = [ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];随机创建数字let s = 0;let create = () => { let x = Math.floor(Math.random() * 4); let y = Math.floor(Math.random() * 4); // console.log(s) if (s > 100) { s = 0; return; } if (arr[x][y] == 0) { if (Math.floor(Math.random() * 10) % 2 == 0) { arr[x][y] = 2; } else { arr[x][y] = 4; } s = 0; return; } else { s++; return create(); }}渲染页面let updateHtml = () => { //获取元素 let warp = document.getElementById(‘warp’); let html = ‘’; //将数据转换为 HTML for (let i = 0; i < arr.length; i++) { for (let j = 0; j < arr[i].length; j++) { html += &lt;div class='c c-${arr[i][j]}'&gt;${arr[i][j]==0?'':arr[i][j]}&lt;/div&gt;; } } //将 数据转换的 HTML 渲染到页面 warp.innerHTML = html;}事件监听window.onkeydown = (e) => { switch (e.keyCode) { case 37: // ← console.log(’←’); arr = new move(arr).moveLeft(); create(); //随机位置新建 updateHtml(); //更新数据到页面 break; case 38: // ↑ console.log(’↑’); arr = new move(arr).moveUp(); create(); //随机位置新建 updateHtml(); //更新数据到页面 break; case 39: // → console.log(’→’); arr = new move(arr).moveRight(); create(); //随机位置新建 updateHtml(); //更新数据到页面 break; case 40: // ↓ console.log(’↓’); arr = new move(arr).moveDown(); create(); //随机位置新建 updateHtml(); //更新数据到页面 break; }}具体处理函数先提取非零数字export default function ClearZero (arr){//去零 let clearZero = [[],[],[],[]]; for (let i = 0; i < 4; i++) { for (let j = 0; j < 4; j++) { if (arr[i][j] != 0) { clearZero[i].push(arr[i][j]) } } } return clearZero;}将挨着的相等数字分组并相加分组import Deduplication from ‘./deduplication’;//将相邻且相同的数字相加export default class Grouping{//将相邻的相同数字分组 constructor(clearZero){ this.clearZero = clearZero; } left(){ let newarr = [[],[],[],[]]; for (let j = 0; j < this.clearZero.length; j++) { let grouping = []; let i = 0; //将重复的 分到一组 while (i < this.clearZero[j].length) { if (this.clearZero[j][i] == this.clearZero[j][i + 1]) { grouping.push([this.clearZero[j][i], this.clearZero[j][i + 1]]); i += 2; } else { grouping.push(this.clearZero[j][i]); i++; } } //去重复 newarr[j] = Deduplication(grouping); } return newarr; } right(){ let newarr = [[],[],[],[]]; for (let i = 0; i < this.clearZero.length; i++) { let grouping = []; let j = this.clearZero[i].length - 1; //将重复的 分到一组 while (j >= 0) { if (this.clearZero[i][j] == this.clearZero[i][j - 1]) { grouping.unshift([this.clearZero[i][j], this.clearZero[i][j - 1]]); j -= 2; } else { grouping.unshift(this.clearZero[i][j]); j–; } } //将重复的进行计算 newarr[i] = Deduplication(grouping); } return newarr; }}相加export default function Deduplication (grouping){//将相邻且相同的数字相加 for (let i = 0; i < grouping.length; i++) { if (typeof grouping[i] == ‘object’) { grouping[i] = grouping[i][0] + grouping[i][1]; } } return grouping;}添加占位用的零export default function AddZero (newarr,w){//加零 for (let i = 0; i < newarr.length; i++) { while (newarr[i].length != 4) { if(w == ’l’){ newarr[i].push(0); }else if(w == ‘r’){ newarr[i].unshift(0); } } } return newarr;}上下的处理将 Y 轴的处理转换成 X 轴的处理export default function turn(arr) {//将数组转一下 let clearZero = [[],[],[],[]]; for (let i = 0; i < 4; i++) { for (let j = 0; j < 4; j++) { clearZero[i][j] = arr[j][i] } } return clearZero;}等处理完成后再调用上边的函数,将 X 轴的处理结果转换回 Y 轴的表现方式