原生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技巧--转义符&quot;\&quot;的妙用
Jan 09 Javascript
js 多种变量定义(对象直接量,数组直接量和函数直接量)
May 24 Javascript
css配合jquery美化 select
Nov 29 Javascript
异步安全加载javascript文件的方法
Jul 21 Javascript
基于jQuery实现二级下拉菜单效果
Feb 01 Javascript
javascript操作cookie
Jan 17 Javascript
Bootstrap 下拉多选框插件Bootstrap Multiselect
Jan 22 Javascript
JS获取浮动(float)元素的style.left值为空的快速解决办法
Feb 19 Javascript
SVG实现时钟效果
Jul 17 Javascript
angularjs使用div模拟textarea文本框的方法
Oct 02 Javascript
jQuery实现移动端笔触canvas电子签名
May 21 jQuery
js实现轮播图特效
May 28 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
2021年最新CPU天梯图
2021/03/04 数码科技
simplehtmldom Doc api帮助文档
2012/03/26 PHP
解析isset与is_null的区别
2013/08/09 PHP
微信API接口大全
2015/04/15 PHP
用JS写的一个TableView控件代码
2010/01/23 Javascript
JavaScript 设计模式之组合模式解析
2010/04/09 Javascript
javascript (用setTimeout而非setInterval)
2011/12/28 Javascript
解决jquery submit()提交表单提示:f[s] is not a function
2013/01/23 Javascript
js读写(删除)Cookie实例详解
2013/04/17 Javascript
转换字符串为json对象的方法详解
2013/11/29 Javascript
javascript感应鼠标图片透明度显示的方法
2015/02/24 Javascript
javascript中使用正则表达式清理table样式的代码
2020/04/01 Javascript
jquery实现未经美化的简洁TAB菜单效果
2015/08/28 Javascript
纯前端JavaScript实现Excel IO案例分享
2016/08/26 Javascript
JS常用函数和常用技巧小结
2016/10/15 Javascript
JS实战篇之收缩菜单表单布局
2016/12/10 Javascript
详解基于Angular4+ server render(服务端渲染)开发教程
2017/08/28 Javascript
原生JS实现多个小球碰撞反弹效果示例
2018/01/31 Javascript
2种在vue项目中使用百度地图的简单方法
2018/09/28 Javascript
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
2017/02/14 Python
Django自定义分页与bootstrap分页结合
2021/02/22 Python
python下10个简单实例代码
2017/11/15 Python
Python实现自动上京东抢手机
2018/02/06 Python
使用python Fabric动态修改远程机器hosts的方法
2018/10/26 Python
使用python读取.text文件特定行的数据方法
2019/01/28 Python
用python生成与调用cntk模型代码演示方法
2019/08/26 Python
pycharm激活码有效到2020年11月底
2020/09/18 Python
python字符串判断密码强弱
2020/03/18 Python
CSS3实现的闪烁跳跃进度条示例(附源码)
2013/08/19 HTML / CSS
阿拉伯世界最大的电子商务网站:Souq沙特阿拉伯
2016/10/28 全球购物
材料成型及控制工程专业求职信
2014/06/19 职场文书
医院病假条范文
2015/08/17 职场文书
2016年党建工作简报
2015/11/26 职场文书
2016年乡镇综治宣传月活动总结
2016/03/16 职场文书
Python爬虫框架之Scrapy中Spider的用法
2021/06/28 Python
MySQL系列之十四 MySQL的高可用实现
2021/07/02 MySQL