HTML5+JavaScript实现连连看游戏之二

HTML5+JavaScript实现连连看游戏之二

以前一篇,见 https://blog.csdn.net/cnds123/article/details/144220548

连连看游戏连接规则:

只能连接相同图案(或图标、字符)的方块。

连线路径必须是由直线段组成的,最多可以有两个拐角。

连线路径必须是空的,不能穿过其他方块。

当两个相同图案的方块被有效连接时,它们会从游戏板上消失。当所有方块都被消除时,玩家获胜。

现在再发布一个,可以自定义 行列数、可用图片数(实际是使用Font Awesome图标库以便跨平台兼容,通过CDN加载图标库)

同一局游戏中所有图标使用相同颜色,不同局颜色会变化。

游戏就可以在行数和列数乘积为偶数时才允许开始,如果行数和列数的乘积为奇数,则不允许游戏开始,并且可以通过弹出提示信息来告知用户。

点击"开始"按钮后立即生成布局并开始计时。

运行界面

下面代码若要在手机上玩,可以在  <meta charset="UTF-8"> 之后添加一行

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

源码如下:

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>连连看游戏(跨平台版)</title><!-- 引入Font Awesome图标库 --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"><style>body {font-family: Arial, sans-serif;display: flex;flex-direction: column;align-items: center;background-color: #f0f0f0;}#controls {margin: 20px 0;text-align: center;}input, button {margin: 0 10px;padding: 5px;}button {background-color: #4CAF50;color: white;border: none;cursor: pointer;transition: background-color 0.3s;}button:hover {background-color: #45a049;}#timebar {height: 30px;width: 600px;background-color: #ddd;margin-bottom: 20px;position: relative;}#timebar-inner {height: 100%;width: 100%;background-color: green;transition: width 1s linear;}#timeleft {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);color: white;font-weight: bold;z-index: 1;}#container {background-color: white;padding: 20px;border-radius: 10px;box-shadow: 0 0 10px rgba(0,0,0,0.1);display: flex;justify-content: center;align-items: center;}table {border-collapse: collapse;}td {border: 1px solid #ddd;text-align: center;vertical-align: middle;cursor: pointer;transition: background-color 0.3s;width: 40px;height: 40px;font-family: "Font Awesome 5 Free";font-weight: 900;}td:hover {background-color: #f5f5f5;}td i {font-size: 24px;}</style>
</head>
<body><div id="controls">行数<input id="setrow" type="number" value="9" min="2" max="20">列数<input id="setcol" type="number" value="16" min="2" max="40">图片数<input id="setpic" type="number" value="12" min="1" max="26">时间<input id="settime" type="number" value="120" min="10" max="1200">秒<button onclick="SetupGame();">设置</button><button onclick="StartGame();" id="startButton">开始</button></div><div id="timebar"><div id="timebar-inner"></div><div id="timeleft"></div></div><div id="container"></div><script>// 图标配置(扩展更多图标请访问:https://fontawesome.com/icons)const icons = ['fa-heart',    'fa-star',    'fa-circle',  'fa-square','fa-check',    'fa-times',   'fa-bell',    'fa-flag','fa-cloud',    'fa-sun',     'fa-moon',    'fa-leaf','fa-gem',      'fa-car',     'fa-tree',    'fa-coffee','fa-bolt',     'fa-rocket',  'fa-key',     'fa-bug','fa-cat',      'fa-dog',     'fa-fish',    'fa-horse'];// 图标配置(仅定义类型)const iconClasses = ['fa-heart', 'fa-star', 'fa-circle', 'fa-square','fa-check', 'fa-times', 'fa-bell', 'fa-flag','fa-cloud', 'fa-sun', 'fa-moon', 'fa-leaf'];let currentColor = ""; // 全局当前颜色let RowMax = 11;let ColMax = 18;let PicMax = 12;let TimeMax = 120;let st;let TmpStr = "";let TmpObj = null;let TmpTime = 0;let TmpInt = 0;let gameMatrix;let gameStarted = false;let P = new Array(4);for(let i=0; i<4; i++) P[i] = {x:0, y:0};function SetupGame(){clearInterval(st);// 参数校验const rowVal = Math.min(20, Math.max(2, parseInt(document.getElementById("setrow").value)));const colVal = Math.min(40, Math.max(2, parseInt(document.getElementById("setcol").value)));RowMax = rowVal + 2;ColMax = colVal + 2;// 检查行数与列数的乘积是否为偶数if ((rowVal * colVal) % 2 !== 0) {alert("行数和列数的乘积必须为偶数,请调整行数或列数。");return; // 终止函数执行}PicMax = Math.min(icons.length, Math.max(1, parseInt(document.getElementById("setpic").value)));TimeMax = Math.min(1200, Math.max(10, parseInt(document.getElementById("settime").value)));generateNewGame();document.getElementById("timeleft").innerHTML = "点击开始按钮开始游戏";document.getElementById("timebar-inner").style.width = "100%";document.getElementById("timebar-inner").style.backgroundColor = "#4CAF50";document.getElementById("startButton").disabled = false;gameStarted = false;}function getRandomColor() {return `hsl(${Math.random() * 360}, 70%, 60%)`; // 随机HSL颜色}function generateNewGame() {gameMatrix = Array(RowMax).fill().map(() => Array(ColMax).fill(0));// 生成全局统一颜色currentColor = `hsl(${Math.random()*360}, 70%, 60%)`; // 随机HSL颜色// 生成配对逻辑(仅存储图标类型索引)const totalCells = (RowMax-2)*(ColMax-2);const pairs = [];for(let i=0; i<totalCells/2; i++){const type = i % PicMax; // 确保成对生成pairs.push(type, type);}// 洗牌算法for(let i = pairs.length -1; i > 0; i--){const j = Math.floor(Math.random() * (i+1));[pairs[i], pairs[j]] = [pairs[j], pairs[i]];}// 构建表格(所有图标使用相同颜色)TmpStr = "<table>";let pairIndex = 0;for(let i=0; i<RowMax; i++){TmpStr += "<tr>";for(let j=0; j<ColMax; j++){TmpStr += `<td onclick="CheckP(this,${i},${j});">`;if(i === 0 || j === 0 || i === RowMax-1 || j === ColMax-1){gameMatrix[i][j] = null; // 边界保持为空} else {const type = pairs[pairIndex++];gameMatrix[i][j] = type; // 存储类型索引// 所有图标使用同一颜色TmpStr += `<i class="fas ${iconClasses[type]}" style="color:${currentColor}"></i>`;}TmpStr += "</td>";}TmpStr += "</tr>";}TmpStr += "</table>";document.getElementById("container").innerHTML = TmpStr;TmpInt = totalCells/2;}// 开始游戏function StartGame(){gameStarted = true; // 标记游戏已开始TmpTime = TimeMax; // 重置时间document.getElementById("timeleft").innerHTML = TmpTime; // 显示剩余时间document.getElementById("timebar-inner").style.width = "100%";document.getElementById("timebar-inner").style.backgroundColor = "green";st = setInterval(ShowTime, 1000); // 开始倒计时// 禁用"开始"按钮document.getElementById("startButton").disabled = true;}// X方向连线。(有起点,无终点)function LineX(x, y, xt){for(let i=x; i!=xt; (x<xt? i++: i--) ){if(gameMatrix[i][y]){return false;}}return true;}// Y方向连线。(有起点,无终点)function LineY(x, y, yt){for(let i=y; i!=yt; (y<yt? i++: i--) ){if(gameMatrix[x][i]){return false;}}    return true;}// 2个点被3条线连接function LinkP(P1,P2){// P1在P2下方,交换P1、P2if(P1.x>P2.x){[P1, P2] = [P2, P1];}// P1下方1点(x+1)先横向再纵向是否可连接。(因为起点P1不为空,所以检测其下方一点)if( LineX((P1.x+1), P1.y, P2.x) && LineY(P2.x, P1.y, P2.y) ) return true;// P1先向上侧连接,再检测该点再横向再纵向是否可连接P2。for(let j=(P1.y-1); j>=0; j--){if(gameMatrix[P1.x][j]) break;if( LineX((P1.x+1), j, P2.x) && LineY(P2.x, j, P2.y) ) return true;}// P1先向下侧连接,再检测该点再横向再纵向是否可连接P2。for(let j=(P1.y+1); j<ColMax; j++){if(gameMatrix[P1.x][j]) break;if( LineX((P1.x+1), j, P2.x) && LineY(P2.x, j, P2.y) ) return true;}// P1在P2左侧,交换P1、P2if(P1.y>P2.y){[P1, P2] = [P2, P1];}if( LineY(P1.x, (P1.y+1), P2.y) && LineX(P1.x, P2.y, P2.x) ) return true;for(let j=(P1.x-1); j>=0; j--){if(gameMatrix[j][P1.y]) break;if( LineY(j, (P1.y+1), P2.y) && LineX(j, P2.y, P2.x) ) return true;}for(let j=(P1.x+1); j<RowMax; j++){if(gameMatrix[j][P1.y]) break;if( LineY(j, (P1.y+1), P2.y) && LineX(j, P2.y, P2.x) ) return true;}return false;}// 单击检测该点(仅需比较类型)function CheckP(o,x,y){if (!gameStarted) return;if(gameMatrix[x][y] !== null){ if(null==TmpObj){ TmpObj = o;TmpObj.style.border = "2px solid blue";P[0].x = x;P[0].y = y;}else if(o!=TmpObj){TmpObj.style.border = "";P[1].x = x;P[1].y = y;// 仅比较类型索引if(gameMatrix[P[0].x][P[0].y] === gameMatrix[P[1].x][P[1].y]){if(LinkP(P[0],P[1])){gameMatrix[P[0].x][P[0].y] = null;gameMatrix[P[1].x][P[1].y] = null;TmpObj.innerHTML = "";o.innerHTML = "";TmpTime++;TmpInt--;if(!TmpInt){clearInterval(st);document.getElementById("timeleft").innerHTML = "";document.getElementById("timebar-inner").style.backgroundColor = "white";alert("恭喜完成!");document.getElementById("startButton").disabled = false;gameStarted = false;}}}TmpObj = null;}} else {if(TmpObj) TmpObj.style.border = "";TmpObj = null;}}function ShowTime(){TmpTime--; // 时间减1// 更新时间显示document.getElementById("timeleft").innerHTML = TmpTime;let percentage = Math.floor(100*TmpTime/TimeMax);document.getElementById("timebar-inner").style.width = percentage + "%";if(percentage <= 25){document.getElementById("timebar-inner").style.backgroundColor = "red";}else if(percentage <= 50){document.getElementById("timebar-inner").style.backgroundColor = "yellow";}if(!TmpTime){ // 剩余时间为0clearInterval(st); // 清除倒计时document.getElementById("timeleft").innerHTML = "";document.getElementById("timebar-inner").style.backgroundColor = "white";alert("时间到!游戏结束");// 启用"开始"按钮document.getElementById("startButton").disabled = false;gameStarted = false; // 重置游戏状态}}// 页面加载完成后,显示初始提示信息window.onload = function() {document.getElementById("timeleft").innerHTML = "请设置游戏参数并点击设置按钮";document.getElementById("timebar-inner").style.backgroundColor = "#ddd";document.getElementById("startButton").disabled = true;}</script>
</body>
</html>

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

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

相关文章

《深入浅出Git:从版本控制原理到高效协作实战》​

Git的原理和使用 1、Git初识与安装2、Git基本操作2.1、创建Git本地仓库2.2、配置Git2.3、认识工作区、暂存区、版本库2.4、修改文件2.5、版本回退2.6、撤销修改2.7、删除文件 3、Git分支管理3.1、理解分支3.2、创建、切换、合并分支3.3、删除分支3.4、合并冲突3.5、合并模式3.6…

数据分析_问题/优化

1 报表开发 1.1 数据问题 (1) 数据易错 问题描述 ①数据整合困难:数据来源多样、格式差异大,整合时处理不当易丢错数据. ②计算逻辑复杂:开发人员对复杂计算逻辑的理解产生偏差,会导致计算结果不准. 解决方案 ①建立数据标准,统一修正字段命名、数据类型、日期格式等 ②加强…

“深入剖析ThreadLocal原理:从多线程数据隔离到内存泄漏防范“

1.在没有ThreadLocal遇到的问题&#xff1a; 在多线程编程领域&#xff0c;多个线程同时访问同一个变量时&#xff0c;数据一致性成为关键挑战。为防止修改数据时出现覆盖问题&#xff0c;传统解决方案是采用加锁机制&#xff0c;让线程排队依次访问共享变量。然而&#xff0c…

读懂 Vue3 路由:从入门到实战

在构建现代化单页应用&#xff08;SPA&#xff09;时&#xff0c;Vue3 凭借其简洁高效的特性成为众多开发者的首选。 而 Vue3 路由&#xff08;Vue Router&#xff09;则是 Vue3 生态中不可或缺的一部分&#xff0c;它就像是单页应用的 “导航地图”&#xff0c;帮助用户在不同…

Mac M1安装 Docker Desktop 后启动没反应

Mac M1安装 Docker Desktop 后启动没反应 如果在 Mac M1 上安装 Docker&#xff0c;那最好的选择是安装 Docker Desktop但是今天重新安装 Docker Desktop 后&#xff0c;发现点击图标启动怎么也没反应&#xff0c;经过排查后发现换个版本安装就好了&#xff0c;可能是最新的版…

快速上手c语言

快速上手c语言 快速上手c语言关于学c语言的一些信息杂谈第一个C语言程序通过命令行运行c程序Dev-c5.11Visual Studio系列产品 数据类型变量、常量定义变量的方法变量的命名变量的分类变量的使用变量的作用域和生命周期常量 操作符简单介绍语句选择语句循环语句 数组数组定义数组…

Nginx核心功能及正则表达

目录 一&#xff1a;正向代理 1&#xff1a;编译安装nginx &#xff08;1&#xff09;安装支持软件 &#xff08;2&#xff09;创建运行用户、组和日志目录 &#xff08;3&#xff09;编译安装nginx &#xff08;4&#xff09;添加nginx系统服务 2&#xff1a;配置正向代…

npm命令介绍(Node Package Manager)(Node包管理器)

文章目录 npm命令全解析简介基础命令安装npm&#xff08;npm -v检插版本&#xff09;初始化项目&#xff08;npm init&#xff09;安装依赖包&#xff08;npm install xxx、npm i xxx&#xff09;卸载依赖包&#xff08;npm uninstall xxx 或 npm uni xxx、npm remove xxx&…

【Linux】Linux基础概念

一些比较重要的使用Linux的前情提要。 部分经验来源于网络&#xff0c;若有侵权请联系我删除&#xff0c;主要是做笔记的时候忘记写来源了&#xff0c;做完笔记很久才写博客。 专栏目录&#xff1a;记录自己的嵌入式学习之路-CSDN博客 目录 1 Shell命令参数 2 系统变量…

阿里开源Qwen3:大语言模型的新突破

一、模型概览&#xff1a;丰富的模型家族 Qwen3 系列包含了 2 款混合专家&#xff08;MoE&#xff09;模型与 6 款密集&#xff08;Dense&#xff09;模型&#xff0c;参数量覆盖范围极广&#xff0c;从 0.6B 一直延伸至 235B 。其中&#xff0c;旗舰模型 Qwen3 - 235B - A22B…

数字智慧方案5856丨智慧环保综合解决方案(50页PPT)(文末有下载方式)

资料解读&#xff1a;智慧环保综合解决方案 详细资料请看本解读文章的最后内容。 随着城市化进程的加速和环境问题的日益严峻&#xff0c;智慧环保成为提升城市环境管理水平的重要手段。本文将对智慧环保综合解决方案进行详细解读&#xff0c;探讨其在实际应用中的需求、解决…

基于ssm的网盘管理系统(全套)

一、系统架构 前端&#xff1a;vue | element-ui 后端&#xff1a;spring | springmvc | mybatis 环境&#xff1a;jdk1.8 | mysql | maven | tomcat | nodejs 二、代码及数据库 三、功能介绍 01. 注册 02. 登录 03. 管理员-首页 04. 管理员-个人中心 …

PostgreSQL 的 VACUUM 与 VACUUM FULL 详解

PostgreSQL 的 VACUUM 与 VACUUM FULL 详解 一、基本概念对比 特性VACUUMVACUUM FULL定义常规维护操作&#xff0c;清理死元组激进重组操作&#xff0c;完全重写表数据锁级别不阻塞读写(共享锁)排他锁(阻塞所有操作)空间回收只标记空间为可用&#xff0c;不返还OS空间返还操作…

复刻低成本机械臂 SO-ARM100 舵机配置篇(WSL)

视频讲解&#xff1a; 复刻低成本机械臂 SO-ARM100 舵机配置篇&#xff08;WSL&#xff09; 飞特舵机 组装之前需要配置舵机的ID&#xff0c;如下的网址为舵机的资料&#xff0c;实际上用不到&#xff0c;但可以mark在这里 Software-深圳飞特模型有限公司 User Guide里面可以…

Tailwind CSS实战技巧:从核心类到高效开发

使用 Kooboo平台 训练实战技巧&#xff0c;无需配置安装&#xff0c;直接引入CDN就可以在线练习了&#xff01;具体操作流程&#xff1a;进入Kooboo后&#xff0c;选择创建空白站点 -> 站点开发 -> 控制面板 -> 页面 ->新建普通页面 -> 编写代码 一、核心布局类…

【LINUX操作系统】线程操作

了解了线程的基本原理之后&#xff0c;我们来学习线程在C语言官方库中的写法与用法。 1. 常见pthread接口及其背后逻辑 1.1 pthread_create 与线程有关的函数构成了⼀个完整的系列&#xff0c;绝⼤多数函数的名字都是以“pthread_”打头的 • 要使⽤这些函数库&#xff0c;…

【AI面试准备】Azure DevOps沙箱实验全流程详解

介绍动手实验&#xff1a;通过 Azure DevOps 沙箱环境实操&#xff0c;体验从代码提交到测试筛选的全流程。如何快速掌握&#xff0c;以及在实际工作中如何运用。 通过 Azure DevOps 沙箱环境进行动手实验&#xff0c;是快速掌握 DevOps 全流程&#xff08;从代码提交到测试筛选…

VulnHub-DC-2靶机

主机发现 sudo arp-scan -l 以sudo管理员权限扫描本地活动ip地址 Interface: eth0, type: EN10MB, MAC: 08:00:27:22:46:4f, IPv4: 192.168.252.230 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.252.6 4c:5f:70:74:3c:3b …

藏语英语中文机器翻译入门实践

&#x1f3af; 项目目标&#xff1a; 输入藏文句子&#xff0c;自动翻译成英文和中文&#xff08;或输入中文&#xff0c;翻译为英文和藏文&#xff09;。 &#x1f50d; 技术与原理简介 机器翻译&#xff08;Machine Translation, MT&#xff09;是人工智能中自然语言处理&a…

【阿里云大模型高级工程师ACP习题集】2.9 大模型应用生产实践(上篇)

练习题 【单选题】在自然语言处理的法务咨询场景中,以下哪种模型选择最为合适? A. 通用大语言模型 B. 经过数学领域微调的模型 C. 面向法律领域训练的模型 D. 视觉模型 【多选题】以下哪些属于模型非功能性需求?( ) A. 模型对不同语言的支持能力 B. 模型的响应速度要求 C.…