游戏简介:
2048是一款简单而又上瘾的数字拼图游戏。游戏的目标是通过移动方块,合并相同数字的方块,最终达到数字2048。每一次移动都会在空白的方格中生成一个数字为2或4的方块,而移动方向可以选择上、下、左、右四个方向。游戏结束的条件是方格填满且无法继续移动,或者成功合成数字2048。2048的简单规则和挑战性的玩法吸引了众多玩家,让人沉迷其中。快来挑战自己的智力和策略,在有限的空间中创造最高的分数吧!
游戏界面:
运行效果:
源码:
<!DOCTYPE html>
<html>
<head>
<title>2048</title>
<style>
body {
text-align: center;
margin-top: 50px;
}
h1 {
font-size: 50px;
color: #776e65;
}
#gameContainer {
margin-top: 50px;
display: inline-block;
}
#score {
font-size: 24px;
margin-bottom: 10px;
color: #776e65;
}
#gridContainer {
width: 400px;
height: 400px;
border: 1px solid #bbada0;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 10px;
background-color: #faf8ef;
padding: 10px;
}
.tile {
display: flex;
justify-content: center;
align-items: center;
font-size: 36px;
font-weight: bold;
background-color: #eee4da;
border-radius: 6px;
color: #776e65;
}
#gameOverContainer {
display: none;
margin-top: 20px;
}
#gameOver {
font-size: 36px;
color: #776e65;
margin-bottom: 10px;
}
#restartButton {
font-size: 20px;
padding: 8px 20px;
border-radius: 6px;
background-color: #8f7a66;
color: #fff;
border: none;
cursor: pointer;
}
</style>
</head>
<body>
<h1>2048</h1>
<div id="gameContainer">
<div id="score">Score: 0</div>
<div id="gridContainer"></div>
<div id="gameOverContainer">
<div id="gameOver">Game Over!</div>
<button id="restartButton">Restart</button>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
const gridContainer = document.getElementById("gridContainer");
const scoreDisplay = document.getElementById("score");
const gameOverContainer = document.getElementById("gameOverContainer");
const gameOver = document.getElementById("gameOver");
const restartButton = document.getElementById("restartButton");
const width = 4;
let tiles = [];
let score = 0;
let gameOverFlag = false;
// 初始化游戏
function init() {
score = 0;
gameOverFlag = false;
updateScore();
gameOverContainer.style.display = "none";
restartButton.removeEventListener("click", restart);
while (gridContainer.firstChild) {
gridContainer.firstChild.remove();
}
tiles = new Array(width * width).fill(null);
addTile();
addTile();
drawTiles();
}
// 随机在空位置添加方块
function addTile() {
const emptyTiles = tiles.reduce((acc, tile, index) => {
if (tile === null) {
acc.push(index);
}
return acc;
}, []);
if (emptyTiles.length > 0) {
const randomIndex = emptyTiles[Math.floor(Math.random() * emptyTiles.length)];
const value = Math.random() < 0.9 ? 2 : 4;
tiles[randomIndex] = value;
}
}
// 绘制方块
function drawTiles() {
gridContainer.innerHTML = "";
tiles.forEach((tile, index) => {
const tileElement = document.createElement("div");
tileElement.classList.add("tile");
if (tile !== null) {
tileElement.textContent = tile;
tileElement.classList.add(`tile-${tile}`);
}
gridContainer.appendChild(tileElement);
});
}
// 更新得分
function updateScore() {
scoreDisplay.textContent = `Score: ${score}`;
}
// 移动方块
function move(direction) {
if (gameOverFlag) return;
let hasChanged = false;
switch (direction) {
case "up":
for (let col = 0; col < width; col++) {
for (let row = 1; row < width; row++) {
let currentIndex = col + row * width;
if (tiles[currentIndex] !== null) {
let newIndex = currentIndex;
while (newIndex >= width && tiles[newIndex - width] === null) {
newIndex -= width;
}
if (newIndex - width >= 0 && tiles[newIndex - width] === tiles[currentIndex]) {
tiles[newIndex - width] *= 2;
tiles[currentIndex] = null;
score += tiles[newIndex - width];
hasChanged = true;
} else if (newIndex !== currentIndex) {
tiles[newIndex] = tiles[currentIndex];
tiles[currentIndex] = null;
hasChanged = true;
}
}
}
}
break;
case "down":
for (let col = 0; col < width; col++) {
for (let row = width - 2; row >= 0; row--) {
let currentIndex = col + row * width;
if (tiles[currentIndex] !== null) {
let newIndex = currentIndex;
while (newIndex + width < width * width && tiles[newIndex + width] === null) {
newIndex += width;
}
if (newIndex + width < width * width && tiles[newIndex + width] === tiles[currentIndex]) {
tiles[newIndex + width] *= 2;
tiles[currentIndex] = null;
score += tiles[newIndex + width];
hasChanged = true;
} else if (newIndex !== currentIndex) {
tiles[newIndex] = tiles[currentIndex];
tiles[currentIndex] = null;
hasChanged = true;
}
}
}
}
break;
case "left":
for (let row = 0; row < width; row++) {
for (let col = 1; col < width; col++) {
let currentIndex = row * width + col;
if (tiles[currentIndex] !== null) {
let newIndex = currentIndex;
while (newIndex % width !== 0 && tiles[newIndex - 1] === null) {
newIndex--;
}
if (newIndex % width !== 0 && tiles[newIndex - 1] === tiles[currentIndex]) {
tiles[newIndex - 1] *= 2;
tiles[currentIndex] = null;
score += tiles[newIndex - 1];
hasChanged = true;
} else if (newIndex !== currentIndex) {
tiles[newIndex] = tiles[currentIndex];
tiles[currentIndex] = null;
hasChanged = true;
}
}
}
}
break;
case "right":
for (let row = 0; row < width; row++) {
for (let col = width - 2; col >= 0; col--) {
let currentIndex = row * width + col;
if (tiles[currentIndex] !== null) {
let newIndex = currentIndex;
while ((newIndex + 1) % width !== 0 && tiles[newIndex + 1] === null) {
newIndex++;
}
if ((newIndex + 1) % width !== 0 && tiles[newIndex + 1] === tiles[currentIndex]) {
tiles[newIndex + 1] *= 2;
tiles[currentIndex] = null;
score += tiles[newIndex + 1];
hasChanged = true;
} else if (newIndex !== currentIndex) {
tiles[newIndex] = tiles[currentIndex];
tiles[currentIndex] = null;
hasChanged = true;
}
}
}
}
break;
}
if (hasChanged) {
addTile();
drawTiles();
updateScore();
checkGameOver();
}
}
// 检查游戏是否结束
function checkGameOver() {
const isFull = !tiles.includes(null);
const canMove = checkMove();
if (isFull && !canMove) {
gameOverFlag = true;
gameOverContainer.style.display = "block";
restartButton.addEventListener("click", restart);
}
}
// 检查是否能够移动
function checkMove() {
for (let i = 0; i < tiles.length; i++) {
if (tiles[i] === null) {
return true;
}
if (i % width !== width - 1 && tiles[i] === tiles[i + 1]) {
return true;
}
if (i < tiles.length - width && tiles[i] === tiles[i + width]) {
return true;
}
}
return false;
}
// 重新开始游戏
function restart() {
init();
}
// 添加键盘按键监听事件
document.addEventListener("keydown", function (event) {
if (event.key === "ArrowUp" || event.key === "w") {
move("up");
} else if (event.key === "ArrowDown" || event.key === "s") {
move("down");
} else if (event.key === "ArrowLeft" || event.key === "a") {
move("left");
} else if (event.key === "ArrowRight" || event.key === "d") {
move("right");
}
});
// 初始化游戏
init();
});
</script>
</body>
</html>