js實現小球的彈性碰撞。

  前  言javascript

MYBGcss

 小編最近在作本身的我的網站,其中就用到了一個小球碰撞檢測的功能,想本身寫,無奈本人能力不足啊(畢竟仍是一個菜鳥)!!就想着找個插件用一下也好,但是找了很久也沒有找到一個比較好用的。好在天無絕人之路,在不斷的搜搜巡巡過程當中,仍是發現了一個,用原生js實現小球碰撞檢測的方法,下面分享給你們。java

注:本文參考「敲代碼不愛找bug的妹子」的一篇博客,詳解可參考:http://blog.csdn.net/new_codeer/article/details/52386566json

  參考事後,通過對原文進行了稍微的改動,特別適用於網站的開發。複製過去,稍微改動一下便可。具體的原代碼以下:數組

1、HTML代碼(body部分)
 1 <body>
 2     <!--只須要作一個大div包裹幾個小div便可,你想要幾個小球碰撞就在內部作幾個div便可,這裏咱們作了6個小球-->
 3     <div id="main">
 4         <div></div>
 5         <div></div>
 6         <div></div>
 7         <div></div>
 8         <div></div>
 9         <div></div>
10     </div>  
11 </body>

  上面body部分這樣就算是完成了,下面咱們給body中的div作一些小樣式。瀏覽器

2、CSS小球樣式部分
 1 <style type="text/css">
 2     /*將body默認的margin和padding部分去掉*/
 3     *{
 4         margin: 0px;
 5         padding: 0px;
 6      }
 7      /*採用定位的方式,讓小球運動起來*/
 8      #main{
 9          margin: 0px auto;
10          position: relative;
11      }
12      /*小球的樣式*/
13      #main div{
14          overflow: hidden;
15          position: absolute;
16          width: 80px;
17          height: 80px;
18          opacity: 0.5;
19          border-radius: 50%;
20          background-color: red;
21      }
22 </style>

   小球是要運動起來的,咱們經過給小球和它的父元素添加定位,最後用js改變其top、bottom、left、right值來讓小球運動。如今咱們小球的樣式已經作好了,下面的js代碼纔是重中之重。app

3.1 Android 事件基礎知識
  1 <script type="text/javascript">
  2         var main = document.getElementById("main"); //取到小球父元素
  3         var circles = main.getElementsByTagName("div"); //取到小球
  4         var st = [0,1,2,3,4,5,6,7,8,9];
  5         var json = [],arr = [],color = [];
  6         var maxW = 0;
  7         var maxH = 0;
  8         var cwidth = circles[0].offsetWidth; //對象可見寬度
  9         var cheight = circles[0].offsetHeight; //對象可見高度
 10 
 11         //根據瀏覽器窗口的大小自動調節小球的運動空間
 12         window.onresize=function(){
 13             maxW=window.innerWidth-circles[0].clientWidth;//小球運動的最大寬度
 14             maxH=window.innerHeight-circles[0].clientHeight;//小球運動的最大高度
 15                 main.style.width = window.innerWidth+"px";
 16             main.style.height = window.innerHeight+"px";
 17         }
 18         onresize();
 19         //數組對象的初始化
 20         for(var i=0;i<circles.length;i++){
 21             arr=[];
 22             for(var j=0;j<6;j++){
 23                 color[j] = st[Math.floor(Math.random()*16)];
 24             }
 25         arr.x = Math.floor(Math.random()*(maxW+1));//初始x座標
 26         arr.y = Math.floor(Math.random()*(maxH+1));//初始y座標
 27         arr.cx = arr.x + circles[0].offsetWidth/2; //圓心x座標
 28         arr.cy = arr.y + circles[0].offsetHeight/2; //圓心y座標
 29         arr.movex = Math.floor(Math.random()*2);//x軸移動方向
 30         arr.movey = Math.floor(Math.random()*2);//y軸移動方向
 31         arr.speed = 2+Math.floor(Math.random()*5);//隨機生成2-6之間的移動速度,若是在作項目的時候,這種隨即生成的速度不想用的話,能夠直接給speed賦值,
固定小球的速度便可。如如下代碼:
32 //arr.speed = 1.5; 34 arr.timer = null;//計時器 35 arr.index = i;//索引值 36 json.push(arr); 37 circles[i].style.left = arr.x + "px";//小球位置初始化 38 circles[i].style.top = arr.y + "px";//小球位置初始化 39 } 40 //碰撞函數 41 function crash(a){ 42 var ball1x = json[a].cx; 43 var ball1y = json[a].cy; 44 for(var i= 0;i<json.length;i++){ 45 if(i!=a){ 46 var ball2x = json[i].cx; 47 var ball2y = json[i].cy; 48 //圓心距離的平方 49 var len = (ball1x-ball2x)*(ball1x-ball2x)+(ball1y-ball2y)*(ball1y-ball2y); 50 if(len <= cwidth*cwidth){ 51 //小球位置的判斷,發生碰撞反應 52 if(ball1x >ball2x){ 53 if(ball1y > ball2y){ 54 json[a].movex=1; 55 json[a].movey=1; 56 }else if(ball1y < ball2y){ 57 json[a].movex=1; 58 json[a].movey=0; 59 }else{ 60 json[a].movex=1; 61 } 62 }else if(ball1x < ball2x){ 63 if(ball1y > ball2y){ 64 json[a].movex=0; 65 json[a].movey=0; 66 }else if(ball1y < ball2y){ 67 json[a].movex=0; 68 json[a].movey=1; 69 }else{ 70 json[a].movex=0; 71 } 72 }else{ 73 if(ball1y > ball2y){ 74 json[a].movey=1; 75 }else if(ball1y < ball2y){ 76 json[a].movey=0; 77 } 78 } 79 } 80 } 81 82 } 83 } 84 //移動函數 85 function move(circle){ 86 circle.timer = setInterval(function () { 87 if(circle.movex == 1){ 88 circle.x+=circle.speed; 89 if(circle.x+circle.speed >= maxW){//防止小球出界 90 circle.x = maxW; 91 circle.movex=0;//小球運動方向發生改變 92 } 93 }else{ 94 circle.x-=circle.speed; 95 if(circle.x-circle.speed <= 0){ 96 circle.x = 0; 97 circle.movex=1; 98 } 99 } 100 if(circle.movey == 1){ 101 circle.y += circle.speed; 102 if(circle.y+circle.speed >= maxH){ 103 circle.y = maxH; 104 circle.movey=0; 105 } 106 }else{ 107 circle.y-=circle.speed; 108 if(circle.y-circle.speed <= 0){ 109 circle.y = 0; 110 circle.movey=1; 111 } 112 } 113 circle.cx = circle.x + circles[0].offsetWidth/2;//小球每一次運動圓心都會發生改變 114 circle.cy = circle.y + circles[0].offsetHeight/2; 115 circles[circle.index].style.left = circle.x + "px";//小球位置重定位 116 circles[circle.index].style.top = circle.y + "px"; 117 crash(circle.index); 118 },15); 119 } 120 //對每個小球綁定計時器,讓小球動起來 121 for(var i=0;i<circles.length;i++){ 122 move(json[i]); 123 } 124 </script>

   其實,咱們經過上面的代碼就能夠徹底實現一個小球碰撞檢測的功能了。可是僅僅是上面的代碼,仍是會存在必定的bug,就是當整個網站存在右側滾動條時,當小球碰到屏幕右側的時候,會出現一瞬的橫向滾動條,這就是作網站比較忌諱的了,橫向滾動條的出現太醜了。因此咱們能夠經過如下代碼來解決。dom

 1        //滾動條寬度計算函數
 2         function getScrollbarWidth() {
 3             var oP = document.createElement("p"),
 4                 styles = {
 5                     width: "100px",
 6                     height: "100px",
 7                     overflowY: "scroll"
 8                 }, i, scrollbarWidth;
 9             for (i in styles) oP.style[i] = styles[i];
10             document.body.appendChild(oP);
11             scrollbarWidth = oP.offsetWidth - oP.clientWidth;
12             oP.remove();
13             return scrollbarWidth;
14         }

  以上是一個計算滾動條寬度的函數,此函數能夠計算右側滾動條的寬度,咱們只須要在「根據瀏覽器窗口的大小自動調節小球的運動空間」上面,調用此函數函數

var scrollbarWidth = getScrollbarWidth(); 再修改小球的最大運動寬度   maxW=window.innerWidth-circles[0].clientWidth-scrollbarWidth ;這樣這個bug就修改好了。網站

編者按

  這個是我在作項目時的親身經歷,以爲這個寫得特別好用,就拿過來與你們分享一下。但願對你們有那麼一點點兒幫助吧!!最後還要感謝一下「敲代碼不愛找bug的妹子」幫我解決了一個大問題。。

相關文章
相關標籤/搜索