原生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获取当页面上鼠标光标位置和触发事件的对象的代码
Dec 09 Javascript
Web 前端设计模式--Dom重构 提高显示性能
Oct 22 Javascript
使用documentElement正确取得当前可见区域的大小
Jul 25 Javascript
手机端网页点击链接触发自动拨打或保存电话的示例代码
Aug 15 Javascript
jfreechart插件将数据展示成饼状图、柱状图和折线图
Apr 13 Javascript
JavaScript File分段上传
Mar 10 Javascript
js实现右键自定义菜单
Dec 03 Javascript
JS表单传值和URL编码转换
Mar 03 Javascript
Vue-cropper 图片裁剪的基本原理及思路讲解
Apr 17 Javascript
vue cli 3.0 搭建项目的图文教程
May 17 Javascript
JavaScript多种滤镜算法实现代码实例
Dec 10 Javascript
浅谈React中组件逻辑复用的那些事儿
May 21 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实现模仿socket请求返回页面的方法
2014/11/04 PHP
ucenter中词语过滤原理分析
2016/07/13 PHP
php获取数据库结果集方法(推荐)
2017/06/01 PHP
转一个日期输入控件,支持FF
2007/04/27 Javascript
js 表单提交后按钮变灰的实例代码
2013/08/16 Javascript
javascript电商网站抢购倒计时效果实现
2015/11/19 Javascript
JQuery移动页面开发之屏幕方向改变与滚屏的实现
2015/12/03 Javascript
通过修改360抢票的刷新频率和突破8车次限制实现方法
2017/01/04 Javascript
js将字符串中的每一个单词的首字母变为大写其余均为小写
2017/01/05 Javascript
Bootstrap modal只加载一次数据的解决办法(推荐)
2017/11/24 Javascript
layui在form表单页面通过Validform加入简单验证的方法
2019/09/06 Javascript
Vue前端项目部署IIS的实现
2020/01/06 Javascript
简单了解Vue + ElementUI后台管理模板
2020/04/07 Javascript
JavaScript仿京东轮播图效果
2021/02/25 Javascript
Python多线程编程简单介绍
2015/04/13 Python
Python读取txt某几列绘图的方法
2018/10/14 Python
利用Python代码实现一键抠背景功能
2019/12/29 Python
浅谈pytorch池化maxpool2D注意事项
2020/02/18 Python
K最近邻算法(KNN)---sklearn+python实现方式
2020/02/24 Python
pycharm导入源码的具体步骤
2020/08/04 Python
对Pytorch 中的contiguous理解说明
2021/03/03 Python
HTML5的结构和语义(1):前言
2008/10/17 HTML / CSS
HTML5通用接口详解
2016/06/12 HTML / CSS
amazeui模态框弹出后立马消失并刷新页面
2020/08/19 HTML / CSS
Viking Direct爱尔兰:办公用品和家具
2019/11/21 全球购物
文员岗位职责
2013/11/09 职场文书
缓刑人员的思想汇报
2014/01/11 职场文书
新领导上任欢迎词
2014/01/13 职场文书
省三好学生申请材料
2014/01/22 职场文书
《再见了,亲人》教学反思
2014/02/26 职场文书
合作意向协议书范本
2014/03/31 职场文书
乡镇党的群众路线教育实践活动总结报告
2014/10/30 职场文书
实施意见格式范本
2015/06/05 职场文书
2015暑期社会实践调查报告
2015/07/14 职场文书
微信小程序实现录音Record功能
2021/05/09 Javascript
《黑岩★★射手 DAWN FALL》BD发售宣传CM公开
2022/04/04 日漫