原生JS实现多个小球碰撞反弹效果示例


Posted in Javascript onJanuary 31, 2018

本文实例讲述了原生JS实现多个小球碰撞反弹效果。分享给大家供大家参考,具体如下:

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

小球与小球之间的碰撞,要判断小球在被撞小球的哪个方向,从而判断小球该向哪个方向移动,同样的改变小球的坐标值,来实现小球的反弹

实现代码:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>小球碰撞</title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
      #wrap {
        height: 800px;
        width: 1300px;
        border: 1px solid red;
        /*小球设置相对定位*/
        position: relative;
        margin: 0 auto;
        overflow: hidden;
      }
      p {
        width: 40px;
        height: 40px;
        border-radius: 50%;
        background-color: red;
        position: absolute;
        top: 0;
        left: 0;
        color: white;
        font-size: 25px;
        text-align: center;
        line-height: 40px;
      }
    </style>
  </head>
  <body>
    <div id="wrap">
    </div>
  </body>
  <!--<script src="js/common.js" type="text/javascript" charset="utf-8"></script>-->
  <script type="text/javascript">
    /**
     * 生成并返回一个从m到n全区间的随机数
     * @param {Object} m
     * @param {Object} n
     */
    function randomNum(m, n) {
      return Math.floor(Math.random() * (n - m + 1) + m);
    }
    /**
     * 生成一个随机颜色,并返回rgb字符串值
     */
    function randomColor() {
      var r = randomNum(0, 255);
      var g = randomNum(0, 255);
      var b = randomNum(0, 255);
      return "rgb(" + r + "," + g + "," + b + ")";
    }
    //获得wrapDiv
    var wrapDiv = document.getElementById("wrap");
    //定义数组存储所有的小球
    var balls = [];
    //生成小球函数
    function createBalls() {
      for (var i = 0; i < 20; i++) {
        var ball = document.createElement("p");
        //随机小球起始的X坐标和小球的Y坐标
        ball.x = randomNum(0, 1200);
        ball.y = randomNum(0, 700);
        //随机小球的移动速度
        ball.speed = randomNum(2, 5);
        //随机小球移动的方向
        if (Math.random() - 0.5 > 0) {
          ball.xflag = true;
        } else {
          ball.xflag = false;
        }
        if (Math.random() - 0.5 > 0) {
          ball.yflag = true;
        } else {
          ball.yflag = false;
        }
        //随机小球的背景颜色
        ball.style.backgroundColor = randomColor();
        ball.innerHTML = i + 1;
        //将小球插入当wrapDiv中
        wrapDiv.appendChild(ball);
        //将所有的小球存储到数组中
        balls.push(ball);
      }
    }
    createBalls();
    //小球移动函数,判断小球的位置
    function moveBalls(ballObj) {
      setInterval(function() {
        ballObj.style.top = ballObj.y + "px";
        ballObj.style.left = ballObj.x + "px";
        //判断小球的标志量,对小球作出相应操作
        if (ballObj.yflag) {
          //小球向下移动
          ballObj.y += ballObj.speed;
          if (ballObj.y >= 800 - ballObj.offsetWidth) {
            ballObj.y = 800 - ballObj.offsetWidth;
            ballObj.yflag = false;
          }
        } else {
          //小球向上移动
          ballObj.y -= ballObj.speed;
          if (ballObj.y <= 0) {
            ballObj.y = 0;
            ballObj.yflag = true;
          }
        }
        if (ballObj.xflag) {
          //小球向右移动
          ballObj.x += ballObj.speed;
          if (ballObj.x >= 1300 - ballObj.offsetHeight) {
            ballObj.x = 1300 - ballObj.offsetHeight;
            ballObj.xflag = false;
          }
        } else {
          //小球向左移动
          ballObj.x -= ballObj.speed;
          if (ballObj.x <= 0) {
            ballObj.x = 0;
            ballObj.xflag = true;
          }
        }
        crash(ballObj);
      }, 10);
    }
    var x1, y1, x2, y2;
    //碰撞函数
    function crash(ballObj) {
      //通过传过来的小球对象来获取小球的X坐标和Y坐标
      x1 = ballObj.x;
      y1 = ballObj.y;
      for (var i = 0; i < balls.length; i++) {
        //确保不和自己对比
        if (ballObj != balls[i]) {
          x2 = balls[i].x;
          y2 = balls[i].y;
          //判断位置的平方和小球的圆心坐标的关系
          if (Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2) + 800 <= Math.pow(ballObj.offsetWidth + balls[i].offsetWidth, 2)) {
            //判断传过来的小球对象,相对于碰撞小球的哪个方位
            if (ballObj.x < balls[i].x) {
              if (ballObj.y < balls[i].y) {
                //小球对象在被碰小球的左上角
                ballObj.yflag = false;
                ballObj.xflag = false;
              } else if (ballObj.y > balls[i].y) {
                //小球对象在被碰小球的左下角
                ballObj.xflag = false;
                ballObj.yflag = true;
              } else {
                //小球对象在被撞小球的正左方
                ballObj.xflag = false;
              }
            } else if (ballObj.x > balls[i].x) {
              if (ballObj.y < balls[i].y) {
                //小球对象在被碰撞小球的右上方
                ballObj.yflag = false;
                ballObj.xflag = true;
              } else if (ballObj.y > balls[i].y) {
                //小球对象在被碰撞小球的右下方
                ballObj.xflag = true;
                ballObj.yflag = true;
              } else {
                //小球对象在被撞小球的正右方
                ballObj.xflag = true;
              }
            } else if (ballObj.y > balls[i].y) {
              //小球对象在被撞小球的正下方
              ballObj.yflag = true;
            } else if (ballObj.y < balls[i].y) {
              //小球对象在被撞小球的正上方
              ballObj.yflag = false;
            }
          }
        }
      }
    }
    for (var i = 0; i < balls.length; i++) {
      //将所有的小球传到函数中,来实现对小球的移动
      moveBalls(balls[i]);
    }
  </script>
</html>

运行效果:

原生JS实现多个小球碰撞反弹效果示例

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
JSQL SQLProxy 的 php 版本代码
May 05 Javascript
如何制作浮动广告 JavaScript制作浮动广告代码
Dec 30 Javascript
innerHTML,outerHTML,innerText,outerText的用法及区别解析
Dec 16 Javascript
jquery ajax请求方式与提示用户正在处理请稍等
Sep 01 Javascript
jQuery实现Meizu魅族官方网站的导航菜单效果
Sep 14 Javascript
浅谈JS的基础类型与引用类型
Sep 13 Javascript
bootstrap中日历范围选择插件daterangepicker的使用详解
Apr 17 Javascript
如何在Vue.js中实现标签页组件详解
Jan 02 Javascript
Vue插槽原理与用法详解
Mar 05 Javascript
详解es6新增数组方法简便了哪些操作
May 09 Javascript
vue项目中使用eslint+prettier规范与检查代码的方法
Jan 16 Javascript
Vue的生命周期一起来看看
Feb 24 Vue.js
浅析Angular19 自定义表单控件
Jan 31 #Javascript
JavaScript实现计算多边形质心的方法示例
Jan 31 #Javascript
微信小程序switch开关选择器使用详解
Jan 31 #Javascript
详解Angular调试技巧之报错404(not found)
Jan 31 #Javascript
微信小程序slider组件使用详解
Jan 31 #Javascript
vue项目实现记住密码到cookie功能示例(附源码)
Jan 31 #Javascript
AngularJS 将再发布一个重要版本 然后进入长期支持阶段
Jan 31 #Javascript
You might like
php实现查询功能(数据访问)
2017/05/23 PHP
jscript之List Excel Color Values
2007/06/13 Javascript
页面调用单个swf文件,嵌套出多个方法。
2011/11/21 Javascript
js/jquery获取浏览器窗口可视区域高度和宽度以及滚动条高度实现代码
2012/12/17 Javascript
12种不宜使用的Javascript语法整理
2013/11/04 Javascript
JavaScript中使用ActiveXObject操作本地文件夹的方法
2014/03/28 Javascript
JavaScript中的this关键字使用方法总结
2015/03/13 Javascript
JS中完美兼容各大浏览器的scrolltop方法
2015/04/17 Javascript
js实现具有高亮显示效果的多级菜单代码
2015/09/01 Javascript
JavaScript中setter和getter方法介绍
2016/07/11 Javascript
微信小程序 picker-view 组件详解及简单实例
2017/01/10 Javascript
JS实现移动端整屏滑动的实例代码
2017/11/10 Javascript
微信小程序之圆形进度条实现思路
2018/02/22 Javascript
浅谈Vue 性能优化之深挖数组
2018/12/11 Javascript
vue父组件给子组件的组件传值provide inject的方法
2019/10/23 Javascript
python通过shutil实现快速文件复制的方法
2015/03/14 Python
python实现字符串加密 生成唯一固定长度字符串
2019/03/22 Python
python定时复制远程文件夹中所有文件
2019/04/30 Python
Python实现计算文件MD5和SHA1的方法示例
2019/06/11 Python
python模拟菜刀反弹shell绕过限制【推荐】
2019/06/25 Python
Django用户认证系统 Web请求中的认证解析
2019/08/02 Python
Python 解码Base64 得到码流格式文本实例
2020/01/09 Python
在python tkinter界面中添加按钮的实例
2020/03/04 Python
基于matplotlib xticks用法详解
2020/04/16 Python
简单了解如何封装自己的Python包
2020/07/08 Python
Python局部变量与全局变量区别原理解析
2020/07/14 Python
详解Python之Scrapy爬虫教程NBA球员数据存放到Mysql数据库
2021/01/24 Python
css图标制作教程制作云图标
2014/01/19 HTML / CSS
黑猩猩商店:The Chimp Store
2020/02/12 全球购物
Java里面StringBuilder和StringBuffer有什么区别
2016/06/06 面试题
道路施工安全责任书
2014/07/24 职场文书
小学生五年级大队长竞选发言稿
2014/09/12 职场文书
学校党委干部个人对照检查材料思想汇报
2014/10/09 职场文书
学生会副主席竞选稿
2015/11/19 职场文书
餐饮行业关注的9大营销策略
2019/08/26 职场文书
redis 查看所有的key方式
2021/05/07 Redis