源代码在效果图后面
效果图
源代码
<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>2048 Game</title><style>body {margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;background: #f7f7f7;font-family: Arial, sans-serif;}.game-container {width: 400px;height: 400px;background: #fff;border-radius: 10px;overflow: hidden;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);}.tile {width: 25%;height: 25%;box-sizing: border-box;position: relative;background: #fff;border: 1px solid #eaeaea;margin: 0;float: left;text-align: center;line-height: 100px;font-size: 48px;color: #776e65;border-radius: 10px;transition: transform 0.2s;}.tile:after {content: '';display: block;padding-top: 100%;}.tile.new {animation: slideIn 0.5s;}.tile.tile-2 {background: #eee4da;}.tile.tile-4 {background: #ede0c8;}.tile.tile-8 {background: #f2b47b;}.tile.tile-16 {background: #f59563;}.tile.tile-32 {background: #f67c5f;}.tile.tile-64 {background: #f65e3b;}.tile.tile-128 {background: #edcf72;}.tile.tile-256 {background: #edcc61;}.tile.tile-512 {background: #edc850;}.tile.tile-1024 {background: #edc53f;}.tile.tile-2048 {background: #edc22e;}@keyframes slideIn {0% {transform: translate(-50%, -50%) rotate(90deg);}100% {transform: translate(-50%, -50%) rotate(0deg);}}</style>
</head><body><div class="game-container" id="game-container"></div><div style="margin-top: 20px;"><button onclick="moveUp()">上</button><button onclick="moveDown()">下</button><button onclick="moveLeft()">左</button><button onclick="moveRight()">右</button></div><script>const container = document.getElementById('game-container');let grid = [];let score = 0;function createGrid() {for (let i = 0; i < 4; i++) {const row = [];for (let j = 0; j < 4; j++) {const tile = document.createElement('div');tile.classList.add('tile');tile.dataset.row = i;tile.dataset.col = j;container.appendChild(tile);row.push(tile);}grid.push(row);}}function addRandomTile() {const emptyCells = [];grid.forEach((row, rowIndex) => {row.forEach((tile, colIndex) => {if (!tile.classList.contains('tile-2') &&!tile.classList.contains('tile-4') &&!tile.classList.contains('tile-8') &&!tile.classList.contains('tile-16') &&!tile.classList.contains('tile-32') &&!tile.classList.contains('tile-64') &&!tile.classList.contains('tile-128') &&!tile.classList.contains('tile-256') &&!tile.classList.contains('tile-512') &&!tile.classList.contains('tile-1024') &&!tile.classList.contains('tile-2048')) {emptyCells.push({ row: rowIndex, col: colIndex });}});});if (emptyCells.length) {const randomIndex = Math.floor(Math.random() * emptyCells.length);const cell = emptyCells[randomIndex];const value = Math.random() > 0.5? 2 : 4;addTile(cell.row, cell.col, value);}}function addTile(row, col, value) {const tile = grid[row][col];tile.classList.add(`tile-${value}`);tile.textContent = value;}function removeTile(row, col) {const tile = grid[row][col];tile.classList.remove('tile-2', 'tile-4', 'tile-8', 'tile-16', 'tile-32', 'tile-64', 'tile-128', 'tile-256', 'tile-512', 'tile-1024', 'tile-2048');tile.textContent = '';}function moveUp() {for (let col = 0; col < 4; col++) {let merged = false;let newRow = [];for (let row = 0; row < 4; row++) {const tile = grid[row][col];if (tile.textContent === '') continue;let currentValue = parseInt(tile.textContent);if (newRow.length === 0) {newRow.push(currentValue);} else {const lastValue = newRow[newRow.length - 1];if (lastValue === currentValue &&!merged) {newRow[newRow.length - 1] = currentValue * 2;score += currentValue * 2;merged = true;} else {newRow.push(currentValue);merged = false;}}}for (let row = 0; row < 4; row++) {if (row < newRow.length) {addTile(row, col, newRow[row]);} else {removeTile(row, col);}}}addRandomTile();}function moveDown() {for (let col = 0; col < 4; col++) {let merged = false;let newRow = [];for (let row = 3; row >= 0; row--) {const tile = grid[row][col];if (tile.textContent === '') continue;let currentValue = parseInt(tile.textContent);if (newRow.length === 0) {newRow.push(currentValue);} else {const lastValue = newRow[newRow.length - 1];if (lastValue === currentValue &&!merged) {newRow[newRow.length - 1] = currentValue * 2;score += currentValue * 2;merged = true;} else {newRow.push(currentValue);merged = false;}}}for (let row = 3; row >= 0; row--) {if (3 - row < newRow.length) {addTile(row, col, newRow[3 - row]);} else {removeTile(row, col);}}}addRandomTile();}function moveLeft() {for (let row = 0; row < 4; row++) {let merged = false;let newCol = [];for (let col = 0; col < 4; col++) {const tile = grid[row][col];if (tile.textContent === '') continue;let currentValue = parseInt(tile.textContent);if (newCol.length === 0) {newCol.push(currentValue);} else {const lastValue = newCol[newCol.length - 1];if (lastValue === currentValue &&!merged) {newCol[newCol.length - 1] = currentValue * 2;score += currentValue * 2;merged = true;} else {newCol.push(currentValue);merged = false;}}}for (let col = 0; col < 4; col++) {if (col < newCol.length) {addTile(row, col, newCol[col]);} else {removeTile(row, col);}}}addRandomTile();}function moveRight() {for (let row = 0; row < 4; row++) {let merged = false;let newCol = [];for (let col = 3; col >= 0; col--) {const tile = grid[row][col];if (tile.textContent === '') continue;let currentValue = parseInt(tile.textContent);if (newCol.length === 0) {newCol.push(currentValue);} else {const lastValue = newCol[newCol.length - 1];if (lastValue === currentValue &&!merged) {newCol[newCol.length - 1] = currentValue * 2;score += currentValue * 2;merged = true;} else {newCol.push(currentValue);merged = false;}}}for (let col = 3; col >= 0; col--) {if (3 - col < newCol.length) {addTile(row, col, newCol[3 - col]);} else {removeTile(row, col);}}}addRandomTile();}function checkGameEnd() {// 检查是否无法再进行移动let canMove = false;for (let row = 0; row < 4; row++) {for (let col = 0; col < 4; col++) {const tile = grid[row][col];if (tile.textContent === '') {canMove = true;break;}if (row > 0 && parseInt(grid[row - 1][col].textContent) === parseInt(tile.textContent)) {canMove = true;break;}if (row < 3 && parseInt(grid[row + 1][col].textContent) === parseInt(tile.textContent)) {canMove = true;break;}if (col > 0 && parseInt(grid[row][col - 1].textContent) === parseInt(tile.textContent)) {canMove = true;break;}if (col < 3 && parseInt(grid[row][col + 1].textContent) === parseInt(tile.textContent)) {canMove = true;break;}}if (canMove) break;}if (!canMove) {alert('游戏结束!你的得分是:' + score);}}document.addEventListener('keydown', (e) => {switch (e.key) {case 'ArrowUp':moveUp();break;case 'ArrowDown':moveDown();break;case 'ArrowLeft':moveLeft();break;case 'ArrowRight':moveRight();break;}});createGrid();addRandomTile();addRandomTile();</script>
</body></html>