HTML2048小游戏

news/2024/8/30 20:48:45 标签: html, css, 前端, javascript, css3
htmledit_views">
源代码在效果图后面

效果图

源代码

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>


http://www.niftyadmin.cn/n/5561034.html

相关文章

STM32使用CubeMX创建HAL库工程文件

文章目录 1. STM32CubeMX 2. 界面介绍 3. 使用教程 新建工程 选择芯片界面 ​编辑 配置页面 引脚配置页面 引脚配置界面的颜色指示 配置RCC时钟参数 配置SYS参数 配置时钟树 Project Manager项目管理配置 生成工程文件 KEIL代码编写 1. STM32CubeMX STM32CubeM…

【JavaScript 算法】树的遍历:前序、中序与后序

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、前序遍历&#xff08;Preorder Traversal&#xff09;前序遍历的步骤前序遍历的JavaScript实现 二、中序遍历&#xff08;Inorder Traversal&#xff09;中序遍历的步骤中序遍历的JavaScript实现 三、后序遍历&#xff…

【时时三省】单元测试 简介

目录 1,单元测试简介 2,单元测试的目的 3,单元测试检查范围 4,单元测试用例设计方法 5,单元测试判断通过标准 6,测试范围 7,测试频率 8,输出成果 经验建议: 山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 1,单元测试简介 单元测试在以V模型…

时间轮算法理解、Kafka实现

概述 TimingWheel&#xff0c;时间轮&#xff0c;简单理解就是一种用来存储若干个定时任务的环状队列&#xff08;或数组&#xff09;&#xff0c;工作原理和钟表的表盘类似。 关于环形队列&#xff0c;请参考环形队列。 时间轮由两个部分组成&#xff0c;一个环状数组&…

电脑系统重装数据被格式化,那些文件还有办法恢复吗?

在日常使用电脑的过程中&#xff0c;系统重装或格式化操作是常见的维护手段&#xff0c;尤其是在遇到系统崩溃、病毒感染或需要升级系统时。然而&#xff0c;这一操作往往伴随着数据丢失的风险&#xff0c;尤其是当C盘&#xff08;系统盘&#xff09;和D盘&#xff08;或其他数…

Linux C++ realpath函数crash的解决方法

现象 调用realpath函数进程崩溃&#xff0c;可使用如下代码复现&#xff1a; //test.cpp #include "stdio.h" #include "stdlib.h" #include <limits.h>int main() {char *pnew char[300];realpath("1.txt",p);printf("%s\n",…

<数据集>绝缘子缺陷检测数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2139张 标注数量(xml文件个数)&#xff1a;2139 标注数量(txt文件个数)&#xff1a;2139 标注类别数&#xff1a;8 标注类别名称&#xff1a;[insulator, broken disc, pollution-flashover, Two glass, Glassdirt…

转型Web3开发第二课:Dapp开发入门基础 | 01 | 安装MetaMask

前言 完成了《转型 Web3 开发第一课》之后&#xff0c;得到了不少读者的认可&#xff0c;很多都在问什么时候开始下一课&#xff0c;近期终于抽出了时间开始搞起这第二课。 这第二课的主题为「Dapp开发入门基础」&#xff0c;即想要转型做 Dapp 开发的人员&#xff0c;不管是…