原生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 相关文章推荐
JS 文件大小判断的实现代码
Apr 07 Javascript
javascript下利用arguments实现string.format函数
Aug 24 Javascript
JQuery 操作/获取table具体代码
Jun 13 Javascript
jQuery使用toggleClass方法动态添加删除Class样式的方法
Mar 26 Javascript
再谈javascript注入 黑客必备!
Sep 14 Javascript
原生ajax处理json格式数据的实例代码
Dec 25 Javascript
ES6中Proxy代理用法实例浅析
Apr 06 Javascript
Node.js+ELK日志规范的实现
May 23 Javascript
ES6 Array常用扩展的应用实例分析
Jun 26 Javascript
详解JavaScript类型判断的四种方法
Oct 21 Javascript
微信小程序将页面按钮悬浮固定在底部的实现代码
Oct 29 Javascript
Vant Weapp组件踩坑:picker的初始赋值解决
Nov 12 Javascript
浅析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
ThinkPHP模板中数组循环实例
2014/10/30 PHP
php获取文件后缀的9种方法
2016/03/22 PHP
PHP基于自增数据如何生成不重复的随机数示例
2017/05/19 PHP
PHP基于DateTime类解决Unix时间戳与日期互转问题【针对1970年前及2038年后时间戳】
2018/06/13 PHP
php多进程应用场景实例详解
2019/07/22 PHP
JavaScript 小型打飞机游戏实现原理说明
2010/10/28 Javascript
JS实现随机数生成算法示例代码
2013/08/08 Javascript
jQuery CSS()方法改变现有的CSS样式表
2014/09/09 Javascript
node.js集成百度UE编辑器
2015/02/05 Javascript
JS+CSS实现的日本门户网站经典选项卡导航效果
2015/09/27 Javascript
Bootstrap每天必学之下拉菜单
2015/11/25 Javascript
js智能获取浏览器版本UA信息的方法
2016/08/08 Javascript
js获取form表单所有数据的简单方法
2016/08/18 Javascript
js 获取图像缩放后的实际宽高,位置等信息
2017/03/07 Javascript
详解Vue 2.0封装axios笔记
2017/06/22 Javascript
使用Vue完成一个简单的todolist的方法
2017/12/01 Javascript
使用jQuery mobile NuGet让你的网站在移动设备上同样精彩
2019/06/18 jQuery
Openlayers显示瓦片网格信息的方法
2020/09/28 Javascript
python实现的一个p2p文件传输实例
2014/06/04 Python
python实现多线程抓取知乎用户
2016/12/12 Python
浅谈Python由__dict__和dir()引发的一些思考
2017/10/30 Python
Python 中的Selenium异常处理实例代码
2018/05/03 Python
python获取时间及时间格式转换问题实例代码详解
2018/12/06 Python
基于Python对数据shape的常见操作详解
2018/12/25 Python
Python中时间datetime的处理与转换用法总结
2019/02/18 Python
Python3解释器知识点总结
2019/02/19 Python
python ddt数据驱动最简实例代码
2019/02/22 Python
python基于json文件实现的gearman任务自动重启代码实例
2019/08/13 Python
Python基本语法之运算符功能与用法详解
2019/10/22 Python
英国领先的电子、技术和办公用品购物网站:Ebuyer
2018/04/04 全球购物
《真想变成大大的荷叶》教学反思
2014/04/14 职场文书
整顿机关作风心得体会
2014/09/10 职场文书
群众路线教育实践活动实施方案
2014/10/31 职场文书
二年级作文之动物作文
2019/11/13 职场文书
uniapp开发小程序的经验总结
2021/04/08 Javascript
css3新特性的应用示例分析
2022/03/16 HTML / CSS