HTML2048小游戏

源代码在效果图后面

效果图

源代码

html 复制代码
<!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>
相关推荐
周亚鑫5 分钟前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
落魄小二14 分钟前
el-table 表格索引不展示问题
javascript·vue.js·elementui
y52364815 分钟前
Javascript监控元素样式变化
开发语言·javascript·ecmascript
Justinc.22 分钟前
CSS3新增边框属性(五)
前端·css·css3
fruge29 分钟前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
neter.asia38 分钟前
vue中如何关闭eslint检测?
前端·javascript·vue.js
~甲壳虫38 分钟前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
嚣张农民1 小时前
JavaScript中Promise分别有哪些函数?
前端·javascript·面试
光影少年1 小时前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_1 小时前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习