HTML2048小游戏

源代码在效果图后面

效果图

源代码

<!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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/842988.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

UDP客户端、服务端及简易聊天室实现 —— Java

UDP 协议&#xff08;用户数据包协议&#xff09; UDP 是无连接通信协议&#xff0c;即在数据传输时&#xff0c;数据的发送端和接收端不建立逻辑连接&#xff0c;简单来说&#xff0c;当客户端向接收端发送数据时&#xff0c;客户端不会确认接收端是否存在&#xff0c;就会发出…

使用llama-cpp-python制作api接口

文章目录 概要整体操作流程技术细节小结 概要 使用llama-cpp-python制作api接口&#xff0c;可以接入gradio当中&#xff0c;参考上一节。 llama-cpp-python的github网址 整体操作流程 下载llama-cpp-python。首先判断自己是在CPU的环境下还是GPU的环境下。以下操作均在魔搭…

鑫创SSS1700USB音频桥芯片USB转IIS芯片

鑫创SSS1700支持IIC初始外部编&#xff08;EEPROM选项),两线串行总线&#xff08;I2C总线&#xff09;用于外部MCU控制整个EEPROM空间可以通过MCU访问用于主机控制同步的USB HID外部串行EEPROM&#xff08;24C02~24C16&#xff09;接口&#xff0c;用于客户特定的USB视频、PID、…

【QT】定时器事件 - QTimerEvent QTimer

qt 系统 - 定时器 定时器1. QTimerEvent2. QTimer3. 获取系统日期及时间 定时器 Qt 中在进行窗口程序的处理过程中&#xff0c;经常要周期性的执⾏某些操作&#xff0c;或者制作⼀些动画效果&#xff0c;使用定时器就可以实现。所谓定时器就是在间隔⼀定时间后&#xff0c;去执…

TCP重传机制详解

1.什么是TCP重传机制 在 TCP 中&#xff0c;当发送端的数据到达接收主机时&#xff0c;接收端主机会返回⼀个确认应答消息&#xff0c;表示已收到消息。 但是如果传输的过程中&#xff0c;数据包丢失了&#xff0c;就会使⽤重传机制来解决。TCP的重传机制是为了保证数据传输的…

C语言编译报错:error: expected declaration or statement at end of input(缺了括号)

文章目录 报错信息分析解决步骤&#xff1a; 排查 报错信息 /userdata/testOtherPrj/20240715_box_circuit_breaker/test/external/modbus_vendorA/src/vendor_a_modbus.c: In function ‘VendorA_PowerStop’: /userdata/testOtherPrj/20240715_box_circuit_breaker/test/exte…

python3.10.4——CentOS7安装步骤

目录 1.CentOS7中默认有python2.7.5 2.安装前置依赖程序 3.在python官网下载linux系统安装包 4.解析、编译安装python3.10.4 5.创建软链接 6.修改yum相关配置 7.重新检查python版本号 1.CentOS7中默认有python2.7.5 2.安装前置依赖程序 yum install wget zlib-devel bz…

HarmonyOS应用开发者高级认证,Next版本发布后最新题库 - 单选题序号3

基础认证题库请移步&#xff1a;HarmonyOS应用开发者基础认证题库 注&#xff1a;有读者反馈&#xff0c;题库的代码块比较多&#xff0c;打开文章时会卡死。所以笔者将题库拆分&#xff0c;单选题20个为一组&#xff0c;多选题10个为一组&#xff0c;题库目录如下&#xff0c;…

给Wordpress添加评分功能到评论表单

今天要 给你的 Wordpress 添加评分功能到评论表单 吗&#xff1f; 评分功能效果图 什么类型的网站需要评分&#xff1f; 资源站教程站其他&#xff0c;我也没想到。。。 但我这个网站&#xff0c;因为是电影类的网站&#xff0c;好像还是有点需要的&#xff0c;所以&#xf…

使用C#手搓Word插件

WordTools主要功能介绍 编码语言&#xff1a;C#【VSTO】 1、选择 1.1、表格 作用&#xff1a;全选文档中的表格&#xff1b; 1.2、表头 作用&#xff1a;全选文档所有表格的表头【第一行】&#xff1b; 1.3、表正文 全选文档中所有表格的除表头部分【除第一行部分】 1.…

【大数据面试题】37 Doris 是怎么保证性能的?

一步一个脚印&#xff0c;一天一道大数据面试题 博主希望能够得到大家的点赞收藏支持&#xff01;非常感谢 点赞&#xff0c;收藏是情分&#xff0c;不点是本分。祝你身体健康&#xff0c;事事顺心&#xff01; Doris 是当下大热的 MPP 数据库&#xff0c;下面来聊聊它如何保证…

汽车电动空调系统

1.电动空调系统概述 电动汽车制冷空调系统与传统汽车制冷空调系统基本原理一样&#xff0c;区别在于电动汽车空调系统采用电动空调压缩机。电动空调压缩机由驱动电机&#xff0c;压缩机&#xff0c;控制器集成。 电动空调压缩机的驱动电机采用体积小&#xff0c;质量轻&#x…

oceanbase架构、功能模块、数据存储、特性、sql流转层等概念详解

一、架构图 OceanBase 数据库采用无共享&#xff08;Shared-Nothing&#xff09;分布式集群架构&#xff0c;各个节点之间完全对等&#xff0c;每个节点都有自己的 SQL 引擎、存储引擎、事务引擎&#xff0c;运行在普通 PC 服务器组成的集群之上&#xff0c;具备高可扩展性、高…

3、宠物商店智能合约实战(truffle智能合约项目实战)

3、宠物商店智能合约实战&#xff08;truffle智能合约项目实战&#xff09; 1-宠物商店环境搭建、运行2-webjs与宠物逻辑实现3-领养智能合约初始化4-宠物领养实现5-更新宠物领养状态 1-宠物商店环境搭建、运行 https://www.trufflesuite.com/boxes/pet-shop 这个还是不行 或者…

C语言:数组-学习笔记(万字笔记)——翻新版

目录 前言&#xff1a; 1、 数组的概念 1.1 什么是数组 1.2 为什么学习数组&#xff1f; 2. ⼀维数组的创建和初始化 2.1 数组创建 2.2 数组的初始化 2.3 数组的类型 2.3.1 什么是数组类型&#xff1f; 2.3.2 数组类型的作用 3、 一维数组的使用 3.1 数组下标 3.2 数…

收银系统源码-千呼新零售收银视频介绍

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

无需业务改造,一套数据库满足 OLTP 和 OLAP,GaiaDB 发布并行查询能力

在企业中通常存在两类数据处理场景&#xff0c;一类是在线事务处理场景&#xff08;OLTP&#xff09;&#xff0c;例如交易系统&#xff0c;另一类是在线分析处理场景&#xff08;OLAP&#xff09;&#xff0c;例如业务报表。 OLTP 数据库擅长处理数据的增、删、改&#xff0c…

【计算机网络】0 课程主要内容(自顶向下方法,中科大郑烇、杨坚)(待)

1 教学目标 掌握计算机网络 基本概念 工作原理 常用技术 为将来学习、应用和研究计算机网络打下坚实基础 2 课程主要内容 1 计算机网络和互联网2 应用层3 传输层4 网络层&#xff1a;数据平面5 网络层&#xff1a;控制平面6 数据链路层和局域网7 网络安全8 无线和移动网络9 多…

【python】Numpy运行报错详细分析:IndexError: too many indices for array

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

【Langchain大语言模型开发教程】基于文档问答

&#x1f517; LangChain for LLM Application Development - DeepLearning.AI Embedding&#xff1a; https://huggingface.co/BAAI/bge-large-en-v1.5/tree/main 学习目标 1、Embedding and Vector Store 2、RetrievalQA 引包、加载环境变量 import osfrom dotenv import…