创建一个2048游戏的最小完整实现需要HTML、CSS和JavaScript。以下是一个简单的实现,你可以将这些代码复制到本地文件中,比如命名为2048.html,然后用浏览器打开这个文件来玩游戏。
<html>
<head>
<title>2048 Game</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.container {
width: 480px;
position: relative;
}
.grid-container {
display: grid;
grid-template-columns: repeat(4, 100px);
grid-gap: 15px;
background-color: #bbada0;
padding: 15px;
border-radius: 10px;
position: relative;
}
.tile {
width: 100px;
height: 100px;
background: #cdc1b4;
border-radius: 3px;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
font-weight: bold;
color: #776e65;
}
.tile-2 {
background: #eee4da;
}
.tile-4 {
background: #ede0c8;
}
.tile-8 {
background: #f2b179;
color: #f9f6f2;
}
/* Additional tile styles for 16, 32, 64, etc. go here */
.game-message {
width: 500px;
text-align: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: none;
}
.game-message p {
font-size: 36px;
font-weight: bold;
color: #776e65;
}
.game-message .button {
background: #8f7a66;
color: #f9f6f2;
border: none;
padding: 10px 20px;
font-size: 18px;
cursor: pointer;
margin-top: 20px;
}
.game-message a {
color: inherit;
text-decoration: none;
}
</style>
</head>
<body>
<div class="container">
<div class="grid-container" id="grid-container">
<!-- Tiles will be generated here -->
</div>
<div class="game-message" id="game-message">
<p>Game Over!</p>
<button class="button" onclick="setup()">Try again</button>
</div>
</div>
<script>
// Logic for the 2048 game
var grid, score, gameOver;
function setup() {
grid = [[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]];
score = 0;
gameOver = false;
addNumber();
addNumber();
updateView();
document.getElementById('game-message').style.display = 'none';
}
function addNumber() {
var options = [];
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
if (grid[i][j] === 0) {
options.push({
x: i,
y: j
});
}
}
}
if (options.length > 0) {
var spot = options[Math.floor(Math.random() * options.length)];
var randomNumber = Math.random() > 0.5 ? 2 : 4;
grid[spot.x][spot.y] = randomNumber;
}
}
function updateView() {
var container = document.getElementById('grid-container');
container.innerHTML = '';
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
var tile = document.createElement('div');
tile.classList.add('tile');
var value = grid[i][j];
if (value > 0) {
tile.textContent = value;
tile.classList.add('tile-' + value);
}
container.appendChild(tile);
}
}
}
function copyGrid(grid) {
var extra = [[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]];
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
extra[i][j] = grid[i][j];
}
}
return extra;
}
function compare(a, b) {
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
if (a[i][j] !== b[i][j]) {
return true;
}
}
}
return false;
}
function slide(row) {
var arr = row.filter(val => val);
var missing = 4 - arr.length;
var zeros = Array(missing).fill(0);
arr = zeros.concat(arr);
return arr;
}
function combine(row) {
for (var i = 3; i >= 1; i--) {
var a = row[i];
var b = row[i - 1];
if (a == b) {
row[i] = a + b;
score += row[i];
row[i - 1] = 0;
}
}
return row;
}
function operate(row) {
row = slide(row);
row = combine(row);
row = slide(row);
return row;
}
function flipGrid(grid) {
for (var i = 0; i < 4; i++) {
grid[i].reverse();
}
return grid;
}
function rotateGrid(grid) {
var newGrid = [[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]];
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
newGrid[i][j] = grid[j][i];
}
}
return newGrid;
}
function isGameOver() {
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
if (grid[i][j] == 0) {
return false;
}
if (j !== 3 && grid[i][j] === grid[i][j + 1]) {
return false;
}
if (i !== 3 && grid[i][j] === grid[i + 1][j]) {
return false;
}
}
}
return true;
}
function checkGameOver() {
if (isGameOver()) {
document.getElementById('game-message').style.display = 'block';
gameOver = true;
}
}
function keyPressed(event) {
if (gameOver) {
return;
}
var flipped = false;
var rotated = false;
var played = true;
switch(event.keyCode) {
case 39: // Right
// No action needed
break;
case 40: // Down
grid = rotateGrid(grid);
rotated = true;
break;
case 37: // Left
grid = flipGrid(grid);
flipped = true;
break;
case 38: // Up
grid = rotateGrid(grid);
rotated = true;
flipped = true;
break;
default:
played = false;
}
if (played) {
var past = copyGrid(grid);
for (var i = 0; i < 4; i++) {
grid[i] = operate(grid[i]);
}
var changed = compare(past, grid);
if (flipped) {
grid = flipGrid(grid);
}
if (rotated) {
grid = rotateGrid(grid);
grid = rotateGrid(grid);
grid = rotateGrid(grid);
}
if (changed) {
addNumber();
}
updateView();
checkGameOver();
}
}
document.addEventListener('keydown', keyPressed);
// Variables to track touch start positions
var touchStartX = null;
var touchStartY = null;
// Event listener for touch start
document.addEventListener('touchstart', function(event) {
if (event.touches.length > 1) return; // Only single touch events
touchStartX = event.touches[0].clientX;
touchStartY = event.touches[0].clientY;
event.preventDefault(); // Prevent scrolling when inside DIV
}, { passive: false });
// Event listener for touch move
document.addEventListener('touchmove', function(event) {
event.preventDefault(); // Prevent scrolling when inside DIV
}, { passive: false });
// Event listener for touch end
document.addEventListener('touchend', function(event) {
if (!touchStartX || !touchStartY || gameOver) return;
var deltaX = event.changedTouches[0].clientX - touchStartX;
var deltaY = event.changedTouches[0].clientY - touchStartY;
// Determine swipe direction
if (Math.abs(deltaX) > Math.abs(deltaY)) { // Horizontal swipe
if (deltaX > 0) {
moveRight();
} else {
moveLeft();
}
} else { // Vertical swipe
if (deltaY > 0) {
moveDown();
} else {
moveUp();
}
}
touchStartX = null;
touchStartY = null;
});
// Move functions
function moveLeft() { keyPressed({ keyCode: 37 }); }
function moveUp() { keyPressed({ keyCode: 38 }); }
function moveRight() { keyPressed({ keyCode: 39 }); }
function moveDown() { keyPressed({ keyCode: 40 }); }
setup();
</script>
</body>
</html>
效果图: