H5 台球猜位置小游戏

刷到抖音有人这样玩,就写了一个这样的小游戏练习一下H5的知识点。

小游戏预览
w(゚Д゚)w 不开挂越急越完成不了,👿确认15次也没全对…
在这里插入图片描述
知识点

获取坐标位置的DOM元素,感觉应该是新的吧,以前的时候没什么印象有这个方法。兼容性不晓得可以自己查下~

document.elementFromPoint(x, y)

源码
注释不多,比较简单的,还是比较好理解的。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="./assets/global.css"><style>.block {width: 65px;height: 65px;/* position: absolute; */background-size: 300px;display: inline-block;user-select: none;background-position: calc(var(--x, 0) * (65px + 13.5px) * -1) calc(var(--y, 0) * (65px + 13.5px) * -1);}.title {margin-top: 40px;font-size: 40px;font-weight: bold;text-align: center;}.container {margin: 0 20px;}.tips {margin: 20px;font-size: 20px;color: rgba(0, 0, 0, .5);}.btn {margin: 20px;color: #fff;background-color: green;width: 120px;height: 40px;line-height: 40px;text-align: center;}.btn:active {opacity: .7;}.abs {position: absolute;z-index: 2;pointer-events: none;}.op5 {opacity: .5;}.billiard-container .block {pointer-events: none;width: 32.5px;height: 32.5px;background-size: 150px;background-position: calc(var(--x, 0) * (32px + 7.5px) * -1) calc(var(--y, 0) * (32px + 7.5px) * -1)/* transform: scale(-50%); */}.result {display: flex;flex-direction: column-reverse}.result-item {display: flex;align-items: center;padding: 10px 20px 0;}.result-item .index {font-size: 20px;font-weight: bold;margin-right: 20px;}.result-item .billiard-container {flex: 1;}.result-item .right-count {color: #12be77;}.win {margin: 20px 20px 0;font-size: 20px;}</style>
</head><body><div class="title">猜位置</div><div class="tips">拖动更换位置,点击确认获取结果,位置都正确获取游戏胜利。</div><div class="container"></div><div class="win">🐂🍺! 🎉游戏胜利!🎉</div><div class="btn">确定</div><div class="result"></div><script type="module">let winDom = document.querySelector('.win')winDom.hidden = true;import { Maths, Randoms, Animation, cloneDeep, InterchangeFlag } from "https://unpkg.com/@3r/tool"let containerDom = document.querySelector('.container')let btnDom = document.querySelector('.btn')let resultDom = document.querySelector('.result')let billiardConfig = {sprite: './assets/taiqiu.png',blocks: [{id: '1',position: { x: 0, y: 0 }},{id: '2',position: { x: 1, y: 0 }},{id: '3',position: { x: 2, y: 0 }},{id: '4',position: { x: 3, y: 0 }},{id: '5',position: { x: 0, y: 1 }},{id: '6',position: { x: 1, y: 1 }},{id: '7',position: { x: 2, y: 1 }},{id: '8',position: { x: 3, y: 1 }},{id: '9',position: { x: 0, y: 2 }},{id: '10',position: { x: 1, y: 2 }},{id: '11',position: { x: 2, y: 2 }},{id: '12',position: { x: 3, y: 2 }},{id: '13',position: { x: 0, y: 3 }},{id: '14',position: { x: 1, y: 3 }},{id: '15',position: { x: 2, y: 3 }},{id: '白球',position: { x: 3, y: 3 }}]}let allBlocks = cloneDeep(billiardConfig.blocks) // 所有的数据let selBlockDom = null // 移动前不动的球let movBlockDom = null // 当前移动的球let hovBlockDom = null // 不表浮动到哪个球上面let curBlocks = Randoms.getDisorganizeArray(cloneDeep(allBlocks)).slice(0, 5) // 记录当前记录let resDataIds = Randoms.getDisorganizeArray(curBlocks.map(b => b.id)) // 记录本轮结果let hisList = [] // 记录历史document.body.addEventListener("touchmove", handleMoving)document.body.addEventListener("touchend", handleMoveEnd)document.body.addEventListener("touchcancel", handleMoveEnd)document.body.addEventListener("mousemove", handleMoving)document.body.addEventListener("mouseup", handleMoveEnd)function handleMoveStart(ev) {// console.log("handleMoveStart", ev);let x, y;if (ev.type == 'touchstart') {selBlockDom = ev.target;movBlockDom = ev.target.cloneNode()x = ev.touches[0].clientXy = ev.touches[0].clientY}if (ev.type == 'mousedown') {x = ev.xy = ev.yselBlockDom = ev.target;movBlockDom = ev.target.cloneNode()}if (!movBlockDom) return;movBlockDom.classList.add('abs')movBlockDom.classList.add('op5')movBlockDom.style.left = `${x}px`movBlockDom.style.top = `${y}px`document.body.appendChild(movBlockDom)}function handleMoving(ev) {// console.log("handleMoving", ev);let x, y;if (ev.type == 'touchmove') {x = ev.touches[0].clientXy = ev.touches[0].clientY}if (ev.type == 'mousemove') {x = ev.xy = ev.y}x = Math.floor(x)y = Math.floor(y)hovBlockDom?.classList.remove('op5')hovBlockDom = null;let tmpHovBlockDom = document.elementFromPoint(x, y)if (tmpHovBlockDom.classList.contains('block')) {tmpHovBlockDom.classList.add('op5')hovBlockDom = tmpHovBlockDom;}if (!movBlockDom) return;movBlockDom.style.left = `${x}px`movBlockDom.style.top = `${y}px`}function handleMoveEnd(ev) {if (!movBlockDom) return;if (hovBlockDom) {// 交换位置let dataId = hovBlockDom.getAttribute('data-id')let style = hovBlockDom.getAttribute('style');hovBlockDom.setAttribute('data-id', selBlockDom.getAttribute('data-id'))hovBlockDom.setAttribute('style', selBlockDom.getAttribute('style'))selBlockDom.setAttribute('data-id', dataId)selBlockDom.setAttribute('style', style)let idx1 = curBlocks.findIndex(b => b.id == selBlockDom.getAttribute('data-id'))let idx2 = curBlocks.findIndex(b => b.id == hovBlockDom.getAttribute('data-id'))// 下标交换Maths.interchange(curBlocks, idx1, idx2, InterchangeFlag.Change)}hovBlockDom?.classList.remove('op5')document.body.removeChild(movBlockDom)hovBlockDom = null;movBlockDom = null;selBlockDom = null;}// 生成球function generateBilliardItemDom(blocks) {let blockDomList = []for (const block of blocks) {let blockDom = document.createElement('div')blockDom.classList.add('block')// let px = Math.round(block.position.x * billiardConfig.width + billiardConfig.marginRight * block.position.x) * -1// let py = Math.round(block.position.y * billiardConfig.height + billiardConfig.marginBottom * block.position.y) * -1// let backgroundPosition = `background-position: ${px}px ${py}px;`// blockDom.style = `background-image: url(${billiardConfig.sprite});${backgroundPosition}`blockDom.setAttribute('style', `--x: ${block.position.x}; --y: ${block.position.y}`);blockDom.style.backgroundImage = `url(${billiardConfig.sprite})`blockDom.setAttribute('data-id', block.id)blockDom.addEventListener("mousedown", handleMoveStart)blockDom.addEventListener("touchstart", handleMoveStart)blockDomList.push(blockDom)// containerDom.appendChild(blockDom)}return blockDomList}// 生成历史结果function generateResultDom(result) {let resultItemDom = document.createElement('div')resultItemDom.classList.add('result-item')let indexDom = document.createElement('div')indexDom.classList.add('index')indexDom.textContent = `${hisList.length + 1}`let billiardDom = document.createElement('div')billiardDom.classList.add('billiard-container')let rightCountDom = document.createElement('div')rightCountDom.classList.add('right-count')rightCountDom.textContent = `✔ × ${result.rightCount}`generateBilliardItemDom(result.blocks).forEach(item => {billiardDom.appendChild(item)});resultItemDom.appendChild(indexDom)resultItemDom.appendChild(billiardDom)resultItemDom.appendChild(rightCountDom)resultDom.appendChild(resultItemDom)}// 计算结果function calculateResult() {let curDataIds = curBlocks.map(b => b.id)let rightCount = 0;for (let i = 0; i < curDataIds.length; i++) {if (curDataIds[i] == resDataIds[i]) {rightCount++;}}// 判断是否游戏胜利✌if (rightCount == curBlocks.length) {winDom.hidden = false;btnDom.hidden = true;}let result = {rightCount,blocks: cloneDeep(curBlocks)}generateResultDom(result)hisList.push(result)}btnDom.addEventListener('click', calculateResult)generateBilliardItemDom(curBlocks).forEach(item => {containerDom.appendChild(item)});</script>
</body></html>

源码地址 https://github.com/linyisonger/H5.Examples
在线试玩 https://linyisonger.github.io/H5.Examples/?name=./066.%E7%8C%9C%E4%BD%8D%E7%BD%AE.html

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

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

相关文章

使用Python进行容器编排Docker Compose与Kubernetes的比较

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 随着容器化技术的普及&#xff0c;容器编排成为了管理和部署容器化应用程序的重要环节。在容…

[C++][算法基础]求约数(试除法)

给定 n 个正整数 &#xff0c;对于每个整数 &#xff0c;请你按照从小到大的顺序输出它的所有约数。 输入格式 第一行包含整数 n。 接下来 n 行&#xff0c;每行包含一个整数 。 输出格式 输出共 n 行&#xff0c;其中第 i 行输出第 i 个整数 的所有约数。 数据范围 1≤…

上传文件到HDFS

1.创建文件夹 hdfs -dfs -mkdir -p /opt/mydoc 2.查看创建的文件夹 hdfs -dfs -ls /opt 注意改文件夹是创建在hdfs中的&#xff0c;不是本地&#xff0c;查看本地/opt&#xff0c;并没有该文件夹。 3.上传文件 hdfs dfs -put -f file:///usr/local/testspark.txt hdfs://m…

插值与重采样在AI去衣技术中的关键作用

在人工智能&#xff08;AI&#xff09;的众多应用中&#xff0c;去衣技术作为一种新兴的图像处理技术&#xff0c;逐渐引起了广泛关注。这项技术不仅涉及复杂的计算机视觉和深度学习算法&#xff0c;还需要对图像处理中的插值与重采样技术有深入的理解。本文将详细探讨插值与重…

【智能算法】寄生捕食算法(PPA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2020年&#xff0c;AAA Mohamed等人受到自然界乌鸦-布谷鸟-猫寄生系统启发&#xff0c;提出了寄生捕食算法&#xff08;Parasitism – Predation Algorithm, PPA&#xff09;。 2.算法原理 2.1算法…

密钥密码学(一)

原文&#xff1a;annas-archive.org/md5/b5abcf9a07e32fc6f42b907f001224a1 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 序言 从秘密解码环到政府政策声明&#xff0c;隐藏和发现信息的挑战长期以来一直吸引着智慧。密码学是一个引人入胜的主题&#xff0c;…

网络安全与密码学--AES加密

分组加密之AES加密算法 AES算法的诞生 python实现AES加密 AES加密详细流程 AES解密过程 AES的应用 1997年 NIST征集AES&#xff08;Advanced Encryption Standard&#xff09;2000年选中 https://www.nist.gov/ https://csrc.nist.gov/projects/block-cipher-techniques A…

串联超前及对应matlab实现

串联超前校正它的本质是利用相角超前的特性提高系统的相角裕度。传递函数为&#xff1a;下面将以一个实际的例子&#xff0c;使用matlab脚本&#xff0c;实现其校正后的相位裕度≥60。

YOLOv8-PySide --- 基于 ultralytics 8.1.0 发行版优化 | 代码已开源

YOLOv8-PySide — 基于 ultralytics 8.1.0 发行版优化 Github 项目地址&#xff1a;https://github.com/WangQvQ/Ultralytics-PySide6 页面效果 如何使用 pip install ultralytics8.1.0 or git clone --branch v8.1.0 --single-branch https://github.com/ultralytics/ultral…

如何让AI生成自己喜欢的歌曲-AI音乐创作的正确方式 - 第507篇

历史文章 AI音乐&#xff0c;8大变现方式——Suno&#xff1a;音乐版的ChatGPT - 第505篇 日赚800&#xff0c;利用淘宝/闲鱼进行AI音乐售卖实操 - 第506篇 导读 在使用AI生成音乐&#xff08;AI写歌&#xff09;的时候&#xff0c;你是不是有这样的困惑&#xff1a; &…

新版a_bogus算法分析以及成品展示调用

新版a_bogus算法的过程&#xff0c;仅学习参考&#xff0c;如有涉及侵权联系本人删除 最近看到这个参数花了点时间研究了一下 流程和X-Bogus差不多&#xff0c;通过对这段字符串概是对数据、ua、时间戳、浏览器的几个指纹进行计算&#xff0c;长度168位 下面是实现效果以及测…

TQZC706开发板教程:编译zynq linux内核2019_R1

您需要下载对应版本的Linux系统文件以及IMG1.3.1镜像文件。为了方便您的操作&#xff0c;本文所使用的所有文件以及最终生成的文件&#xff0c;我都已经整理并放置在本文末尾提供的网盘链接中。您可以直接通过该链接进行下载&#xff0c;无需在其他地方单独搜索和获取。希望这能…

C语言:数据结构(单链表)

目录 1. 链表的概念及结构2. 实现单链表3. 链表的分类 1. 链表的概念及结构 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表的指针链接次序实现的。 链表的结构跟火车车厢相似&#xff0c;淡季时车次的车厢会相应…

linux之进程通信

目录 一、进程通信介绍 1.目的 2.发展 3.进程通信是什么&#xff0c;怎么通信&#xff1f; 二、管道 1.介绍 2.匿名管道 1.单向通信管道原理 2.代码实现 3.管道特征 4.管道的四种情况 5.管道的应用场景 使用管道实现一个简易版本的进程池 3.命名管道 1.思考 2.…

使用JXLS+Excel模板制作灵活的excel导出

前期一直卡在模板的批注上&#xff0c;改了很多遍的模板批注最终才成功导入&#xff0c;记录下方便以后寻找。 话不多说直接上代码&#xff1a; Report package com.example.jxls.common;import java.io.IOException; import java.io.InputStream; import java.io.OutputStr…

使用 Meta Llama 3 构建人工智能的未来

使用 Meta Llama 3 构建人工智能的未来 现在提供 8B 和 70B 预训练和指令调整版本,以支持广泛的应用 使用 Meta AI 体验 Llama 3 我们已将 Llama 3 集成到我们的智能助手 Meta AI 中,它扩展了人们完成工作、创造和与 Meta AI 联系的方式。通过使用 Meta AI 进行编码任务和解…

C语言.字符函数与字符串函数

字符函数与字符串函数 1.字符分类函数2.字符转换函数3.[strlen](https://cplusplus.com/reference/cstring/strlen/?kwstrlen) 的使用和模拟实现4.[strcpy](https://legacy.cplusplus.com/reference/cstring/strcpy/?kwstrcpy) 的使用和模拟实现5.[strcat](https://legacy.cp…

信息系统及其技术发展

目录 一、信息系统基本概念 1、信息系统项目开发 2、信息系统项目管理 3、信息系统 Ⅰ、生命周期 Ⅱ、新基建 ①信息基础设施 ②融合基础设施 ③创新基础设施 Ⅲ、工业互联网 Ⅳ、车联网 ①体系框架 ②连接方式 4、习题 二、信息技术发展 1、SDN 2、5G 3、存储…

书生·浦语大模型第二期实战营(5)笔记

大模型部署简介 难点 大模型部署的方法 LMDeploy 实践 安装 studio-conda -t lmdeploy -o pytorch-2.1.2conda activate lmdeploypip install lmdeploy[all]0.3.0模型 ls /root/share/new_models/Shanghai_AI_Laboratory/ln -s /root/share/new_models/Shanghai_AI_Laborato…

只需几步,即可享有笔记小程序

本示例是一个简单的外卖查看店铺点菜的外卖微信小程序&#xff0c;小程序后端服务使用了MemFire Cloud&#xff0c;其中使用到的MemFire Cloud功能包括&#xff1a; 其中使用到的MemFire Cloud功能包括&#xff1a; 云数据库&#xff1a;存储外卖微信小程序所有数据表的信息。…