前 言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的妹子」幫我解決了一個大問題。。