“2048”游戏网页版html+css+js

“2048”游戏网页版html+css+js

 别忘了请点个赞+收藏+关注支持一下博主喵!!!

   2048 游戏是一个非常流行的数字拼图游戏,玩家通过移动方块使相同数字的方块合并,最终达到 2048 或更高分数。本教程将详细介绍如何使用 HTML、CSS 和 JavaScript 创建一个简单的 2048 游戏网页。

  项目结构如下:(懒得搭vue了)

2048-game/
├── index.html
├── styles.css
└── script.js

1. index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"> <!-- 设置文档的字符编码为 UTF-8 --><meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 使页面在移动设备上适配屏幕宽度 --><title>2048 Game</title> <!-- 页面标题 --><link rel="stylesheet" href="styles.css"> <!-- 引入外部 CSS 文件 -->
</head>
<body><div class="game-container"> <!-- 游戏容器,用于包裹整个游戏界面 --><div class="score-container">0</div> <!-- 分数显示区域 --><div class="grid-container"> <!-- 网格容器,用于包裹 4x4 的游戏网格 --><div class="grid-row"> <!-- 每一行的网格 --><div class="grid-cell"></div> <!-- 每一个网格单元 --><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div><div class="grid-row"><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div><div class="grid-row"><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div><div class="grid-row"><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div></div><button id="restart-button">Restart</button> <!-- 重新开始按钮 --></div><script src="script.js"></script> <!-- 引入外部 JavaScript 文件 -->
</body>
</html>

2. styles.css

body {display: flex; /* 使用 Flexbox 布局 */justify-content: center; /* 水平居中 */align-items: center; /* 垂直居中 */height: 100vh; /* 占满整个视窗高度 */margin: 0; /* 移除默认外边距 */background-color: #faf8ef; /* 背景颜色 */font-family: Arial, sans-serif; /* 字体设置 */
}.game-container {width: 500px; /* 容器宽度 */height: 500px; /* 容器高度 */position: relative; /* 相对定位 */background-color: #bbada0; /* 背景颜色 */border-radius: 10px; /* 圆角 */box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3); /* 阴影效果 */
}.score-container {position: absolute; /* 绝对定位 */top: 10px; /* 距离顶部 10px */left: 10px; /* 距离左边 10px */background-color: #eee4da; /* 背景颜色 */padding: 10px; /* 内边距 */border-radius: 5px; /* 圆角 */font-size: 24px; /* 字体大小 */font-weight: bold; /* 加粗字体 */
}.grid-container {width: 400px; /* 网格容器宽度 */height: 400px; /* 网格容器高度 */position: absolute; /* 绝对定位 */top: 50%; /* 距离顶部 50% */left: 50%; /* 距离左边 50% */transform: translate(-50%, -50%); /* 居中对齐 */display: grid; /* 使用 Grid 布局 */grid-template-columns: repeat(4, 100px); /* 4 列,每列 100px */grid-template-rows: repeat(4, 100px); /* 4 行,每行 100px */gap: 10px; /* 网格间距 */
}.grid-cell {background-color: #cdc1b4; /* 背景颜色 */border-radius: 3px; /* 圆角 */display: flex; /* 使用 Flexbox 布局 */justify-content: center; /* 水平居中 */align-items: center; /* 垂直居中 */font-size: 32px; /* 字体大小 */font-weight: bold; /* 加粗字体 */color: #776e65; /* 文字颜色 */
}/* 不同数字的方块样式 */
.grid-cell.number-2 { background-color: #eee4da; color: #776e65; }
.grid-cell.number-4 { background-color: #ede0c8; color: #776e65; }
.grid-cell.number-8 { background-color: #f2b179; color: #f9f6f2; }
.grid-cell.number-16 { background-color: #f59563; color: #f9f6f2; }
.grid-cell.number-32 { background-color: #f67c5f; color: #f9f6f2; }
.grid-cell.number-64 { background-color: #f65e3b; color: #f9f6f2; }
.grid-cell.number-128 { background-color: #edcf72; color: #f9f6f2; }
.grid-cell.number-256 { background-color: #edcc61; color: #f9f6f2; }
.grid-cell.number-512 { background-color: #edc850; color: #f9f6f2; }
.grid-cell.number-1024 { background-color: #edc53f; color: #f9f6f2; }
.grid-cell.number-2048 { background-color: #edc22e; color: #f9f6f2; }#restart-button {position: absolute; /* 绝对定位 */bottom: 10px; /* 距离底部 10px */left: 50%; /* 距离左边 50% */transform: translateX(-50%); /* 水平居中 */padding: 10px 20px; /* 内边距 */background-color: #8f7a66; /* 背景颜色 */color: #f9f6f2; /* 文字颜色 */border: none; /* 无边框 */border-radius: 5px; /* 圆角 */cursor: pointer; /* 鼠标指针样式 */font-size: 18px; /* 字体大小 */font-weight: bold; /* 加粗字体 */
}#restart-button:hover {background-color: #746655; /* 鼠标悬停时的背景颜色 */
}

3. 最难的script.js

const grid = document.querySelector('.grid-container'); // 获取网格容器
const cells = document.querySelectorAll('.grid-cell'); // 获取所有网格单元
const scoreContainer = document.querySelector('.score-container'); // 获取分数显示区域
const restartButton = document.getElementById('restart-button'); // 获取重新开始按钮let score = 0; // 初始化分数
let hasWon = false; // 标记是否已经赢得游戏const matrix = [[0, 0, 0, 0], // 初始化 4x4 的矩阵[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]
];const winNumber = 2048; // 赢得游戏的目标数字// 获取一个随机的空格子
function getRandomEmptyCell() {const emptyCells = []; // 存储所有空格子的坐标for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (matrix[i][j] === 0) { // 如果格子为空emptyCells.push({ row: i, col: j }); // 将坐标加入空格子列表}}}if (emptyCells.length > 0) { // 如果有空格子const randomIndex = Math.floor(Math.random() * emptyCells.length); // 随机选择一个空格子return emptyCells[randomIndex];}return null; // 没有空格子返回 null
}// 在随机选择的空格子中添加一个新方块(2 或 4)
function addRandomTile() {const cell = getRandomEmptyCell();if (cell) {const value = Math.random() < 0.9 ? 2 : 4; // 90% 的概率生成 2,10% 的概率生成 4matrix[cell.row][cell.col] = value; // 更新矩阵updateGrid(); // 更新网格显示}
}// 更新 HTML 网格中的方块显示
function updateGrid() {cells.forEach((cell, index) => {const row = Math.floor(index / 4); // 计算当前单元格所在的行const col = index % 4; // 计算当前单元格所在的列const value = matrix[row][col]; // 获取矩阵中的值cell.textContent = value || ''; // 显示值,如果没有值则显示空字符串cell.classList.remove('number-2', 'number-4', 'number-8', 'number-16', 'number-32', 'number-64', 'number-128', 'number-256', 'number-512', 'number-1024', 'number-2048'); // 移除所有样式类if (value !== 0) { // 如果有值,添加对应的样式类cell.classList.add(`number-${value}`);}});
}// 向上移动
function moveUp() {for (let col = 0; col < 4; col++) { // 遍历每一列let tempCol = []; // 临时存储非零值for (let row = 0; row < 4; row++) {if (matrix[row][col] !== 0) {tempCol.push(matrix[row][col]); // 将非零值加入临时列表}}tempCol = mergeTiles(tempCol); // 合并相同的值for (let row = 0; row < 4; row++) {matrix[row][col] = tempCol[row] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 向下移动
function moveDown() {for (let col = 0; col < 4; col++) { // 遍历每一列let tempCol = []; // 临时存储非零值for (let row = 3; row >= 0; row--) {if (matrix[row][col] !== 0) {tempCol.push(matrix[row][col]); // 将非零值加入临时列表}}tempCol = mergeTiles(tempCol); // 合并相同的值for (let row = 3; row >= 0; row--) {matrix[row][col] = tempCol[3 - row] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 向左移动
function moveLeft() {for (let row = 0; row < 4; row++) { // 遍历每一行let tempRow = []; // 临时存储非零值for (let col = 0; col < 4; col++) {if (matrix[row][col] !== 0) {tempRow.push(matrix[row][col]); // 将非零值加入临时列表}}tempRow = mergeTiles(tempRow); // 合并相同的值for (let col = 0; col < 4; col++) {matrix[row][col] = tempRow[col] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 向右移动
function moveRight() {for (let row = 0; row < 4; row++) { // 遍历每一行let tempRow = []; // 临时存储非零值for (let col = 3; col >= 0; col--) {if (matrix[row][col] !== 0) {tempRow.push(matrix[row][col]); // 将非零值加入临时列表}}tempRow = mergeTiles(tempRow); // 合并相同的值for (let col = 3; col >= 0; col--) {matrix[row][col] = tempRow[3 - col] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 合并相同的值
function mergeTiles(tiles) {for (let i = 0; i < tiles.length - 1; i++) {if (tiles[i] === tiles[i + 1]) { // 如果相邻的两个值相同tiles[i] *= 2; // 合并值tiles.splice(i + 1, 1); // 删除合并后的值score += tiles[i]; // 更新分数scoreContainer.textContent = score; // 更新分数显示if (tiles[i] === winNumber && !hasWon) { // 如果达到目标值且未赢过alert('You Win!'); // 提示胜利hasWon = true; // 标记已赢}}}while (tiles.length < 4) { // 确保列表长度为 4tiles.push(0);}return tiles;
}// 检查游戏是否结束
function checkGameOver() {let gameOver = true; // 默认游戏结束for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (matrix[i][j] === 0 || // 如果有空格子(i < 3 && matrix[i][j] === matrix[i + 1][j]) || // 或者有相邻的相同值(j < 3 && matrix[i][j] === matrix[i][j + 1])) {gameOver = false; // 游戏未结束break;}}if (!gameOver) break;}if (gameOver) {alert('Game Over!'); // 提示游戏结束}
}// 重新开始游戏
function restartGame() {matrix.forEach(row => row.fill(0)); // 重置矩阵score = 0; // 重置分数hasWon = false; // 重置胜利标记scoreContainer.textContent = score; // 更新分数显示addRandomTile(); // 添加初始方块addRandomTile(); // 添加初始方块updateGrid(); // 更新网格显示
}// 监听键盘事件
document.addEventListener('keydown', (event) => {switch (event.key) {case 'ArrowUp': // 上箭头moveUp();break;case 'ArrowDown': // 下箭头moveDown();break;case 'ArrowLeft': // 左箭头moveLeft();break;case 'ArrowRight': // 右箭头moveRight();break;}
});// 监听重新开始按钮点击事件
restartButton.addEventListener('click', restartGame);// 初始化游戏
restartGame();

 别忘了请点个赞+收藏+关注支持一下博主喵!!!

累了,水一下吧。。。。。。∗︎˚(* ˃̤൬˂̤ *)˚∗︎

gitee:2048-game: html+css+js设计的一个2048游戏(网页)

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

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

相关文章

VScode建立Java项目

学了半天&#xff0c;项目、包是咋创建的都不知道&#x1f62d;&#x1f62d;&#x1f62d;&#xff0c;补习一下✏️✏️✏️ 打开命令面板&#xff0c;“查看”里打开&#xff0c;或者CtrlShiftP。 选择创建Java项目&#xff0c;现在没有用框架&#xff0c;只是普通学习&…

C语言变量与强制类型转换深度解析

在上一篇文章中&#xff0c;小编对数据类型进行了详细的讲解与剖析&#xff0c;所以本篇文章小编要带大家理解变量和强制类型转。还是老规矩&#xff0c;来波鸡汤&#xff0c;学习一定不能着急&#xff0c;无法一下就学明白的知识我们需要给他时间&#xff0c;一定不要在一个知…

国内短剧源码短剧系统搭建小程序部署H5、APP打造短剧平台

​在当今的互联网时代&#xff0c;短剧作为一种新兴的娱乐形式&#xff0c;受到了越来越多用户的喜爱。为了提供更好的用户体验和满足用户需求&#xff0c;一个好的短剧系统需要具备多元化的功能和优质的界面设计。 本文将介绍国内短剧源码短剧系统搭建小程序部署H5、APP所需的…

Synchronized 的几种用法解析

背景介绍 说到并发编程&#xff0c;总绕不开线程安全的问题。 实际上&#xff0c;在多线程环境中&#xff0c;难免会出现多个线程对一个对象的实例变量进行同时访问和操作&#xff0c;如果编程处理不当&#xff0c;会产生脏读现象。 线程安全问题 我们先来看一个简单的线程…

rhce作业4

问题&#xff1a; 1.搭建dns服务器能够对自定义的正向或者反向域完成数据解析查询。 2.配置从DNS服务器&#xff0c;对主dns服务器进行数据备份。 配置&#xff1a; 主服务器配置 安装 关闭防火墙 主配置文件定义正反向解析域 正向解析资源记录文件 反向解析记录文件 重启…

在数据抓取的时候,短效IP比长效IP有哪些优势?

在数据抓取领域&#xff0c;代理IP的选择对于任务的成功率和效率至关重要。短效IP和长效IP各有其特点和适用场景&#xff0c;但在数据抓取过程中&#xff0c;短效IP因其独特的优势而受到青睐。本文将和大家一起探讨短效IP在数据抓取中相比长效IP的优势。 短效IP的定义与特点 …

B2C分销管理系统(源码+文档+部署+讲解)

本文将深入解析“B2C分销管理系统”的项目&#xff0c;探究其架构、功能以及技术栈&#xff0c;并分享获取完整源码的途径。 系统概述 "B2C分销管理系统"是一款集产品管理、客户服务、运营监控和财务管理于一体的综合性分销管理平台。系统功能全面覆盖套餐管理、SI…

【前端基础】CSS基础

目标&#xff1a;掌握 CSS 属性基本写法&#xff0c;能够使用文字相关属性美化文章页。 01-CSS初体验 层叠样式表 (Cascading Style Sheets&#xff0c;缩写为 CSS&#xff09;&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现&#xff08;美化内容&#…

CertiK发现三星区块链密钥库的高风险漏洞,第3次获得致谢

2024年11月5日&#xff0c;CertiK因发现三星手机区块链密钥库&#xff08;Blockchain Keystore&#xff09;的一个高风险漏洞&#xff0c;第3次获得三星的认可与致谢。三星Keystore通过移动硬件安全技术&#xff0c;为私钥的存储与签名过程提供坚固的防护。该漏洞得到及时修复&…

阿里云docker安装禅道记录

docker network ls docker network create -d bridge cl_network sudo docker run --name zentao --restart always -p 9982:80 --networkcl_network -v /data/zentao:/data -e MYSQL_INTERNALtrue -d hub.zentao.net/app/zentao:18.5 升级禅道 推荐用按照此文档升级&a…

DFA算法实现敏感词过滤

DFA算法实现敏感词过滤 需求&#xff1a;检测一段文本中是否含有敏感词。 比如检测一段文本中是否含有&#xff1a;“滚蛋”&#xff0c;“滚蛋吧你”&#xff0c;“有病”&#xff0c; 可使用的方法有&#xff1a; 遍历敏感词&#xff0c;判断文本中是否含有这个敏感词。 …

远程控制项目第四天 功能实现

发送屏幕内容 代码详解 1. 创建 CImage 对象并获取屏幕内容 首先&#xff0c;我们创建一个 CImage 对象&#xff0c;用于接收屏幕上的内容。要获取屏幕内容&#xff0c;我们需要先获取当前设备上下文&#xff08;DC&#xff09;。调用 ::GetDC(NULL) 函数&#xff0c;参数 NU…

多分类logistic回归分析案例教程

因变量为无序多分类变量&#xff0c;比如研究成人早餐选择的相关因素&#xff0c;早餐种类包括谷物类、燕麦类、复合类&#xff0c;此时因变量有三种结局&#xff0c;而且三种早餐是平等的没有顺序或等级属性&#xff0c;此类回归问题&#xff0c;可以使用多分类Logistic回归进…

工业相机常用功能之白平衡及C++代码分享

目录 1、白平衡的概念解析 2、相机白平衡参数及操作 2.1 相机白平衡参数 2.2 自动白平衡操作 2.3 手动白平衡操作流程 3、C++ 代码从XML读取参数及设置相机参数 3.1 读取XML 3.2 C++代码,从XML读取参数 3.3 给相机设置参数 1、白平衡的概念解析 白平衡(White Balance)…

越权访问漏洞

V2Board Admin.php 越权访问漏洞 ## 漏洞描述 V2board面板 Admin.php 存在越权访问漏洞&#xff0c;由于部分鉴权代码于v1.6.1版本进行了修改&#xff0c;鉴权方式变为从Redis中获取缓存判定是否存在可以调用… V2Board Admin.php 越权访问漏洞 漏洞描述 V2board面板 Admin.ph…

[C++ 核心编程]笔记 4.4.2 类做友元

4.4.2 类做友元 关键步骤: 在另一个类中使用 friend class 类名 拓展: 在类外写成员函数(已在类内声明, 实现可以写在外面): //类外写成员函数 Building::Building() {m_SittingRoom "客厅";m_BedRoom "卧室"; }GoodGay::GoodGay() {//创建建筑物对象…

W外链如何设置活码功能?

根据搜索结果&#xff0c;W外链平台的活码功能允许用户创建动态二维码&#xff0c;这些二维码背后可以链接到不同的目标链接或页面&#xff0c;并且可以根据预设条件自动更新跳转链接。以下是W外链平台活码功能的一些关键特点和使用步骤 &#xff1a; 1.活码的特点&#xff1a…

【论文复现】基于图卷积网络的轻量化推荐模型

本文所涉及所有资源均在这里可获取。 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐、摄影的一位博主。 &#x1f4d7;本文收录于论文复现系列&#xff0c;大家有兴趣的可以看一看…

QT 实现绘制汽车仪表盘

1.界面实现效果 以下是具体的项目需要用到的效果展示,通常需要使用QPainter类来绘制各种图形和文本,包括一个圆形的仪表盘、刻度、指针和数字。 2.简介 分为以下几个部分,首先设置抗锯齿 painter.setRenderHint(QPainter::Antialiasing)。 QPainter p(this);p.setRender…

2020年美国总统大选数据分析与模型预测

数据集取自&#xff1a;2020年&#x1f1fa;&#x1f1f8;&#x1f1fa;&#x1f1f8;美国大选数据集 - Heywhale.com 前言 对2020年美国总统大选数据的深入分析&#xff0c;提供各州和县层面的投票情况及选民行为的可视化展示。数据预处理阶段将涉及对异常值的处理&#xff0…