原生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模拟点击事件实现代码
Nov 06 Javascript
浅谈Sizzle的“编译原理”
Apr 14 Javascript
AngularJS的表单使用详解
Jun 17 Javascript
jQuery实现定时读取分析xml文件的方法
Jul 16 Javascript
JavaScript实现的多种鼠标拖放效果
Nov 03 Javascript
javascript HTML+CSS实现经典橙色导航菜单
Feb 16 Javascript
JavaScript中的时间处理小结
Feb 24 Javascript
10分钟掌握XML、JSON及其解析
Dec 06 Javascript
微信小程序 less文件编译成wxss文件实现办法
Dec 05 Javascript
前端js弹出框组件使用方法
Aug 24 Javascript
那些精彩的JavaScript代码片段
Jan 12 Javascript
JavaScript中严格判断NaN的方法
Feb 16 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
多数据表共用一个页的新闻发布
2006/10/09 PHP
Ajax实时验证用户名/邮箱等是否已经存在的代码打包
2011/12/01 PHP
ThinkPHP调用common/common.php函数提示错误function undefined的解决方法
2014/08/25 PHP
thinkphp判断访客为手机端或PC端的方法
2014/11/24 PHP
php实现字符串首字母转换成大写的方法
2015/03/17 PHP
PHP使用file_get_content设置头信息的方法
2016/02/14 PHP
laravel自定义分页的实现案例offset()和limit()
2019/10/15 PHP
Checbox的操作含已选、未选及判断代码
2013/11/07 Javascript
JS、jquery实现几分钟前、几小时前、几天前等时间差显示效果的代码实例分享
2014/04/11 Javascript
JavaScript中自定义事件用法分析
2014/12/23 Javascript
用jQuery.ajaxSetup实现对请求和响应数据的过滤
2016/12/20 Javascript
快速使用node.js进行web开发详解
2017/04/26 Javascript
javascript 封装Date日期类实例详解
2017/05/28 Javascript
JS Testing Properties 判断属性是否在对象里的方法
2017/10/01 Javascript
解决vue同一slot在组件中渲染多次的问题
2018/09/06 Javascript
理理Vue细节(推荐)
2019/04/16 Javascript
使用Karma做vue组件单元测试的实现
2020/01/16 Javascript
jQuery事件模型默认行为执行顺序及trigger()与 triggerHandler()比较实例分析
2020/04/30 jQuery
基于JS+HTML实现弹窗提示是否确认提交功能
2020/06/17 Javascript
PYTHON基础-时间日期处理小结
2018/05/05 Python
Python 判断奇数偶数的方法
2018/12/20 Python
python scipy卷积运算的实现方法
2019/09/16 Python
pycharm不能运行.py文件的解决方法
2020/02/12 Python
Python使用socket模块实现简单tcp通信
2020/08/18 Python
python 6行代码制作月历生成器
2020/09/18 Python
python读取excel数据绘制简单曲线图的完整步骤记录
2020/10/30 Python
英国领先的办公用品供应商:Viking
2016/08/01 全球购物
Omio美国:全欧洲低价大巴、火车和航班搜索和比价
2017/11/08 全球购物
一道写SQL的面试题和答案
2013/11/19 面试题
医生自荐信
2013/10/11 职场文书
文明礼仪事迹材料
2014/01/09 职场文书
售后客服工作职责
2014/06/16 职场文书
小学四年级学生评语
2014/12/26 职场文书
2015年大学班级工作总结
2015/04/28 职场文书
财务人员廉洁自律心得体会
2016/01/13 职场文书
SQL SERVER实现连接与合并查询
2022/02/24 SQL Server