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将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

在React中引入Tailwind CSS的完整指南

《在React中引入TailwindCSS的完整指南》在现代前端开发中,使用UI库可以显著提高开发效率,TailwindCSS是一个功能类优先的CSS框架,本文将详细介绍如何在Reac... 目录前言一、Tailwind css 简介二、创建 React 项目使用 Create React App 创建项目

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

SpringKafka消息发布之KafkaTemplate与事务支持功能

《SpringKafka消息发布之KafkaTemplate与事务支持功能》通过本文介绍的基本用法、序列化选项、事务支持、错误处理和性能优化技术,开发者可以构建高效可靠的Kafka消息发布系统,事务支... 目录引言一、KafkaTemplate基础二、消息序列化三、事务支持机制四、错误处理与重试五、性能优

SpringIntegration消息路由之Router的条件路由与过滤功能

《SpringIntegration消息路由之Router的条件路由与过滤功能》本文详细介绍了Router的基础概念、条件路由实现、基于消息头的路由、动态路由与路由表、消息过滤与选择性路由以及错误处理... 目录引言一、Router基础概念二、条件路由实现三、基于消息头的路由四、动态路由与路由表五、消息过滤

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

基于SpringBoot实现文件秒传功能

《基于SpringBoot实现文件秒传功能》在开发Web应用时,文件上传是一个常见需求,然而,当用户需要上传大文件或相同文件多次时,会造成带宽浪费和服务器存储冗余,此时可以使用文件秒传技术通过识别重复... 目录前言文件秒传原理代码实现1. 创建项目基础结构2. 创建上传存储代码3. 创建Result类4.

Python+PyQt5实现多屏幕协同播放功能

《Python+PyQt5实现多屏幕协同播放功能》在现代会议展示、数字广告、展览展示等场景中,多屏幕协同播放已成为刚需,下面我们就来看看如何利用Python和PyQt5开发一套功能强大的跨屏播控系统吧... 目录一、项目概述:突破传统播放限制二、核心技术解析2.1 多屏管理机制2.2 播放引擎设计2.3 专