源代码在效果图后面
效果图
源代码
<!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>