原生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 XMLHttpRequest对象全面剖析
Apr 24 Javascript
基于jquery的一个浮动框(扩展性比较好 )
Aug 27 Javascript
jQuery实现的多选框多级联动插件
May 02 Javascript
js实现点击文本框显示日期选择器特效代码分享
May 21 Javascript
javascript实现抽奖程序的简单实例
Jun 07 Javascript
AngularJs IE Compatibility 兼容老版本IE
Sep 01 Javascript
微信小程序 POST请求(网络请求)详解及实例代码
Nov 16 Javascript
Vue代码分割懒加载的实现方法
Nov 23 Javascript
教你如何用node连接redis的示例代码
Jul 12 Javascript
详解Angular5/Angular6项目如何添加热更新(HMR)功能
Oct 10 Javascript
实例分析javascript中的异步
Jun 02 Javascript
Vue+element+cookie记住密码功能的简单实现方法
Sep 20 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 file_exists问题杂谈
2012/05/07 PHP
php中sprintf与printf函数用法区别解析
2014/02/17 PHP
PHP的APC模块实现上传进度条
2015/10/27 PHP
学习PHP Cookie处理函数
2016/08/09 PHP
AJAX PHP无刷新form表单提交的简单实现(推荐)
2016/09/09 PHP
使用PHP+Redis实现延迟任务,实现自动取消订单功能
2019/11/21 PHP
根据分辨率不同,调用不同的css文件
2006/07/07 Javascript
对 lightbox JS 图片控件进行了一下改造, 使其他支持复杂的图片说明
2010/03/20 Javascript
简易js代码实现计算器操作
2013/04/15 Javascript
JavaScript 和 Java 的区别浅析
2013/07/31 Javascript
jQuery+PHP实现微信转盘抽奖功能的方法
2016/05/25 Javascript
Node.js如何自动审核团队的代码
2016/07/20 Javascript
JS文件上传神器bootstrap fileinput详解
2021/01/28 Javascript
bootstrap模态框跳转到当前模板页面 框消失了而背景存在问题的解决方法
2020/11/30 Javascript
利用Ionic2 + angular4实现一个地区选择组件
2017/07/27 Javascript
关于jquery form表单序列化的注意事项详解
2017/08/01 jQuery
详解React之key的使用和实践
2018/09/29 Javascript
一文读懂ES7中的javascript修饰器
2019/05/06 Javascript
Python中的匿名函数使用简介
2015/04/27 Python
Python2.x版本中maketrans()方法的使用介绍
2015/05/19 Python
微信跳一跳自动运行python脚本
2018/01/08 Python
Python微医挂号网医生数据抓取
2019/01/24 Python
Python多版本开发环境管理工具介绍
2019/07/03 Python
Django如何使用jwt获取用户信息
2020/04/21 Python
Python中的特殊方法以及应用详解
2020/09/20 Python
Sneaker Studio捷克:购买运动鞋
2018/07/08 全球购物
介绍一下linux文件系统分配策略
2013/02/25 面试题
前台文员职责范本
2014/03/07 职场文书
高中家长寄语
2014/04/02 职场文书
社保委托书怎么写
2014/08/02 职场文书
教师思想作风整顿个人剖析材料
2014/10/10 职场文书
中考学习决心书
2015/02/04 职场文书
《水浒传》读后感3篇(范文)
2019/09/19 职场文书
Mysql案例刨析事务隔离级别
2021/09/25 MySQL
Redis调用Lua脚本及使用场景快速掌握
2022/03/16 Redis
mysql查看表结构的三种方法总结
2022/07/07 MySQL