原生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 相关文章推荐
IE8下关于querySelectorAll()的问题
May 13 Javascript
JavaScript高级程序设计 阅读笔记(十八) js跨平台的事件
Aug 14 Javascript
JavaScript中reduce()方法的使用详解
Jun 09 Javascript
JavaScript+Java实现HTML页面转为PDF文件保存的方法
May 30 Javascript
详解AngularJS通过ocLazyLoad实现动态(懒)加载模块和依赖
Mar 01 Javascript
用jQuery将JavaScript对象转换为querystring查询字符串的方法
Nov 12 jQuery
vue使用codemirror的两种用法
Aug 27 Javascript
对layui数据表格动态cols(字段)动态变化详解
Oct 25 Javascript
微信小程序停止其他视频播放当前视频的实例代码
Dec 25 Javascript
html中创建并调用vue组件的几种方法汇总
Nov 17 Javascript
Vue 简单实现前端权限控制的示例
Dec 25 Vue.js
JS前端监控采集用户行为的N种姿势
Jul 23 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/03/03 咖啡文化
php4的session功能评述(一)
2006/10/09 PHP
PHP个人网站架设连环讲(一)
2006/10/09 PHP
国外比较好的几个的Php开源建站平台小结
2010/04/22 PHP
php中判断文件空目录是否有读写权限的函数代码
2012/08/07 PHP
php和js如何通过json互相传递数据相关问题探讨
2013/02/26 PHP
解析crontab php自动运行的方法
2013/06/24 PHP
js实现简单的星级选择器提交效果适用于评论等
2013/10/18 Javascript
jquery 合并内容相同的单元格(示例代码)
2013/12/13 Javascript
Jquery插件分享之气泡形提示控件grumble.js
2014/05/20 Javascript
node.js中的fs.fstat方法使用说明
2014/12/15 Javascript
jQuery UI设置固定日期选择特效代码分享
2015/08/27 Javascript
Vue2.0+ElementUI实现表格翻页的实例
2017/10/23 Javascript
vue-cli+webpack项目 修改项目名称的方法
2018/02/28 Javascript
js获取html页面代码中图片地址的实现代码
2018/03/05 Javascript
jQuery发请求传输中文参数乱码问题的解决方案
2018/05/22 jQuery
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
2019/04/28 jQuery
vue实现pdf文档在线预览功能
2019/11/26 Javascript
解决vue-pdf查看pdf文件及打印乱码的问题
2020/11/04 Javascript
python动态加载变量示例分享
2014/02/17 Python
pygame播放音乐的方法
2015/05/19 Python
python opencv 实现对图像边缘扩充
2020/01/19 Python
用python对oracle进行简单性能测试
2020/12/05 Python
基于 HTML5 WebGL 实现的垃圾分类系统
2019/10/08 HTML / CSS
HTML5本地存储之Database Storage应用介绍
2013/01/06 HTML / CSS
九州传奇上机题
2014/07/10 面试题
Java模拟试题
2014/11/10 面试题
关于毕业的广播稿
2014/01/10 职场文书
我读书我快乐演讲稿
2014/05/07 职场文书
感恩小明星事迹材料
2014/05/23 职场文书
预防传染病方案
2014/06/14 职场文书
大雁塔英文导游词
2015/02/10 职场文书
污水处理保证书
2015/05/09 职场文书
初中数学教学随笔
2015/08/15 职场文书
SQL Server中交叉联接的用法详解
2021/04/22 SQL Server
python 三边测量定位的实现代码
2021/04/22 Python