本篇文章给大家带来的是原生JS实现小球碰到边界就反弹,点击小球时小球被会销毁,并重新创建一个小球,让小球的数量一直保持在初始的数量,按照思路按步骤进行讲解,只需要源码的小伙伴可以定位到文本末尾直接复制,当然大家可以进行改动优化成自己需要的效果

一、创建地图容器

  1. 代码比较简单,此部分就不在进行讲解,html 部分如下:

     <div class="container"></div>
    
  2. css 部分如下:

    <style>* {margin: 0;padding: 0;}body {display: flex;justify-content: center;align-items: center;}.container {position: relative;width: 80vw;height: 90vh;background-color: #3d4145;margin: 20px 0;}
    </style>
    

二、JS 代码逻辑实现——碰撞反弹

  1. 书写逻辑之前我们先看一下我们需要用到的工具函数:返回随机数的和利用随机数生成随机 rgba 颜色的工具函数,随机函数传入一个最大值和最小值,生成是随机整数就在这个区间内,至于随机数的实现原理这里我就不在过多赘述了,

    // 随机数方法
    function randomMath(min, max) {return Math.round(Math.random() * (max - min) + min)
    }// 创建随机颜色方法
    function randomColor() {const r = randomMath(0, 255)const g = randomMath(0, 255)const b = randomMath(0, 255)const color = `rgb(${r},${g},${b})`return color
    }
    
  2. 获取容器地图 dom 元素,并定义存储所有小球的数组列表

     // 获取容器const map = document.querySelector('.container')// 定义小球数组列表const ballList = []
    
  3. 定义创建小球的方法,并根据自己具体需要的小球数量,循环调用创建小球的函数方法来创建多个小球,并使用循环的遍历 i 值作为创建的小球自定义属性,创建好的小球记得加入到地图容器中

    // 初始化小球的数量
    for (let i = 0; i < 5; i++) {ballList.push(createBall(i))
    }// 创建小球的方法
    function createBall(i) {// 创建小球元素const ball = document.createElement('div')// 为小球设置自定义属性ball.setAttribute('data-index', i)// 调用方法定义小球的属性ballAttribute(ball)// 为小球添加点击消失事件ballClick(ball)// 将小球加入到地图map.appendChild(ball)// 将小球返回,用于添加进小球列表return ball
    }
    
  4. 解析定义小球属性的方法,本方法接收参数,参数传递的值即为创建的小球,利用随机生成颜色得到函数为小球设置背景颜色,因为小球时原型,需要保持宽高一致,所以使用随机数创建一个值用作小球的宽高,具体大小可以自己设置,并将 div 元素 border-radius 属性设置为50%,即可得到一个圆形,在 js 中 - 连接符需要改为驼峰命名,为小球添加绝对定位,添加绝对定位并设置 left 和 top 就可以定义小球的出现位置,使用 randonPos 生成随机坐标,randonPos 的讲解放在下一步

    // 定义小球的大小与定位属性
    function ballAttribute(element) {// 为小球添加颜色element.style.backgroundColor = randomColor()// 定义小球创建的大小const size = randomMath(30, 50)element.style.width = size + 'px'element.style.height = size + 'px'// 修改为圆形element.style.borderRadius = '50%'// 为创建的小球添加绝对定位element.style.position = 'absolute'// 为小球定义出现的位置element.style.left = randomPos(size).leftelement.style.top = randomPos(size).top
    }
    
  5. 解析 randonPos 生成随机坐标函数,坐标的最小距离应该不小于0,横向最大距离不大于容器最大宽度减去小球自身的大小,纵向距离不大于容器高度减去小球自身大小,又因为小球宽高一致,因此只获取小球宽度即可,如果不减去小球自身的大小,就会导致小球超出边界显示,通过次方法将得到最大的边界,利用随机函数返回的随机数,并将生成的随机数作为小球的初始坐标,offsetWidth 等方法本文不进行详解析,请自行查阅文档,使用容器

    // 随机坐标方法
    function randomPos(size) {// 地图边界最大值减去小球自身的大小即可获得最大坐标const width = map.offsetWidth - sizeconst height = map.offsetHeight - sizeconst left = randomMath(0, width) + 'px'const top = randomMath(0, height) + 'px'return { left, top }
    }
    
  6. 小球的点击消失事件在最后进行讲解,现在我们来看一下让小球移动的方法,在讲解移动方法之前,我们先来说一下小球碰撞反弹是如何实现的,假设地图容器宽度为 1000px,高度为 500px,小球自身大小为 50px,那么根据上述的解析,小球的横向移动距离最大不得超过 950px,纵向的移动距离最大不得超过 450px,现在小球的初始位置坐标 x 为 400px,y 为 200px,但看横向移动,如果小球的移动的距离等于 950px,是不是就代表触碰边界了,那么此时小球的移动方向就应该发生改变,也就是向右移动需要改为向左移动,设小球的移动横向移动速度为 5px,按照每 30 毫秒移动一次,那么就是小球的初始 x 坐标 400px 每 30 毫秒就增加 5px,等这个增加叠加到超过 950px时我们就需要反向移动,如何反向移动,向右移动我们是 +5px,那么向左 -5px 是不是就可以实现了,纵向移动同理,就不在重复叙述了,下面我们来看一下具体的代码实现

  7. 小球移动方法的实现,element 表示每个小球,小球的移动速度,应该各不相同,所以我们取最小速度为 1px,最大为 4px,分别定义横向和纵向的移动速度,各不相同实现不同的运动轨迹,初始化定义小球的移动方向设置为向右 right 和向下 down,小球触碰到边界即改变方向移动,即将 right 修改为 left ,将 down 修改为 up,这里最大移动距离如有不解请会看上一步或第五步的解析,让其 30 毫米即移动一次,具体时间可以修改

    // 让小球随机移动方法
    function randomMove(element) {// 设置 x 和 y 的移动速度let stepx = randomMath(1, 4)let stepy = randomMath(1, 4)// 球的移动方向let ballx = 'right'let bally = 'down'setInterval(() => {// 获取每个小球距离边界的距离let left = element.offsetLeftlet up = element.offsetTop// 根据小球的宽度获得小球的大小let size = element.offsetWidth// 判断球是否碰撞到边界,碰撞边界则改变方向移动if (left <= 0) {ballx = 'right'} else if (left >= map.offsetWidth - size) {ballx = 'left'}if (up <= 0) {bally = 'down'} else if (up >= map.offsetHeight - size) {bally = 'up'}// 小球的在 x 轴上的运动方向if (ballx == 'right') {left = left + stepx} else {left = left - stepx}element.style.left = left + 'px'// 小球的在 y 轴上的运动方向if (bally == 'down') {up = up + stepy} else {up = up - stepy}element.style.top = up + 'px'}, 30)
    }
    
  8. 在有了移动方法之后,我们可以利用循环的方式给每个小球绑定移动方法,还记得我们最开始定义存储小球的数组列表吗,遍历这个列表即可为每个小球进行绑定移动方法

    // 为每个小球添加随机移动方法
    for (let i = 0; i < ballList.length; i++) {// 遍历的每个元素则代表一个小球,将其传入移动方法即可randomMove(ballList[i])
    }
    
  9. 此时就可以实现小球的碰撞反弹了

三、JS 代码逻辑实现——点击消失

  1. 现在我们来讲解一下小球点击消失的方法,传入小球这个元素,绑定点击事件,在被点击的时候,获取被点击小球的自定义属性,通过这个自定义属性在存储所有小球数组列表列表中找到该小球在数组中的索引,findIndex 方法返回符合条件的第一个元素的索引值,具体用法请自行查阅,通过这个返回的索引值删除当前小球在数组中的位置,并调用创建小球的方法,来创建一个小球,同时传入刚刚被删除小球的索引,作为新创建小球的自定义属性,即可实现创建的小球自定义属性值不重复,保证每次点击都能销毁小球,同时创建小球的方法会返回创建的小球,可以利用这点,为创建的小球绑定移动方法

    // 小球点击事件
    function ballClick(element) {element.addEventListener('click', function () {// 获取当前被点击小球的自定义属性const index = this.getAttribute('data-index')// 遍历所有小球的自定义属性,获取当前在数组中的索引值const deleteIndex = ballList.findIndex(item => {return index === (item.getAttribute('data-index'))})// 根据索引删除小球在数组列表中的值ballList.splice(deleteIndex, 1)// 将当前被点击的小球从地图中销毁this.style.display = 'none'// 被删除的小球索引值,作为新创建小球的索引值randomMove(createBall(deleteIndex))})
    }
    
  2. 此时就完成了本案例的全局实现过程

四、本案例整体源码

  • 需要案例源码的直接复制如下代码即可

    <!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"><title>小球碰撞边界反弹-点击消失</title><style>* {margin: 0;padding: 0;}body {display: flex;justify-content: center;align-items: center;}.container {position: relative;width: 80vw;height: 90vh;background-color: #3d4145;margin: 20px 0;}</style>
    </head><body><div class="container"></div><script>// 获取容器const map = document.querySelector('.container')// 定义小球数组列表const ballList = []// 初始化小球的数量for (let i = 0; i < 5; i++) {ballList.push(createBall(i))}// 创建小球的方法function createBall(i) {// 创建小球元素const ball = document.createElement('div')// 为小球创建自定义属性ball.setAttribute('data-index', i)// 调用方法定义小球的属性ballAttribute(ball)// 为小球添加点击消失事件ballClick(ball)// 将小球加入到地图map.appendChild(ball)// 将小球返回,用于添加进小球列表return ball}// 小球点击事件function ballClick(element) {element.addEventListener('click', function () {// 获取当前被点击小球的自定义属性const index = this.getAttribute('data-index')// 遍历所有小球的自定义属性,获取当前在数组中的索引值const deleteIndex = ballList.findIndex(item => {return index === (item.getAttribute('data-index'))})// 根据索引删除小球在数组列表中的值ballList.splice(deleteIndex, 1)// 将当前被点击的小球从地图中销毁this.style.display = 'none'// 被删除的小球索引值,作为新创建小球的索引值randomMove(createBall(deleteIndex))})}// 定义小球的大小与定位属性function ballAttribute(element) {// 为小球添加颜色element.style.backgroundColor = randomColor()// 定义小球创建的大小const size = randomMath(30, 50)element.style.width = size + 'px'element.style.height = size + 'px'// 修改为圆形element.style.borderRadius = '50%'// 为创建的小球添加绝对定位element.style.position = 'absolute'// 为小球定义出现的位置element.style.left = randomPos(size).leftelement.style.top = randomPos(size).top}// 随机坐标方法function randomPos(size) {// 地图边界最大值减去小球自身的大小即可获得最大坐标const width = map.offsetWidth - sizeconst height = map.offsetHeight - sizeconst left = randomMath(0, width) + 'px'const top = randomMath(0, height) + 'px'return { left, top }}// 为每个小球添加随机移动方法for (let i = 0; i < ballList.length; i++) {randomMove(ballList[i])}// 让小球随机移动方法function randomMove(element) {// 设置 x 和 y 的移动速度let stepx = randomMath(1, 4)let stepy = randomMath(1, 4)// 球的移动方向let ballx = 'right'let bally = 'down'setInterval(() => {// 获取每个小球距离边界的距离let left = element.offsetLeftlet up = element.offsetTop// 根据小球的宽度获得小球的大小let size = element.offsetWidth// 判断球是否碰撞到边界,碰撞边界则改变方向移动if (left <= 0) {ballx = 'right'} else if (left >= (map.offsetWidth - size)) {ballx = 'left'}if (up <= 0) {bally = 'down'} else if (up >= (map.offsetHeight - size)) {bally = 'up'}// 小球的在 x 轴上的运动方向if (ballx == 'right') {left = left + stepx} else {left = left - stepx}element.style.left = left + 'px'// 小球的在 y 轴上的运动方向if (bally == 'down') {up = up + stepy} else {up = up - stepy}element.style.top = up + 'px'}, 30);}// 创建随机颜色方法function randomColor() {const r = randomMath(0, 255);const g = randomMath(0, 255);const b = randomMath(0, 255);const color = `rgb(${r},${g},${b})`;return color}// 随机数方法function randomMath(min, max) {return Math.round(Math.random() * (max - min) + min);}</script>
    </body></html>
    

JS实现小球碰撞边界反弹-点击消失(详细解析实现思路)相关推荐

  1. 你知道动态IP和静态IP的真正区别吗?点击查看详细解析!

    一.动态IP和静态IP的基本概念 二.动态IP和静态IP的区别 三.动态IP和静态IP各自的优势 四.动态IP和静态IP的应用场景 五.总结 Aorta Cloud 厦门主动脉云科技 一.动态IP和静 ...

  2. Canvas+Js制作动量守恒的小球碰撞

    目的:通过js实现小球碰撞并实现动量守恒 canvas我们就不多说了,有用着呢. 我们可以通过canvas画2D图形(圆.方块.三角形等等)3D图形(球体.正方体等待). 当然这只是基础的皮毛而已,c ...

  3. css动画-小球撞壁反弹

    小球碰到一面壁之后一般都会反弹,反射角=入射角: 其实用css3来实现这个效果也非常简单. 首先,分解一下小球的运动:水平运动和垂直运动. 当小球往右下方向运动时,如果碰到了下面的壁,那么由于碰撞,小 ...

  4. js 小球碰壁反弹and小球碰撞

    好像好几天没有更博了呢,最近有点变懒了,这样不好,不好~~我们要做热爱学习的好孩子,嘻嘻,今天下午补上... 我们在学习js的时候,一个很经典的案例就是小球的碰壁反弹效果啦~简单的小球碰壁效果可以慢慢 ...

  5. Java反弹球两球相撞_java实现小球碰撞反弹

    java实现小球碰撞反弹 java实现小球碰撞反弹 首先我们要在一个窗口里面显示这个功能,因此引入JFrame类然后创建一个窗口代码如下: JFrame win=new JFrame();//新建窗口 ...

  6. js小球碰撞js特效

    下载地址 小球碰撞特效.引用test.js文件.我目前做的是10个小球同时出现,你也可以根据你的需要进行修改.如果你想要小球随机出现的话,你只需要把58行的代码解注,然后57行的注释就行了.这个写法还 ...

  7. js实现多个小球碰撞

    实现思路:小球的移动,是通过改变小球的left和top值来改变,坐标分别为(x,y)当x/y值加到最大,即加到父级的宽度或者高度时,使x值或者y值减小,同理当x值或者y值减到最小时,同样的使x值或者y ...

  8. html5使用canvas实现小球碰撞反弹实例

    使用 html5 中的 canvas, 实现小球相互碰撞并反弹,反弹算法比较简单. index.html <!DOCTYPE html> <html lang="en&qu ...

  9. js运动小球碰壁反弹

    js运动小球碰壁反弹 1.触碰窗口壁沿反弹,同时改变颜色 <!DOCTYPE html> <html lang="en"><head><m ...

最新文章

  1. 2个td合成一个td_18个月16个爆款,合成类玩法的下一个机会在哪?
  2. leecode-8字符串转化为整数C版
  3. 零基础转行web前端,如何高效的去学习web前端?
  4. Microsoft SQL Server数据库部署过程
  5. 如何判断一家公司靠不靠谱?
  6. 903计算机技术综合基础,北大903计算机技术综合基础考研真题、资料、参考书
  7. python列表(list)和元组(tuple)之间的转换
  8. 程序的内存分配----变量在可执行文件中的内存区分配
  9. Java消息盒子实现性能,Python高级进阶#007 pyqt5消息盒子QMessageBox
  10. BlowFish算法Java实现
  11. Android| failed to connect to /10.0.2.2 (port 80) after 10000ms
  12. python3绘制超立方体
  13. Ubuntu Server 20.04 下 HustOJ 安装
  14. 一文详解SQL关联子查询
  15. 鸿蒙系统没有录屏,这15+项高效又实用的功能更新,一定别错过!
  16. 大尺寸图片的性能和内存优化
  17. 电机学他励直流发电机matlab,基于Matlab并励直流发电机的自励过程分析
  18. Python爬虫实战: 爬取网易云歌单
  19. EXCEL——VLOOKUP双条件匹配
  20. 微信小程序用canvasToTempFilePath压缩图片,开发工具压缩正常而真机上比例失调

热门文章

  1. 计算机二级 sql,全国计算机二级(vf)sql命令
  2. Shell脚本实现 ping功能
  3. virtualbox/vbox硬件级虚拟机系统 去虚拟化 批量启动克隆修改信息工具 超能版
  4. 腾讯地图行政区划接口调用
  5. 大数据技术原理与应用—课后题答案(第一章)
  6. 2018年华为杯研究生数学建模竞赛
  7. Docker中安装python-pcl库
  8. Linux服务器安装matlab
  9. MySQL系列3—标准SQL语言
  10. 2022——寒假总结