行业知识
【趣味项目】2048 简单实现
2026-11-12 01:20:09
来源:互联网转载
【趣味项目】2048 简单实现
算法原理
��设用一个二维矩阵表示 2048 页面,操作是左滑
const matrix = [ [2, 2, 4, 0], [0, 2, 4, 0], [0, 2, 2, 0], [2, 4, 4, 8]];
-
将所有非空的数字向左移动
matrix = [ [2, 2, 4, 0], [2, 4, 0, 0], [2, 2, 0, 0], [2, 4, 4, 8]]
-
将相邻的相同数字合并
matrix = [ [4, 0, 4, 0], [2, 4, 0, 0], [4, 0, 0, 0], [2, 8, 0, 8]]
-
将所有非空的数字向左移动
matrix = [ [4, 4, 0, 0], [2, 4, 0, 0], [4, 0, 0, 0], [2, 8, 8, 0]]
-
将相邻的相同数字合并
matrix = [ [8, 0, 0, 0], [2, 4, 0, 0], [4, 0, 0, 0], [2, 8, 8, 0]]
-
将所有非空的数字向左移动
matrix = [ [8, 0, 0, 0], [2, 4, 0, 0], [4, 0, 0, 0], [2, 8, 8, 0] ]
-
将相邻的相同数字合并
matrix = [ [8, 0, 0, 0], [2, 4, 0, 0], [4, 0, 0, 0], [2, 16, 0, 0]]
用 js 实现上述操作
const moveLeft = (matrix) => { const moveLeftOnce = (matrix) => { const size = matrix.length; // 第一步:将所有非零的数字向左移动 for (let i = 0; i item !== 0); let zeroCount = size - currentRow.length; matrix[i] = currentRow.concat(Array(zeroCount).fill(0)); } // 第二步:将相邻的相同数字合并 for (let i = 0; i- 左滑
- 右滑: 翻转 -> 左滑 -> 翻转
- 上滑: 对角线翻折 -> 左滑 -> 对角线翻折
- 下滑: 对角线翻折 -> 右滑 -> 对角线翻折
实现思路
- render 函数用于渲染外部容器和内部单元格
- 通过 requestAnimationFrame 循环调用 render 函数
- 添加键盘事件,借助复杂类型传参直接修改 matrix
- render 函数根据 matrix 遍历渲染单元格
- 键盘事件触发后检测是否结束
实现源码
仅为 JS 文件部分,其他文件及目录结构可在该仓库查看 GitCode
// main.jsconst moveLeft = (matrix) => { const moveLeftOnce = (matrix) => { const size = matrix.length; // 第一步:将所有非零的数字向左移动 for (let i = 0; i item !== 0); let zeroCount = size - currentRow.length; matrix[i] = currentRow.concat(Array(zeroCount).fill(0)); } // 第二步:将相邻的相同数字合并 for (let i = 0; i { const reverseMatrix = (matrix) => { const size = matrix.length; for (let i = 0; i { const transposeMatrix = (matrix) => { const size = matrix.length; const newMatrix = Array.from({ length: size }, () => Array(size).fill(0)); for (let i = 0; i { const transposeMatrix = (matrix) => { const size = matrix.length; const newMatrix = Array.from({ length: size }, () => Array(size).fill(0)); for (let i = 0; i { const color = { 0: '#CCC0B3', 2: '#EEE4DA', 4: '#EDE0C8', 8: '#F2B179', 16: '#F49563', 32: '#F5794D', 64: '#F55D37', 128: '#EEE863', 256: '#EDB04D', 512: '#ECB04D', 1024: '#EB9437', 2048: '#EA7821', }; const matrix = [ [2, 2, 4, 0, 4], [0, 2, 4, 0, 0], [0, 2, 2, 0, 16], [2, 4, 4, 8, 32], [2, 4, 4, 8, 32], ]; /** * 绘制一个单元格 * @param {string} color 颜色 * @param {number} num 数字 */ const renderPixel = (color, num) => { const p = document.createElement('p'); p.style.width = '100px'; p.style.height = '100px'; p.style.backgroundColor = color; p.style.fontSize = '40px'; p.style.textAlign = 'center'; p.style.lineHeight = '100px'; p.innerText = num; return p; } const size = matrix.length; const app = document.getElementById('app'); const render = (matrix) => { const container = document.createElement('p'); container.style.display = 'grid'; container.style.gridTemplateColumns = `repeat(${size}, 100px)`; container.style.gridTemplateRows = `repeat(${size}, 100px)`; container.style.width = `${size * 100}px`; container.style.height = `${size * 100}px`; container.style.border = '1px solid #000'; container.style.borderRadius = '5px'; container.style.margin = '100px auto'; container.style.boxShadow = '0 0 10px #000'; container.style.position = 'relative'; container.style.overflow = 'hidden'; container.style.backgroundColor = '#BBADA0'; container.style.borderRadius = '5px'; container.style.padding = '5px'; container.style.boxSizing = 'border-box'; container.style.transition = 'all 0.3s'; container.style.userSelect = 'none'; container.style.touchAction = 'none'; container.style.cursor = 'pointer'; for (let i = 0; i { app.innerHTML = ''; render(matrix); requestAnimationFrame(() => { update(matrix); }); } requestAnimationFrame(() => { update(matrix); }); document.addEventListener('keydown', (e) => { switch (e.key) { case 'ArrowLeft': moveLeft(matrix); break; case 'ArrowRight': moveRight(matrix); break; case 'ArrowUp': moveUp(matrix); break; case 'ArrowDown': moveDown(matrix); break; } const finishend = matrix.every((row) => row.every((item) => item !== 0)); if (finishend) { alert('Game Over!'); } else { const empty = []; for (let i = 0; i 0.5 ? 2 : 4; } });};window.onload = main;
上一篇:华三服务器如何配置raid?
下一篇:串口服务器怎么调参数?