1.效果如下:
2.代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>2048 游戏</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #faf8ef;
font-family: Arial, sans-serif;
}
.game-container {
position: relative;
width: 400px;
height: 400px;
background-color: #bbada0;
border-radius: 10px;
padding: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}
.tile {
position: absolute;
width: 80px;
height: 80px;
border-radius: 5px;
font-size: 45px;
font-weight: bold;
color: #fff;
text-align: center;
line-height: 80px;
}
.tile-2 { background-color: #eee4da; }
.tile-4 { background-color: #ede0c8; }
.tile-8 { background-color: #f2b179; }
.tile-16 { background-color: #f59563; }
.tile-32 { background-color: #f67c5f; }
.tile-64 { background-color: #f65e3b; }
.tile-128 { background-color: #edcf72; }
.tile-256 { background-color: #edcc61; }
.tile-512 { background-color: #edc850; }
.tile-1024 { background-color: #edc53f; }
.tile-2048 { background-color: #edc22e; }
.game-over, .game-win {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 36px;
font-weight: bold;
color: #ffffff;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
display: none;
padding: 20px;
background: rgba(0, 0, 0, 0.7);
border-radius: 10px;
}
.game-over { background-color: #ff3b30; }
.game-win { background-color: #4caf50; }
</style>
</head>
<body>
<div class="game-container" id="gameContainer">
<div class="game-over" id="gameOver">游戏结束</div>
<div class="game-win" id="gameWin">你赢了!</div>
</div>
<script>
const SIZE = 4;
const TILE_SIZE = 80;
const COLORS = {
2: '#eee4da',
4: '#ede0c8',
8: '#f2b179',
16: '#f59563',
32: '#f67c5f',
64: '#f65e3b',
128: '#edcf72',
256: '#edcc61',
512: '#edc850',
1024: '#edc53f',
2048: '#edc22e'
};
const gameContainer = document.getElementById('gameContainer');
const gameOverElement = document.getElementById('gameOver');
const gameWinElement = document.getElementById('gameWin');
let board = Array(SIZE).fill().map(() => Array(SIZE).fill(0));
let hasMoved = false;
function drawTile(x, y, value) {
const tile = document.createElement('div');
tile.className = `tile tile-${value}`;
tile.style.left = `${x * TILE_SIZE}px`;
tile.style.top = `${y * TILE_SIZE}px`;
tile.textContent = value || '';
gameContainer.appendChild(tile);
}
function renderBoard() {
gameContainer.innerHTML = '';
for (let x = 0; x < SIZE; x++) {
for (let y = 0; y < SIZE; y++) {
drawTile(x, y, board[x][y]);
}
}
if (isGameOver()) {
gameOverElement.style.display = 'block';
} else if (isGameWon()) {
gameWinElement.style.display = 'block';
}
}
function initGame() {
addRandomTile();
addRandomTile();
renderBoard();
document.addEventListener('keydown', handleKeyPress);
}
function addRandomTile() {
let emptyTiles = [];
for (let x = 0; x < SIZE; x++) {
for (let y = 0; y < SIZE; y++) {
if (board[x][y] === 0) {
emptyTiles.push({ x, y });
}
}
}
if (emptyTiles.length === 0) return;
const { x, y } = emptyTiles[Math.floor(Math.random() * emptyTiles.length)];
board[x][y] = Math.random() < 0.9 ? 2 : 4;
}
function slideTiles(direction) {
const oldBoard = JSON.stringify(board);
switch (direction) {
case 'up': slideUp(); break;
case 'down': slideDown(); break;
case 'left': slideLeft(); break;
case 'right': slideRight(); break;
}
if (JSON.stringify(board) !== oldBoard) {
addRandomTile();
renderBoard();
}
}
function slideUp() {
for (let col = 0; col < SIZE; col++) {
let values = [];
for (let row = 0; row < SIZE; row++) {
if (board[row][col] !== 0) {
values.push(board[row][col]);
}
}
values = mergeValues(values);
for (let row = 0; row < SIZE; row++) {
board[row][col] = values[row] || 0;
}
}
}
function slideDown() {
for (let col = 0; col < SIZE; col++) {
let values = [];
for (let row = SIZE - 1; row >= 0; row--) {
if (board[row][col] !== 0) {
values.push(board[row][col]);
}
}
values = mergeValues(values);
for (let row = SIZE - 1; row >= 0; row--) {
board[row][col] = values[SIZE - 1 - row] || 0;
}
}
}
function slideLeft() {
for (let row = 0; row < SIZE; row++) {
let values = [];
for (let col = 0; col < SIZE; col++) {
if (board[row][col] !== 0) {
values.push(board[row][col]);
}
}
values = mergeValues(values);
for (let col = 0; col < SIZE; col++) {
board[row][col] = values[col] || 0;
}
}
}
function slideRight() {
for (let row = 0; row < SIZE; row++) {
let values = [];
for (let col = SIZE - 1; col >= 0; col--) {
if (board[row][col] !== 0) {
values.push(board[row][col]);
}
}
values = mergeValues(values);
for (let col = SIZE - 1; col >= 0; col--) {
board[row][col] = values[SIZE - 1 - col] || 0;
}
}
}
function mergeValues(values) {
let merged = [];
for (let i = 0; i < values.length; i++) {
if (i < values.length - 1 && values[i] === values[i + 1]) {
merged.push(values[i] * 2);
i++;
} else {
merged.push(values[i]);
}
}
return merged;
}
function handleKeyPress(event) {
switch (event.key) {
case 'ArrowUp': slideTiles('up'); break;
case 'ArrowDown': slideTiles('down'); break;
case 'ArrowLeft': slideTiles('left'); break;
case 'ArrowRight': slideTiles('right'); break;
}
}
function isGameOver() {
for (let row = 0; row < SIZE; row++) {
for (let col = 0; col < SIZE; col++) {
if (board[row][col] === 0 ||
(row < SIZE - 1 && board[row][col] === board[row + 1][col]) ||
(col < SIZE - 1 && board[row][col] === board[row][col + 1])) {
return false;
}
}
}
return true;
}
function isGameWon() {
for (let row = 0; row < SIZE; row++) {
for (let col = 0; col < SIZE; col++) {
if (board[row][col] === 2048) {
return true;
}
}
}
return false;
}
initGame();
</script>
</body>
</html>