别踩白块web小游戏

整体思路

1.设置一个游戏界面main(最外面一圈方框)
2.main内部放置一个容器container,容器非常长,且容器底部位于main的顶部
3.将容器内的黑块和白块事先处理好,并将黑块存储在黑块数组中
    容器黑白块处理:①生成一行的黑白块 ②遍历生成一整个容器的黑白块
4.点击开始按钮后,容器开始向下移动,使黑白块随之下落
  容器超出main的部分均会被隐藏
5.点击黑块,黑块变白,并清除黑块数组中的值
6.当黑块数组中任意一个黑块触碰到mai底部时,游戏结束
补充:难度不同速度不同,对于速度的控制:
    setInterval(moveContainerDown, 20);每隔20毫秒调用下落函数
        下落函数里获取当前容器的top值(var top = parseInt(container.style.top) || initialTop;)
        再更新容器的top值,使容器向下移动(container.style.top = top + speed + "px";)

改进

我是将所有的黑白块一开始就生成好放在容器里,容器高度设置非常高;
然后让容器整个往下降,超过main的部分隐藏,实现看起来下落的效果,但这样负担较大
理想中应该是容器内的每一行依次下降(而不是容器下降),
最底部一行越界消失,顶部则新增一行,但是我无法实现

完整代码
// bcbk.html<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>别踩白块</title><link rel="stylesheet" href="bcbk.css">
</head><body><audio id="audioPlayer"><source src="点击.mp3" type="audio/mpeg"></audio><div id="main"><div id="container"></div></div><div class="choose"><select id="difficulty"><option value="easy">初级</option><option value="medium">中级</option><option value="hard">高级</option></select><button id="startbt">开始游戏</button><div id="scoreDisplay">分数: 000</div></div><script src="bcbk.js"></script></body></html>
// bcbk.css* {margin: 0;padding: 0;font-size: 30px;border-collapse: collapse;/* 去除单元格之间的间隙 */box-sizing: border-box;/* 让边框宽度计入方块尺寸 */
}/* 最外面那层游戏框 */
#main {width: 400px;height: 450px;border: 1px solid black;margin: 0 auto;overflow: hidden;margin-top: 60px;position: relative;
}/* 所有的内部方块构成的整体容器 */
#container {width: 400px;position: absolute;
}/* 选择难度 和 开始按钮 的父盒子 */
.choose {display: flex;align-items: center;/* 子元素垂直居中 */justify-content: center;/* 子元素水平居中 */margin: 10px auto;width: 400px;height: 50px;font-size: 20px;
}/* 选择难度按钮 */
#difficulty {margin-right: 10px;
}/* 分数 */
#scoreDisplay {margin-left: 10px;
}/* 方块:默认白色 */
.cell {width: 100px;height: 100px;float: left;background-color: white;/* border: 0.1px solid black; */}/* 黑块 */
.cellblack {background-color: black;
}/* 白块 */
.cellbwhite {background-color: white;
}/* 黑块放大动画 */
@keyframes grow {0% {transform: scale(1);opacity: 1;/* 完全不透明 */}100% {transform: scale(1.4);/* 放大1.4倍数 */opacity: 0;/* 完全透明 */}
}
// bcbk.jsdocument.addEventListener('DOMContentLoaded', function () {//获取容器和主容器元素var container = document.getElementById("container");var main = document.getElementById("main");// 获取开始游戏按钮// var startButton = document.getElementById("startbt");var rowCount = 50;//方块行数var initialTop = -5000;// 初始位置距离页面顶部的高度=rowCount * cell.widthvar blackBlocks = [];//存储黑块的数组var gameStart = false;//游戏开始标志var intervalID;//定时器var score;//分数var scoreDisplay = document.getElementById("scoreDisplay");//分数显示var audioPlayer = document.getElementById("audioPlayer");//点击音效//------更新分数function updateScore() {score += 5; //点一次黑块加5分if (score < 10) {scoreDisplay.textContent = "分数: 00" + score;}else if (score < 100) {scoreDisplay.textContent = "分数: 0" + score;}else {scoreDisplay.textContent = "分数: " + score;}//最原始的方法保证分数是三位数,因为肯定玩不到1000分}//------点击开始游戏按钮,游戏开始document.getElementById("startbt").addEventListener("click", function () {startGame(); // 调用开始游戏函数});//------点击黑块则变白,并更新得分function clickBlackBlock() {if (this.classList.contains("cellblack")) {audioPlayer.play();//添加放大渐变消失动画this.style.animation = "grow 0.4s forwards";//将当前元素应用名为 "grow" 的动画,持续0.4秒,并且动画执行完毕后保持最终状态(不回到初始状态)this.classList.remove("cellblack");//移除该黑块// this.classList.add("cellwhite");//之前写的是把黑块变成白块,而不是移除黑块,会出现://黑块变白块后,再点击该白块,又变黑块,需要设置clicked棋子,很麻烦,还是直接移除的好var index = blackBlocks.indexOf(this);if (index !== -1) {blackBlocks.splice(index, 1);//清除 已点击黑块 在 blackBlocks中的索引}updateScore();//更新分数}}//------生成初始黑块的索引function generateInitialBlackIndices() {var indices = [];//存储黑块的索引位置var blackCount = Math.floor(Math.random() * 3 + 1);//黑块个数1-3(没有4,一行全黑太难了)for (var i = 0; i < blackCount; i++) {var index = Math.floor(Math.random() * 4);//黑块索引位置indices.push(index);}return indices;}//------生成一行黑白块(包含四个块,四个块里有随机个数的黑块)function createRow() {var row = document.createElement("div");//一行方块row.className = "row";//这行方块的类名叫rowvar init = generateInitialBlackIndices();//返回包含了随机生成的初始黑块索引的数组for (var i = 0; i < 4; i++) {//一行内的四个方块迭代var cell = document.createElement("div");//小方块cell.className = "cell";if (init.includes(i)) {// 是否为黑块索引cell.classList.add("cellblack");//是黑块索引,就变成黑块cell.addEventListener("click", clickBlackBlock);//点击黑块变白块blackBlocks.push(cell);//把黑块加到blackBlocks数组}row.appendChild(cell);//将创建的方块元素添加到当前行}return row;}//------生成所有黑白块function geneRows() {for (var i = 0; i < rowCount; i++) {container.appendChild(createRow());}console.log("已生成黑白块");}//------重置函数function resetGame() {// 清除容器中的所有方块元素container.innerHTML = '';score = 0;var diff = document.getElementById("difficulty");if (diff.value === "easy") {speed = 3;} else if (diff.value === "medium") {speed = 5;} else if (diff.value === "hard") {speed = 7;}console.log(speed);// 重新生成方块行geneRows();}//------开始游戏function startGame() {resetGame();// 将容器移动到初始位置container.style.top = initialTop + "px";//------方块下落、判断游戏结束function moveContainerDown() {// 获取当前容器的 top 值var top = parseInt(container.style.top) || initialTop;// 更新容器的 top 值,使容器向下移动container.style.top = top + speed + "px";//获取 main 的底部位置: main 元素顶部距离文档顶部的偏移量加上 main 元素自身的可见高var mainBottom = main.offsetTop + main.clientHeight;//遍历所有的黑块,任一黑块的底部>=main的底部,则游戏结束for (var i = 0; i < blackBlocks.length; i++) {if (blackBlocks[i].getBoundingClientRect().bottom >= mainBottom + 15) {//bla...tom 是黑块元素相对于浏览器窗口顶部的距离加上其自身的高度=黑块元素底部距离浏览器窗口顶部的距离//我也不知道为什么要+15,如果不+,那么黑块离底部还有一段距离的时候就会判断游戏结束gameOver();return; //结束函数,避免继续执行下面的代码}}}//一定要清除之前的定时器,否则速度会叠加,越来越快clearInterval(intervalID);//每隔20毫秒调用下落函数,实现容器持续向下移动intervalID = setInterval(moveContainerDown, 20);}//------游戏结束function gameOver() {gameStart = false;var restart = confirm("游戏结束!您的得分是:" + score + " 分。是否重新开始?");if (restart) {startGame();} else {alert("掰掰");}}});

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

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

相关文章

【开发问题记录】Nacos修改服务实例权重时报错

问题记录 一、问题描述1.1 产生原因1.2 产生问题 二、问题解决2.1 docker部署的nacos解决方案2.1.1 进入nacos容器2.1.2 查看当前目录2.1.3 进入data文件夹2.1.4 删除protocol文件2.2 本地部署的nacos 一、问题描述 1.1 产生原因 在运行项目时&#xff0c;在本地启动了一个服务…

vue3项目 使用 element-plus 中 el-collapse 折叠面板

最近接触拉了一个项目&#xff0c;使用到 element-plus 中 el-collapse 折叠面板&#xff0c;发现在使用中利用高官网多多少少的会出现问题。 &#xff08;1.直接默认一个展开值&#xff0c;发现时显时不显 2 . 数据渲染问题&#xff0c;接口请求了&#xff0c;页面数据不更新 …

js 截取指定字符后面/前面的所有字符串...

项目场景 在 JavaScript 中&#xff0c;你可以使用 substring() 或 substr() 方法来截取字符串中指定字符前面或后面的所有字符。 再配合**indexOf()**方法来判断字符所在的位置从而实现截取指定字符的前后字符串 解决方案&#xff1a; //js 截取指定字符后面/前面的所有字…

类激活映射详解

类激活映射&#xff08;CAM, Class Activation Mapping&#xff09;是一种常用于卷积神经网络&#xff08;CNN&#xff09;的技术&#xff0c;用来识别和解释模型在进行图像或时间序列分类任务时&#xff0c;哪些区域对最终分类决定起到了关键作用。下面&#xff0c;我将详细解…

大数据平台搭建2024(一)

一&#xff1a;基础配置 创建虚拟机并查出ip地址进行连接 ip a1.配置node01静态ip地址与主机名 vi /etc/sysconfig/network-scripts/ifcfg-ens33修改或添加如下内容&#xff1a; BOOTPROTO"static" ONBOOTyes #根据虚拟机网卡信息配置 IPADDR192.168.200.141 NET…

360度VR全景汽车漫游展示让爱车者能感受真实的驾驶体验

小米汽车的惊艳亮相&#xff0c;让无数爱车族心潮澎湃。然而&#xff0c;对于因时间和地理限制无法亲临现场的人来说&#xff0c;这份激动或许带有些许遗憾。如今&#xff0c;有了3D虚拟看车软件&#xff0c;这一切不再是问题。 web3D开发公司深圳华锐视点通过运用尖端的web3D开…

IntelliJ IDEA2024 安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 IDEA&#xff08;Integrated Development Environment for Apache&#xff09; 是一款专为 Apache 开发者设计的集成开发环境。该软件提供了丰富的功能和工具&#xff0c;帮助开发者更高效地创建、调试和部署 Apache 项目。 主…

hot100 -- 链表(中)

不要觉得力扣核心代码模式麻烦&#xff0c;它确实比不上ACM模式舒服&#xff0c;可以自己处理输入输出 只是你对 链表 和 return 的理解不到位 &#x1f442; ▶ 屿前世 (163.com) &#x1f442; ▶ see you tomorrow (163.com) 目录 &#x1f382;两数相加 &#x1f6a9;删…

python 绘制六种激活函数(sigmoid、tanh、relu、softmax、relu、elu)

1、效果 2、实现代码&#xff08;带注释&#xff09; import numpy as np # 导入 numpy 库, 用于数学运算 import matplotlib.pyplot as plt # 导入 matplotlib.pyplot, 用于绘图 import matplotlib as mpl # 导入 matplotlib 库, 用于图形配置plt.rcParams[font.sans-se…

mysql奇葩问题union

单独执行第一条&#xff0c;有三条结果&#xff1b; union之后&#xff0c;只有一条结果&#xff1b; union自动的把重复数据合并了&#xff1b;

使用Python生成100到算术题

需求描述&#xff1a;生成100道包含加法、减法、乘法、除法题目的数学题。 import random import pandas as pddef generate_math_questions(num_questions, question_types[addition, subtraction, multiplication, division], difficultyeasy, range_start1, range_end10):&…

Vue基础使用之V-Model绑定单选、复选、动态渲染选项的值

这里要说明一下&#xff0c;在v-model 绑定的值是id还是value是和<option>中的v-bind保持一致的&#xff0c;如第四个&#xff0c;如果是 <option :value"op[1]" 那v-model绑定的就是数组第二项的值2&#xff0c;4&#xff0c;6 如果是 <option :va…

《AI编程类工具之一——CodeArts Snap》

一.简介 CodeArts Snap是一款基于华为云研发的智能开发助手&#xff0c;它覆盖软件开发的全生命周期&#xff0c;提供端到端的智能支持。该工具的核心功能包括代码生成、研发知识问答、单元测试用例生成、代码解释、代码注释、代码翻译、代码调试以及代码检查等八大方面&#…

软件开发的20条原则

原则是工作的准则,代表了许多人从经验中总结出来的集体智慧 源自《软件开发的201个原则》 需求 需要明确 需求是什么?需求有具体文档记录吗?需求经过多方评审了吗?需求合理吗?需求投入产出比如何?原则46:避免再需求分析时进行系统设计 需求分析:定义系统/软件的黑盒行…

Arduino通过I2C驱动MT6701磁编码器并读取角度数据

Arduino通过I2C驱动MT6701磁编码器并读取角度数据 &#x1f4cd;相关篇《Arduino通过Wire库读取AS5600编码器数据》 ✨测试了使用STM32硬件I2C扫描其地址失败。使用软件I2C可以。 &#x1f4d1;MT6701&#xff08;基于差分霍尔的磁性角度传感器芯片&#xff09;芯片特性简介 &…

WPF中DataGrid主从数据(父子数据)展示

在wpf中可以使用DataGrid控件,进行主从数据展示,也称父子数据展示。下面展示纯原生控件编码实现功能(样式自己可以根据需求进行修改)。 效果如下: 点击图标,展开和收缩可以自由的切换,也可以自己重新写一个样式,比如+,-或者类似图标的样式,都是可以的。 1.首先创建一…

spispispi

SPI C.. & C.. logic是SPI的控制逻辑&#xff0c;芯片内部进行地址锁存、数据读写等操作&#xff0c;都是由控制逻辑自动完成。控制逻辑的左边是SPI的通信引脚&#xff0c;这些引脚和主控芯片相连&#xff0c;主控芯片通过SPI协议&#xff0c;把指令和数据发送给控制逻辑&a…

多线程传参以及线程的优缺点

进程是资源分配的基本单位 线程是调度的基本单位 笼统来说&#xff0c;线程有以下优点&#xff1a; 创建一个新线程的代价要比创建一个新进程小得多 与进程之间的切换相比&#xff0c;线程之间的切换需要操作系统做的工作要少很多 线程占用的资源要比进程少很多 能充分利用多…

leetcode1448.统计二叉树中的好节点数目

1. 题目描述 题目链接 2. 解题思路 首先看一下题目的“核心”&#xff0c;什么是好节点&#xff1a;从根到该节点 X 所经过的节点中&#xff0c;没有任何节点的值大于 X 的值。也就是说&#xff0c;我们只要知道了从根节点到该节点的所有的值&#xff0c;就可以判断该节点是…

Blender3.0 下载地址及安装教程

Blender是一款开源的3D计算机图形软件&#xff0c;广泛应用于动画制作、游戏开发、建模、渲染等领域。它提供了一套强大的工具和功能&#xff0c;让用户能够进行三维建模、动画制作和视觉效果的创作。 Blender支持多种文件格式的导入和导出&#xff0c;使用户能够与其他软件进…