原生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 相关文章推荐
Dom 学习总结以及实例的使用介绍
Apr 24 Javascript
javascript获取ckeditor编辑器的值(实现代码)
Nov 18 Javascript
基于jQuery的图片不完全按比例自动缩小
Jul 11 Javascript
node.js不得不说的12点内容
Jul 14 Javascript
简单理解JavaScript中的封装与继承特性
Mar 19 Javascript
Bootstrap每天必学之级联下拉菜单
Mar 27 Javascript
JS闭包、作用域链、垃圾回收、内存泄露相关知识小结
May 16 Javascript
BootStrap 可编辑表Table格
Nov 24 Javascript
javascript操作cookie
Jan 17 Javascript
JavaScript简单计算人的年龄示例
Apr 15 Javascript
了解JavaScript中的选择器
May 24 Javascript
vue中使用rem布局代码详解
Oct 30 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
基于mysql的论坛(7)
2006/10/09 PHP
php $_ENV为空的原因分析
2009/06/01 PHP
PHP Reflection API详解
2015/05/12 PHP
PHP使用CURL模拟登录的方法
2015/07/08 PHP
PHP微信开发之模板消息回复
2016/06/24 PHP
Laravel 创建可以传递参数 Console服务的例子
2019/10/14 PHP
不同浏览器对回车提交表单的处理办法
2010/02/13 Javascript
Prototype的Class.create函数解析
2011/09/22 Javascript
基于jQuery的遍历同id元素 并响应事件的代码
2012/06/14 Javascript
JS获取DropDownList的value值与text值的示例代码
2014/01/07 Javascript
新手快速学习JavaScript免费教程资源汇总
2015/06/25 Javascript
avalon js实现仿微博拖动图片排序
2015/08/14 Javascript
AngularJS实现全选反选功能
2015/12/08 Javascript
Javascript中的对象和原型(二)
2016/08/12 Javascript
canvas实现图像截取功能
2017/02/06 Javascript
JS中Safari浏览器中的Date
2017/07/17 Javascript
jQuery实现监听下拉框选中内容发生改变操作示例
2018/07/13 jQuery
jQuery表单元素过滤选择器用法实例分析
2019/02/20 jQuery
webpack结合express实现自动刷新的方法
2019/05/07 Javascript
[01:29:42]Liquid vs VP Supermajor决赛 BO 第一场 6.10
2018/07/05 DOTA
Python实现图片拼接的代码
2018/07/02 Python
详解用python生成随机数的几种方法
2019/08/04 Python
Python模块的定义,模块的导入,__name__用法实例分析
2020/01/07 Python
Python logging日志库空间不足问题解决
2020/09/14 Python
Python3利用scapy局域网实现自动多线程arp扫描功能
2021/01/21 Python
HTML实现代码雨源码及效果示例
2020/02/25 HTML / CSS
Conforama西班牙:您的家具、装饰和电器商店
2020/02/21 全球购物
英国时尚首饰品牌:Missoma
2020/06/29 全球购物
小饰品店的创业计划书范文
2013/12/28 职场文书
主持人婚宴答谢词
2014/01/28 职场文书
学校领导班子四风问题整改意见
2014/10/02 职场文书
中学生旷课检讨书500字
2014/10/29 职场文书
升职自我推荐信范文
2015/03/25 职场文书
python调试工具Birdseye的使用教程
2021/05/25 Python
深入讲解数据库中Decimal类型的使用以及实现方法
2022/02/15 MySQL
基于redis+lua进行限流的方法
2022/07/23 Redis