HTML实现的2048游戏

以下是一个纯HTML实现的2048游戏代码,包含CSS和JavaScript:

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>2048 Game</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            background-color: #faf8ef;
        }
        .container {
            width: 450px;
            margin: 0 auto;
        }
        .header {
            display: flex;
            justify-content: space-between;
            margin-bottom: 20px;
        }
        h1 {
            font-size: 80px;
            margin: 0;
            color: #776e65;
        }
        .score-container {
            background: #bbada0;
            padding: 15px 25px;
            border-radius: 6px;
            color: white;
            font-weight: bold;
            text-align: center;
        }
        .score-title {
            font-size: 13px;
            display: block;
        }
        .score-value {
            font-size: 25px;
        }
        .game-container {
            background: #bbada0;
            border-radius: 6px;
            width: 450px;
            height: 450px;
            padding: 15px;
            position: relative;
            margin: 0 auto;
        }
        .grid {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            grid-gap: 15px;
            width: 100%;
            height: 100%;
        }
        .cell {
            background: rgba(238, 228, 218, 0.35);
            border-radius: 3px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 45px;
            font-weight: bold;
            color: #776e65;
            position: relative;
        }
        .tile-2 {
            background: #eee4da;
        }
        .tile-4 {
            background: #ede0c8;
        }
        .tile-8 {
            background: #f2b179;
            color: white;
        }
        .tile-16 {
            background: #f59563;
            color: white;
        }
        .tile-32 {
            background: #f67c5f;
            color: white;
        }
        .tile-64 {
            background: #f65e3b;
            color: white;
        }
        .tile-128 {
            background: #edcf72;
            color: white;
            font-size: 40px;
        }
        .tile-256 {
            background: #edcc61;
            color: white;
            font-size: 40px;
        }
        .tile-512 {
            background: #edc850;
            color: white;
            font-size: 40px;
        }
        .tile-1024 {
            background: #edc53f;
            color: white;
            font-size: 35px;
        }
        .tile-2048 {
            background: #edc22e;
            color: white;
            font-size: 35px;
        }
        .game-message {
            display: none;
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(238, 228, 218, 0.73);
            z-index: 100;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            border-radius: 6px;
        }
        .game-message.game-won {
            background: rgba(237, 194, 46, 0.5);
            color: white;
        }
        .game-message.game-over {
            background: rgba(238, 228, 218, 0.73);
            color: #776e65;
        }
        .game-message p {
            font-size: 60px;
            font-weight: bold;
            margin: 0;
        }
        .game-message .lower {
            margin-top: 30px;
        }
        .game-message button {
            background: #8f7a66;
            color: white;
            border: none;
            border-radius: 3px;
            padding: 10px 20px;
            font-size: 18px;
            cursor: pointer;
        }
        .game-message button:hover {
            background: #9f8b77;
        }
        .instructions {
            margin-top: 30px;
            color: #776e65;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>2048</h1>
            <div class="score-container">
                <span class="score-title">SCORE</span>
                <span class="score-value" id="score">0</span>
            </div>
        </div>
        
        <div class="game-container">
            <div class="grid" id="grid"></div>
            <div class="game-message" id="game-message">
                <p id="message-text"></p>
                <div class="lower">
                    <button id="keep-going-button">Keep going</button>
                    <button id="retry-button">Try again</button>
                </div>
            </div>
        </div>
        
        <div class="instructions">
            <p>Join the numbers and get to the <strong>2048 tile!</strong></p>
            <p>Use <strong>arrow keys</strong> to move the tiles.</p>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const grid = document.getElementById('grid');
            const scoreDisplay = document.getElementById('score');
            const gameMessage = document.getElementById('game-message');
            const messageText = document.getElementById('message-text');
            const retryButton = document.getElementById('retry-button');
            const keepGoingButton = document.getElementById('keep-going-button');
            
            let board = [];
            let score = 0;
            let gameWon = false;
            
            // Initialize the game
            function initGame() {
                // Create empty board
                board = [
                    [0, 0, 0, 0],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0]
                ];
                
                score = 0;
                gameWon = false;
                updateScore();
                
                // Clear the grid
                grid.innerHTML = '';
                
                // Create cells
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        const cell = document.createElement('div');
                        cell.className = 'cell';
                        cell.id = `cell-${i}-${j}`;
                        grid.appendChild(cell);
                    }
                }
                
                // Hide game message
                gameMessage.style.display = 'none';
                
                // Add two initial tiles
                addRandomTile();
                addRandomTile();
                
                // Render the board
                renderBoard();
            }
            
            // Add a random tile (2 or 4) to an empty cell
            function addRandomTile() {
                const emptyCells = [];
                
                // Find all empty cells
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        if (board[i][j] === 0) {
                            emptyCells.push({row: i, col: j});
                        }
                    }
                }
                
                // If there are empty cells, add a new tile
                if (emptyCells.length > 0) {
                    const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
                    board[randomCell.row][randomCell.col] = Math.random() < 0.9 ? 2 : 4;
                    return true;
                }
                
                return false;
            }
            
            // Render the board
            function renderBoard() {
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        const cell = document.getElementById(`cell-${i}-${j}`);
                        const value = board[i][j];
                        
                        // Clear the cell
                        cell.className = 'cell';
                        cell.textContent = '';
                        
                        // If the cell has a value, add the appropriate class and content
                        if (value > 0) {
                            cell.textContent = value;
                            cell.classList.add(`tile-${value}`);
                        }
                    }
                }
            }
            
            // Update the score display
            function updateScore() {
                scoreDisplay.textContent = score;
            }
            
            // Check if the game is over
            function isGameOver() {
                // Check if there are any empty cells
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        if (board[i][j] === 0) {
                            return false;
                        }
                    }
                }
                
                // Check if any adjacent cells have the same value
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        if (j < 3 && board[i][j] === board[i][j + 1]) {
                            return false;
                        }
                        if (i < 3 && board[i][j] === board[i + 1][j]) {
                            return false;
                        }
                    }
                }
                
                return true;
            }
            
            // Check if the player has won (reached 2048)
            function checkWin() {
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        if (board[i][j] === 2048) {
                            return true;
                        }
                    }
                }
                return false;
            }
            
            // Show game message (win or lose)
            function showGameMessage(won) {
                if (won) {
                    messageText.textContent = 'You Win!';
                    gameMessage.classList.add('game-won');
                    gameMessage.classList.remove('game-over');
                    keepGoingButton.style.display = 'inline-block';
                } else {
                    messageText.textContent = 'Game Over!';
                    gameMessage.classList.add('game-over');
                    gameMessage.classList.remove('game-won');
                    keepGoingButton.style.display = 'none';
                }
                gameMessage.style.display = 'flex';
            }
            
            // Move tiles left
            function moveLeft() {
                let moved = false;
                
                for (let i = 0; i < 4; i++) {
                    // Remove zeros
                    let row = board[i].filter(val => val !== 0);
                    
                    // Merge adjacent equal values
                    for (let j = 0; j < row.length - 1; j++) {
                        if (row[j] === row[j + 1]) {
                            row[j] *= 2;
                            score += row[j];
                            row[j + 1] = 0;
                            moved = true;
                            if (row[j] === 2048) {
                                gameWon = true;
                            }
                        }
                    }
                    
                    // Remove zeros again after merging
                    row = row.filter(val => val !== 0);
                    
                    // Add zeros to the end
                    while (row.length < 4) {
                        row.push(0);
                    }
                    
                    // Check if the row has changed
                    if (JSON.stringify(board[i]) !== JSON.stringify(row)) {
                        moved = true;
                    }
                    
                    board[i] = row;
                }
                
                return moved;
            }
            
            // Move tiles right
            function moveRight() {
                let moved = false;
                
                for (let i = 0; i < 4; i++) {
                    // Remove zeros
                    let row = board[i].filter(val => val !== 0);
                    
                    // Merge adjacent equal values (from right)
                    for (let j = row.length - 1; j > 0; j--) {
                        if (row[j] === row[j - 1]) {
                            row[j] *= 2;
                            score += row[j];
                            row[j - 1] = 0;
                            moved = true;
                            if (row[j] === 2048) {
                                gameWon = true;
                            }
                        }
                    }
                    
                    // Remove zeros again after merging
                    row = row.filter(val => val !== 0);
                    
                    // Add zeros to the beginning
                    while (row.length < 4) {
                        row.unshift(0);
                    }
                    
                    // Check if the row has changed
                    if (JSON.stringify(board[i]) !== JSON.stringify(row)) {
                        moved = true;
                    }
                    
                    board[i] = row;
                }
                
                return moved;
            }
            
            // Move tiles up
            function moveUp() {
                let moved = false;
                
                for (let j = 0; j < 4; j++) {
                    // Get column
                    let column = [board[0][j], board[1][j], board[2][j], board[3][j]];
                    
                    // Remove zeros
                    column = column.filter(val => val !== 0);
                    
                    // Merge adjacent equal values
                    for (let i = 0; i < column.length - 1; i++) {
                        if (column[i] === column[i + 1]) {
                            column[i] *= 2;
                            score += column[i];
                            column[i + 1] = 0;
                            moved = true;
                            if (column[i] === 2048) {
                                gameWon = true;
                            }
                        }
                    }
                    
                    // Remove zeros again after merging
                    column = column.filter(val => val !== 0);
                    
                    // Add zeros to the end
                    while (column.length < 4) {
                        column.push(0);
                    }
                    
                    // Check if the column has changed
                    for (let i = 0; i < 4; i++) {
                        if (board[i][j] !== column[i]) {
                            moved = true;
                            board[i][j] = column[i];
                        }
                    }
                }
                
                return moved;
            }
            
            // Move tiles down
            function moveDown() {
                let moved = false;
                
                for (let j = 0; j < 4; j++) {
                    // Get column
                    let column = [board[0][j], board[1][j], board[2][j], board[3][j]];
                    
                    // Remove zeros
                    column = column.filter(val => val !== 0);
                    
                    // Merge adjacent equal values (from bottom)
                    for (let i = column.length - 1; i > 0; i--) {
                        if (column[i] === column[i - 1]) {
                            column[i] *= 2;
                            score += column[i];
                            column[i - 1] = 0;
                            moved = true;
                            if (column[i] === 2048) {
                                gameWon = true;
                            }
                        }
                    }
                    
                    // Remove zeros again after merging
                    column = column.filter(val => val !== 0);
                    
                    // Add zeros to the beginning
                    while (column.length < 4) {
                        column.unshift(0);
                    }
                    
                    // Check if the column has changed
                    for (let i = 0; i < 4; i++) {
                        if (board[i][j] !== column[i]) {
                            moved = true;
                            board[i][j] = column[i];
                        }
                    }
                }
                
                return moved;
            }
            
            // Handle keyboard events
            function handleKeyPress(event) {
                if (gameMessage.style.display === 'flex' && !gameWon) {
                    return;
                }
                
                let moved = false;
                
                switch (event.key) {
                    case 'ArrowLeft':
                        moved = moveLeft();
                        break;
                    case 'ArrowRight':
                        moved = moveRight();
                        break;
                    case 'ArrowUp':
                        moved = moveUp();
                        break;
                    case 'ArrowDown':
                        moved = moveDown();
                        break;
                    default:
                        return;
                }
                
                if (moved) {
                    addRandomTile();
                    renderBoard();
                    updateScore();
                    
                    if (gameWon) {
                        showGameMessage(true);
                    } else if (isGameOver()) {
                        showGameMessage(false);
                    }
                }
            }
            
            // Event listeners
            document.addEventListener('keydown', handleKeyPress);
            retryButton.addEventListener('click', initGame);
            keepGoingButton.addEventListener('click', () => {
                gameMessage.style.display = 'none';
                gameWon = false;
            });
            
            // Start the game
            initGame();
        });
    </script>
</body>
</html>

功能说明

这个2048游戏实现包含以下功能:

  • 4×4的游戏棋盘
  • 使用箭头键控制方块移动
  • 分数计算和显示
  • 游戏胜利检测(达到2048方块)
  • 游戏结束检测(无法移动)
  • 重新开始游戏选项
  • 达到2048后可以选择继续游戏
  • 响应式设计,适应不同屏幕

使用方法

  1. 将上述代码复制到一个HTML文件中
  2. 用浏览器打开该文件即可开始游戏
  3. 使用键盘方向键(↑↓←→)移动方块
  4. 相同数字的方块碰撞时会合并
  5. 目标是得到2048方块
相关推荐
老纪的技术唠嗑局37 分钟前
网易游戏DB SaaS引入OceanBase:存储成本降60%,备份恢复提速3倍
游戏
努力往上爬de蜗牛1 小时前
vue3 daterange正则踩坑
javascript·vue.js·elementui
3Katrina1 小时前
理解Promise:让异步编程更优雅
前端·javascript
星之金币1 小时前
关于我用Cursor优化了一篇文章:30 分钟学会定制属于你的编程语言
前端·javascript
每天都想着怎么摸鱼的前端菜鸟1 小时前
【uniapp】uni.chooseImage在Android 13以下机型第一次调用授权后无权限问题
javascript·uni-app
市民中心的蟋蟀1 小时前
第十一章 这三个全局状态管理库之间的共性与差异 【上】
前端·javascript·react.js
小宋10211 小时前
el-table的select回显问题
javascript·vue.js·elementui
豆豆(设计前端)1 小时前
在 JavaScript 中,你可以使用 Date 对象来获取 当前日期 和 当前时间、当前年份。
开发语言·javascript·ecmascript
DoraBigHead1 小时前
深入 JavaScript 作用域机制:透视 V8 引擎背后的执行秘密
前端·javascript
薛定谔的算法1 小时前
JavaScript闭包深度解析:从基础概念到柯里化实践
javascript