1949啦网--小小 痛苦,是因为能力和欲望不匹配造成的

js碰撞运动之无损碰撞

无损碰撞

  假设两个元素的碰撞,对元素的速度并不产生损耗,而只是改变元素速度方向

  假设元素一在与元素二碰撞前的瞬时速度是v,将该速度分解为平行于碰撞方向的速度v1和垂直于碰撞方向的速度v2

  碰撞发生后,碰撞方向的速度v1变成了反向的v1

  将反向的v1分解到水平方向v1x和垂直方向v1y

  将垂直于碰撞方向的速度v2分解到水平方向v2x和垂直方向v2y

    水平方向的速度vx = v2x - v1x

    垂直方向的速度vy = v2y - v1y

  元素二的速度分解形式与元素一类似,就不再赘述

  <!DOCTYPE html>  <html>  	<head>  		<meta charset="UTF-8">  		<title></title>  	</head>  	<body>  <button id="btn1">开始运动</button>  <button id="reset">还原</button>  <div id="test1" style="height: 150px;width: 150px;background:pink;position:absolute;top:50px;left:50px;border-radius: 50%;"></div>  <div id="test2" style="height: 150px;width: 150px;background:orange;position:absolute;top:250px;left:250px;border-radius: 50%;"></div>  <script>  //声明元素的步长值  //步长值默认值为[-25,-20,-15,-10,-5,0,5,10,15,20]中的一个随机数  test1.stepX =  5*Math.floor(Math.random() * 10 - 5);  test1.stepY =  5*Math.floor(Math.random() * 10 - 5);  test2.stepX =  5*Math.floor(Math.random() * 10 - 5);  test2.stepY =  5*Math.floor(Math.random() * 10 - 5);  btn1.onclick = function(){      collisionMove({          obj:test1      })      collisionMove({          obj:test2      })  }  reset.onclick = function(){      history.go();  }  function collisionMove(json){      var obj = json.obj;      var fn = json.fn;      //声明x、y轴的当前值      var curX,curY;      //声明x、y轴方向      var dirX = json.dirX;      var dirY = json.dirY;      dirX = obj.stepX > 0 ? '+' : '-';      dirY = obj.stepY > 0 ? '+' : '-';      //声明offset宽高      var offsetWidth = obj.offsetWidth;      var offsetHeight = obj.offsetHeight;      //声明元素活动区域宽高      var activeWidth = json.activeWidth;      var activeHeight = json.activeHeight;      //元素获取区域宽高默认值为可视区域宽高      activeWidth = Number(activeWidth) || document.documentElement.clientWidth;      activeHeight = Number(activeHeight) || document.documentElement.clientHeight;      //声明left、top样式值      var left,top;      //清除定时器      if(obj.timer){return;}       //开启定时器      obj.timer = setInterval(function(){          //获取x、y轴的当前值          curX = parseFloat(getCSS(obj,'left'));          curY = parseFloat(getCSS(obj,'top'));          bump(test1,test2);          //更新left、top值          left = curX + obj.stepX;          top = curY + obj.stepY;          //右侧碰壁前一刻,步长大于剩余距离,且元素向右运动时          if((left > activeWidth - offsetWidth) && (dirX == '+')){              left = activeWidth - offsetWidth;          }          //左侧碰壁前一刻,步长大于剩余距离,且元素向左运动时          if((Math.abs(obj.stepX) > curX) && (dirX == '-')){              left = curX;          }          //下侧碰壁前一刻,步长大于剩余距离,且元素向下运动时          if((top > activeHeight - offsetHeight) && (dirY == '+')){              top = activeHeight - offsetHeight;          }          //上侧碰壁前一刻,步长大于剩余距离,且元素向上运动时          if((Math.abs(obj.stepY) > curY) && (dirY == '-')){              top = curY;          }          obj.style.left= left + 'px';          obj.style.top = top + 'px';          //左侧或右侧碰撞瞬间          if(left == activeWidth - offsetWidth || left == curX){              obj.stepX = -obj.stepX;          }          //上侧或下侧碰撞瞬间          if(top == activeHeight - offsetHeight || top == curY){              obj.stepY = -obj.stepY;          }          //更新运动方向          dirX = obj.stepX > 0 ? '+' : '-';          dirY = obj.stepY > 0 ? '+' : '-';      },20);              }    function getCSS(obj,style){      if(window.getComputedStyle){          return getComputedStyle(obj)[style];      }      return obj.currentStyle[style];  }   //碰撞检测函数  function bump(obj,objOther){      /***动态元素***/      obj.r = obj.offsetWidth/2;      obj.x0 = parseFloat(getCSS(obj,'left')) + obj.r;      obj.y0 = parseFloat(getCSS(obj,'top')) + obj.r;      /**静态元素**/      objOther.r = objOther.offsetWidth/2;      objOther.x0 = parseFloat(getCSS(objOther,'left')) + objOther.r;      objOther.y0 = parseFloat(getCSS(objOther,'top')) + objOther.r;      //圆心之间的距离      var len = Math.sqrt((obj.x0-objOther.x0)*(obj.x0-objOther.x0) + (obj.y0-objOther.y0)*(obj.y0-objOther.y0));      //发生碰撞      if(len <= obj.r + objOther.r){      //碰撞方向与水平负方向的夹角a           var a = Math.atan(Math.abs((obj.y0-objOther.y0)/(obj.x0-objOther.x0)));          stepChange(test1,test2,a);          stepChange(test2,test1,a);      }  }  //碰撞时,步长变化函数  function stepChange(obj,objOther,a){      //步长合并      obj.step = Math.sqrt(obj.stepX*obj.stepX + obj.stepY*obj.stepY);      //假设总步长方向与x轴方向的夹角为b      obj.b = Math.atan(Math.abs(obj.stepY/obj.stepX));      //假设总步长方向与碰撞方向的夹角为c      obj.c = Math.abs(a - obj.b);      //步长分解      //碰撞方向      obj.step1 = obj.step*Math.cos(obj.c);      //垂直方向      obj.step2 = obj.step*Math.sin(obj.c);      //按照运动元素(侵入元素)的起始运动方向对步长进行重新分解      //左上      if(obj.x0 <= objOther.x0 && obj.y0 <= objOther.y0){          obj.stepX = -obj.step1*Math.cos(a) + obj.step2*Math.sin(a)          obj.stepY = -obj.step1*Math.sin(a) - obj.step2*Math.cos(a)      }      //左下      if(obj.x0 < objOther.x0 && obj.y0 > objOther.y0){          obj.stepX = -obj.step1*Math.cos(a) + obj.step2*Math.sin(a)          obj.stepY = obj.step1*Math.sin(a) + obj.step2*Math.cos(a)       }      //右上      if(obj.x0 > objOther.x0 && obj.y0 < objOther.y0){          obj.stepX = obj.step1*Math.cos(a) - obj.step2*Math.sin(a)          obj.stepY = -obj.step1*Math.sin(a) - obj.step2*Math.cos(a)      }      //右下      if(obj.x0 > objOther.x0 && obj.y0 > objOther.y0){          obj.stepX = obj.step1*Math.cos(a) - obj.step2*Math.sin(a)          obj.stepY = obj.step1*Math.sin(a) + obj.step2*Math.cos(a)      }  }  </script>          	</body>  </html>

原文链接:https://www.qiquanji.com/post/8704.html

本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。

微信扫码关注

更新实时通知

作者:xialibing 分类:网页教程 浏览: