css+js完成黑洞吞噬小球成长功能

2023-11-07 16:59

本文主要是介绍css+js完成黑洞吞噬小球成长功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 介绍
  • 原理
  • 完整代码
  • 总结

介绍

因为最近比较闲,就想着能不能自己做个h5游戏出来,所以先做个小东西试试手,既然要做游戏当然就要涉及到很多的运动轨迹以及碰撞后事件效果等问题,所以就做了这个小demo出来

原理

说起来原理其实也很简单的,想做一个黑洞吞噬效果的话首先我们至少需要两个物体

  • 黑洞
    这个的话比较简单,其实就是往中间放一个黑色的小球而已,可以根据我们需要稍微做一点样式上的优化
<style>#blackhole {width: 40px;height: 40px;background: radial-gradient(black, transparent, transparent);/* radial-gradient是渐变色方法的一种使用三个颜色作为渐变可以直接使用transparent设置透明色这样就可以得到一个带有散射效果的黑色小球 */position: absolute;left: calc(50% - 20px);top: calc(50% - 20px);}
</style>
<div id="blackhole"></div>

喏,大概就长这个样子
在这里插入图片描述

  • 小球
    小球的话可能稍微复杂一些,我这里是通过鼠标点击然后在鼠标点击位置生成一个红色小球,然后这个小球会在创建好之后向着黑洞的位置移动,代码如下
<style>
.block {width: 30px;height: 30px;position: absolute;background: radial-gradient(red, transparent, transparent);border-radius: 10px;
}
</style>
<body id="body">
</body>
<script>
/* 通过tagname直接获取body有点问题
所以选择添加id后通过byId方式获取dom元素 */
let body = document.getElementById('body')
body.addEventListener('click',e=>{let a = document.createElement('div')a.className = 'block'body.appendChild(a)
}
</script>

这部分代码很好理解,就是在点击body时创建一个红色的小球然后添加进body,接下来的话再对小球的位置进行修正

body.addEventListener('click',e=>{let a = document.createElement('div')a.className = 'block'//首先获取到鼠标点击时的坐标位置let x = e.clientXlet y = e.clientY/* 因为小球本身时带有高度和宽度的所以在进行位置判断的时候需要先减去小球宽高的一半 */let ballX = x - 10let ballY = y - 10a.style.left = ballX + 'px'a.style.top = ballY + 'px'body.appendChild(a)
}

现在小球已经有了,位置也对了,接下来就要让小球动起来了,小球运动的话就需要进行刷新了,也就是说我们需要用到 setInterval() 这个方法来进行小球位置的刷新,刷新频率的话一般30ms就够了,大家都知道运动距离等于运动速度乘以运动时间,运动速度可以理解为单位事件内运动的距离,现在刷新事件已经有了,也就是30ms 所以只需要再设定一个单位距离作为速度即可。

/* 在上边我把黑洞的位置设到了屏幕正中心
所以小球的运动轨迹应该是向着正中心位置偏移 */
let h = window.innerHeight
let w = window.innerWidth
/* 速度的生成建议通过下边这种方式来进行生成
这样生成的速度本身是带有正负的
所以就不需要判断点击时小球是在中心点之上还是之下了 */
let speedX = (x - w/2)/30
let speedY = (y - h/2)/30
body.appendChild(a)
a.style.left = ballX + 'px'
a.style.top = ballY + 'px'
let itv = setInterval(()=>{//每30ms刷新一次位置ballY -= speedYballX -= speedXa.style.left = ballX + 'px'a.style.top = ballY + 'px'
},30)

现在小球的运动已经完成了,但是还有一个问题,小球在运动到黑洞位置时不会消失,还会一直运动直到飞出屏幕之外(因为body设置了overflow:hidden属性,所以看不到了,但其实还在),所以接下来需要做一个判断,在小球运动到黑洞位置时让它消失

/* 这几行代码建议放在点击事件之外
因为他们本身不需要频繁创建
可以节省开销 */
let b = document.getElementById('blackhole')
let bw = b.clientHeight
let bh = b.clientWidth
let bt = b.offsetTop
let bl = b.offsetLeft
/* 这里的判断条件看起来很复杂,稍微解释一下
因为小球本身是基于中心点运动的
而且因为小数点等问题的缘故也是无法直接让小球坐标等于中心点的
所以应该是在小球运动到某一区间值时进行操作
小球的left应该介于黑洞的左右边界之间,即
ballX < (bl + bw - 20) && ballX > (bl - 10)
top介于黑洞的上下边界之间
ballY < (bt + bh - 20) && ballY >  (bt - 10) */
if((ballX < (bl + bw - 20) && ballX > (bl - 10))&&
(ballY < (bt + bh - 20) && ballY >  (bt - 10))){clearInterval(itv) //清除计时器body.removeChild(a)
}

现在小球已经可以到达指定位置,然后消失了,但是距离我们想要的效果还差那么一点点,我们还要黑洞会随着吞噬小球的多少而进行成长

//首先,在最外部声明一个小球成长比例的参数
let p = 1
//然后在小球碰撞到黑洞后,调整黑洞的大小及位置
p += 0.1
b.style.width = bw * p + 'px'
b.style.height = bh * p + 'px'
b.style.top = 'calc(50% - '+ bh * p/2 +'px)'
b.style.left = 'calc(50% - '+ bw * p/2 +'px)'

OK,大功告成
在这里插入图片描述

完整代码

<style type="text/css">body, html{height: 100%;width: 100%;margin: 0;overflow: hidden;}.block {width: 30px;height: 30px;position: absolute;background: radial-gradient(red, transparent, transparent);border-radius: 10px;}#blackhole {width: 40px;height: 40px;background: radial-gradient(black, transparent, transparent);position: absolute;left: calc(50% - 20px); top: calc(50% - 20px);}
</style>
<body id="body"><div class="blackhole" id="blackhole"></div><script type="text/javascript">let body = document.getElementById('body')let b = document.getElementById('blackhole')let h = window.innerHeightlet w = window.innerWidthlet bw = b.clientHeightlet bh = b.clientWidthlet bt = b.offsetToplet bl = b.offsetLeftlet p = 1body.addEventListener('click',e=>{let a = document.createElement('div')a.className = 'block'let x = e.clientXlet y = e.clientYlet ballX = x - 10let ballY = y - 10let speedX = (x - w/2)/30 //每次运动点击位置到中心点的1/30距离let speedY = (y - h/2)/30body.appendChild(a)a.style.left = ballX + 'px'a.style.top = ballY + 'px'let itv = setInterval(()=>{//每30ms刷新一次位置ballY -= speedYballX -= speedXa.style.left = ballX + 'px'a.style.top = ballY + 'px'if((ballX < (bl + bw - 20) && ballX > (bl - 10))&&(ballY < (bt + bh - 20) && ballY >  (bt - 10))){clearInterval(itv)body.removeChild(a)p += 0.1b.style.width = bw * p + 'px'b.style.height = bh * p + 'px'b.style.top = 'calc(50% - '+ bh * p/2 +'px)'b.style.left = 'calc(50% - '+ bw * p/2 +'px)'}},30)})</script>
</body>
w * p + 'px'b.style.height = bh * p + 'px'b.style.top = 'calc(50% - '+ bh * p/2 +'px)'b.style.left = 'calc(50% - '+ bw * p/2 +'px)'}},30)})</script>
</body>

总结

相对来说,整个制作都是很简单的,但是也稍微有了那么一点游戏的意思,代码本身并不难重点还是需要搞清楚自己的思路吧

这篇关于css+js完成黑洞吞噬小球成长功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/365026

相关文章

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Vue3绑定props默认值问题

《Vue3绑定props默认值问题》使用Vue3的defineProps配合TypeScript的interface定义props类型,并通过withDefaults设置默认值,使组件能安全访问传入的... 目录前言步骤步骤1:使用 defineProps 定义 Props步骤2:设置默认值总结前言使用T

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转

基于Java和FFmpeg实现视频压缩和剪辑功能

《基于Java和FFmpeg实现视频压缩和剪辑功能》在视频处理开发中,压缩和剪辑是常见的需求,本文将介绍如何使用Java结合FFmpeg实现视频压缩和剪辑功能,同时去除数据库操作,仅专注于视频处理,需... 目录引言1. 环境准备1.1 项目依赖1.2 安装 FFmpeg2. 视频压缩功能实现2.1 主要功

使用Python实现无损放大图片功能

《使用Python实现无损放大图片功能》本文介绍了如何使用Python的Pillow库进行无损图片放大,区分了JPEG和PNG格式在放大过程中的特点,并给出了示例代码,JPEG格式可能受压缩影响,需先... 目录一、什么是无损放大?二、实现方法步骤1:读取图片步骤2:无损放大图片步骤3:保存图片三、示php

深度解析Python yfinance的核心功能和高级用法

《深度解析Pythonyfinance的核心功能和高级用法》yfinance是一个功能强大且易于使用的Python库,用于从YahooFinance获取金融数据,本教程将深入探讨yfinance的核... 目录yfinance 深度解析教程 (python)1. 简介与安装1.1 什么是 yfinance?