前 言
MYBG
小编最近在做自己的个人网站,其中就用到了一个小球碰撞检测的功能,想自己写,无奈本人能力不足啊(毕竟还是一个菜鸟)!!就想着找个插件用一下也好,可是找了好久也没有找到一个比较好用的。好在天无绝人之路,在不断的搜搜巡巡过程中,还是发现了一个,用原生js实现小球碰撞检测的方法,下面分享给大家。
注:本文参考“敲代码不爱找bug的妹子”的一篇博客,详解可参考:http://blog.csdn.net/new_codeer/article/details/52386566
参考过后,经过对原文进行了稍微的改动,特别适用于网站的开发。复制过去,稍微改动一下即可。具体的原代码如下:
一、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做一些小样式。
二、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代码才是重中之重。
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,就是当整个网站存在右侧滚动条时,当小球碰到屏幕右侧的时候,会出现一瞬的横向滚动条,这就是做网站比较忌讳的了,横向滚动条的出现太丑了。所以我们可以通过以下代码来解决。
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的妹子”帮我解决了一个大问题。。
js实现小球的弹性碰撞。
原文地址:http://www.cnblogs.com/interesting-me/p/7818632.html