HTML2048小游戏

news2024/9/21 4:39:14
源代码在效果图后面

效果图

源代码

<!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.coloradmin.cn/o/1930779.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt Creator的好用的功能

&#xff08;1&#xff09;ctrlf&#xff1a; 在当前文档进行查询操作 &#xff08;2&#xff09;f3: 找到后&#xff0c;按f3&#xff0c;查找下一个 &#xff08;3&#xff09;shiftf3: 查找上一个 右键菜单&#xff1a; (4)f4&#xff1a;在…

【海外云手机】静态住宅IP集成解决方案

航海大背景下&#xff0c;企业和个人用户对于网络隐私、稳定性以及跨国业务的需求日益增加。静态住宅IP与海外云手机的结合&#xff0c;提供了一种创新的集成解决方案&#xff0c;能够有效应对这些需求。 本篇文章分为三个部分&#xff1b;静态住宅优势、云手机优势、集成解决…

FPGA资源容量

Kintex™ 7 https://www.amd.com/zh-tw/products/adaptive-socs-and-fpgas/fpga/kintex-7.html#product-table AMD Zynq™ 7000 SoC https://www.amd.com/en/products/adaptive-socs-and-fpgas/soc/zynq-7000.html#product-table AMD Zynq™ UltraScale™ RFSoC 第一代 AMD Z…

对象存储解决方案:高性能分布式对象存储系统MinIO

文章目录 引言I 自动化数据管理界面1.1 图形用户界面:GUI1.2 命令行界面:MinIO CLI1.3 应用程序编程接口:MinIO APIII 部署集成2.1 静态端口分配2.2 将NGINX用作反向代理,配置负载。III 基础概念3.1 为什么是对象存储?3.2 MinIO支持哪些系统拓扑结构?3.3 时间同步3.4 存储…

react学习——28react-redux实现多组件共享数据(精简版)

1、目录结构 2、containers/Count/index.js import {createIncrementAction, createDecrementAction, createIncrementAsyncAction} from ../../redux/action/count //引入conect用于链接UI组件与redux import {connect} from react-redux import React, {Component} from &qu…

UML面向对象分析与设计

UML不是OOA/D&#xff0c;也不是方法&#xff0c;它仅仅只是一种图形表示法如果不掌握对象思想&#xff0c;那么UML或任何case工具(如ROSE)将毫无意义 我们需要一种用于〇OA/D的语言&#xff0c;这既是一种思考的工具&#xff0c;也是一种沟通的形式。因此&#xff0c;我们将在…

Python | Leetcode Python题解之第240题搜索二维矩阵II

题目&#xff1a; 题解&#xff1a; class Solution:def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:m, n len(matrix), len(matrix[0])x, y 0, n - 1while x < m and y > 0:if matrix[x][y] target:return Trueif matrix[x][y] > tar…

前端基础之JavaScript学习——变量、数据类型、类型转换

大家好&#xff0c;我是来自CSDN的博主PleaSure乐事&#xff0c;今天我们开始有关JS的学习&#xff0c;希望有所帮助并巩固有关前端的知识。 我使用的编译器为vscode&#xff0c;浏览器使用为谷歌浏览器&#xff0c;使用webstorm或其他环境效果几乎一样&#xff0c;使用系统自…

搞清c++中的队列(queue)以及双端队列(deque),以及常用的接口!

1. 队列 概念&#xff1a;Queue是一种先进先出(First In First Out,FIFO)的数据结构&#xff0c;它有两个出口 特征&#xff1a; 队列容器允许从一端新增元素&#xff0c;从另一端移除元素 队列中只有队头和队尾才可以被外界使用&#xff0c;因此队列不允许有遍历行为 队列…

【React Hooks原理 - forwardRef、useImperativeHandle】

概述 上文我们聊了useRef的使用和实现&#xff0c;主要两个用途&#xff1a;1、用于持久化保存 2、用于绑定dom。 但是有时候我们需要在父组件中访问子组件的dom或者属性/方法&#xff0c;而React中默认是不允许父组件直接访问子组件的dom的&#xff0c;这时候就可以通过forwa…

进程通信(3): System V IPC

System IPC包括System V消息队列&#xff0c;System V信号量&#xff0c;System V共享内存区。 System V IPC使用一个key&#xff08;key_t&#xff09;作为他们名字&#xff0c;这个值由ftok函数通过路径名和一个id生成。 客户和服务器通过在路径名和id达成一致&#xff0c;双…

解决网页中的 video 标签在移动端浏览器(如百度访问网页)视频脱离文档流播放问题

问题现象 部分浏览器视频脱离文档流&#xff0c;滚动时&#xff0c;视频是悬浮出来&#xff0c;在顶部播放 解决方案 添加下列属性&#xff0c;可解决大部分浏览器的脱离文档流的问题 <videowebkit-playsinline""playsInlinex5-playsinlinet7-video-player-t…

pico+unity3d开启彩色透视

1、点击游戏对象、点击XR、点击添加XR Origin&#xff0c;并把自带的摄像对象删除 2、添加脚本 using System.Collections; using System.Collections.Generic; using UnityEngine; using Unity.XR.PXR;//引入xr对象 public class toushi : MonoBehaviour {// Start is called…

Python项目部署到Linux生产环境(uwsgi+python+flask+nginx服务器)

1.安装python 我这里是3.9.5版本 安装依赖&#xff1a; yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make -y 根据自己的需要下载对应的python版本&#xff1a; cd local wget https://www.python.org/ftp…

ELK日志管理

目录 一.ELK简介 1.Elasticsearch 2.Logstash 4.ELK 组件解决的主要问题 5.ELK应用的好处 6.ELK的工作原理 7.ELK的主要应用场景 二.安装部署ELK 1.前期准备 2.安装部署ElasticseaErch 软件 3. 在apache节点上 部署 Logstash 4.安装 kibana 三.实现nginx日志管理 …

modbus slave 设备通过 网关thingsboard-gateway 将数据上传到thingsboard云平台

搭建thingsboard物联网云平台花了大量时间&#xff0c;从小白到最后搭建成功&#xff0c;折磨了好几天&#xff0c;也感谢网友的帮助&#xff0c;提供了思路最终成功搞定&#xff0c;特此记录。 一、thingsboard环境搭建&#xff08;Ubuntu20.04LTS&#xff09; 参考官方文档&a…

景区导航导览系统:基于AR技术+VR技术的功能效益全面解析

在数字化时代背景下&#xff0c;游客对旅游体验的期望不断提升。游客们更倾向于使用手机作为旅行的贴身助手&#xff0c;不仅因为它能提供实时、精准的导航服务&#xff0c;更在于其融合AR&#xff08;增强现实&#xff09;、VR&#xff08;虚拟现实&#xff09;等前沿技术&…

Template execution failed: ReferenceError: name is not defined

问题 我们使用了html-webpack-plugin&#xff08;webpack&#xff09;进行编译html&#xff0c;导致的错误。 排查结果 连接地址 html-webpack-plugin版本低(2.30.1)&#xff0c;html模板里面不能有符号&#xff0c;注释都不行 // var reg new RegExp((^|&)${name}([^&…

【ROS2】高级:使用 Fast DDS 发现服务器作为发现协议 [社区贡献]

目标&#xff1a;本教程将展示如何使用 Fast DDS Discovery Server 发现协议启动 ROS 2 节点。 教程级别&#xff1a;高级 时间&#xff1a;20 分钟 目录 背景 快速 DDS 发现服务器 v2 先决条件 运行此教程 设置发现服务器 启动监听节点 启动对话节点展示发现服务器执行 可视化…

【15】Android基础知识之Window(一)

概述 这篇文章纠结了很久&#xff0c;在想需要怎么写&#xff1f;因为window有关的篇幅&#xff0c;如果需要讲起来那可太多了。从层级&#xff0c;或是从关联&#xff0c;总之不是很好开口。这次也下定决心&#xff0c;决定从浅入深的讲讲window这个东西。 Window Window是…