原生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 相关文章推荐
JavaScript 格式字符串的应用
Mar 29 Javascript
qTip2 精致的基于jQuery提示信息插件
Feb 17 Javascript
javascript限制文本框只允许输入数字(曾经与现在的方法对比)
Jan 18 Javascript
IE8下jQuery改变png图片透明度时出现的黑边
Aug 30 Javascript
javascript实现对表格元素进行排序操作
Nov 18 Javascript
js轮盘抽奖实例分析
Apr 17 Javascript
AngularJS的脏检查深入分析
Apr 22 Javascript
Angular 1.x个人使用的经验小结
Jul 19 Javascript
React应用中使用Bootstrap的方法
Aug 15 Javascript
浅谈Node.js之异步流控制
Oct 25 Javascript
js针对图片加载失败的处理方法分析
Aug 24 Javascript
vue vantUI tab切换时 list组件不触发load事件的问题及解决方法
Feb 14 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
给初学PHP的5个入手程序
2006/11/23 PHP
PHP eval函数使用介绍
2013/12/08 PHP
PHP不使用递归的无限级分类简单实例
2016/11/05 PHP
PHP中时间加减函数strtotime用法分析
2017/04/26 PHP
javascript奇异的arguments分析
2010/10/20 Javascript
IE6、IE7中获取Button元素的值的bug说明
2011/08/28 Javascript
很好用的js日历算法详细代码
2013/03/07 Javascript
使用jQuery简单实现模拟浏览器搜索功能
2014/12/21 Javascript
使用jspdf生成pdf报表
2015/07/03 Javascript
freemarker判断对象是否为空的方法
2015/08/13 Javascript
js纯数字逐一停止显示效果的实现代码
2016/03/16 Javascript
json对象转为字符串,当做参数传递时加密解密的实现方法
2016/06/29 Javascript
Json按某个键的值进行排序
2016/12/22 Javascript
AngularJS全局警告框实现方法示例
2017/05/18 Javascript
Express系列之multer上传的使用
2017/10/27 Javascript
React如何避免重渲染
2018/04/10 Javascript
[02:43]DOTA2英雄基础教程 圣堂刺客
2013/12/09 DOTA
django静态文件加载的方法
2018/05/20 Python
Python3实现的反转单链表算法示例
2019/03/08 Python
python实现批量处理将图片粘贴到另一张图片上并保存
2019/12/12 Python
解决TensorFlow训练内存不断增长,进程被杀死问题
2020/02/05 Python
Python sublime安装及配置过程详解
2020/06/29 Python
python实现scrapy爬虫每天定时抓取数据的示例代码
2021/01/27 Python
俄罗斯便宜的在线服装商店:GroupPrice
2020/04/10 全球购物
优秀的计算机专业求职信范文
2013/12/27 职场文书
高中同学聚会邀请函
2014/01/11 职场文书
大学生社会实践评语
2014/04/25 职场文书
企业活动策划方案
2014/06/02 职场文书
售房协议书范本2014
2014/10/23 职场文书
大学生暑期社会实践证明范本
2014/10/24 职场文书
写给医生的感谢信
2015/01/22 职场文书
个园导游词
2015/02/04 职场文书
2021-4-5课程——SQL Server查询【3】
2021/04/05 SQL Server
Android自定义scrollview实现回弹效果
2022/04/01 Java/Android
吉利入股戴姆勒后smart“长大了”
2022/04/21 数码科技
Elasticsearch6.2服务器升配后的bug(避坑指南)
2022/09/23 Servers