桌面上有多个球在同时运动,怎么实现球之间不交叉,即碰撞?
编程技术  /  houtizong 发布于 3年前   167
for(var particle=0;particle<particles.length ;particle++){particles[particle].draw(timeDelta);particles[particle].define();document.getElementsByClassName('tag')[0].className='';}需要在绘制完一个点后,马上调用碰撞检测函数define检测该点所以需要把它放在animate当中来调用,particle与animate都是全局变量这就陷入了一个两难的境地,既要全局变量animate能调用define也要让define能够访问全局变量particle下的私有变量,这正符合闭包的定义,闭包是即可以访问私有变量也可以成为全局变量被其他全局变量调用。所以可以把define作为particle下的闭包。
if(nexty<0){//if angle is between 3 o'clock and 9 o'clock if((angle-0.08)<=0) {angle=0.1;}if(angle+0.08>= Math.PI){angle=Math.PI-0.1}angle=Math.PI*2-angle;}
cssbody{padding: 0px;margin: 0px;overflow: hidden;}span{width: 16px;height: 16px;display: inline-block;border-radius: 50%;position: absolute;}#fps{position: fixed;bottom: 10px;right: 10px;font-size: 30px;font-weight: bold;}html<div id="fps"></div>js引用的是color.js它是一个1匿名函数如下(function(){var MAX_PARTICLES = 50;var MAX_VELOCITY = 500;var PARTICLE_RADIUS = 8;var STAGE_WIDTH = 1024;var STAGE_HEIGHT = 768;var COLORS = ["#cc0000", "#ffcc00", "#aaff00", "#0099cc", "#194c99", "#661999"];var FRAME_TIMES = [];var fpsArr=[];var timer;var max=0;var min=60;var average=0;var time=new Date().getTime();var particles = [];var wrap=document.createElement('div');//fps图表包含块初始化wrap.className='wrap';wrap.style.position='absolute';wrap.style.bottom=10+'px';wrap.style.left=10+'px';wrap.style.width=500+'px';wrap.style.height=120+'px';document.body.appendChild(wrap);var labelx=1;init();// debugger();function init(){STAGE_WIDTH=document.documentElement.clientWidth;//获取窗口可见宽高STAGE_HEIGHT=document.documentElement.clientHeight;for(var i=0 ;i<MAX_PARTICLES;i++)particles.push( new particle() );timer=setInterval(animate,30);}function paint(fps){//绘制图表上的每一个点if(labelx>wrap.offsetWidth/2){//一旦大于宽的一半擦掉重绘var delDot=document.getElementsByClassName('dot');while(delDot[0])wrap.removeChild(delDot[0]);labelx=1;}var dot=document.createElement('div');dot.className='dot';dot.style.position='absolute';dot.style.bottom=3*fps+'px';dot.style.left=labelx+'px';dot.style.backgroundColor='red';dot.style.zIndex=-5;dot.style.width=2+'px';dot.style.height=2+'px';wrap.appendChild(dot);labelx+=2;}function animate(){//动画function sum(arr){var i=0;var sum=0;for(;i<arr.length;i++)sum+=arr[i];return sum;}if(FRAME_TIMES.length>30) //保持计算fps的存储时间的数组长度为30FRAME_TIMES.splice(0,1);var curr=new Date().getTime();FRAME_TIMES.push(curr);// console.log(curr-FRAME_TIMES[FRAME_TIMES.length-2]);var fps=0;if(FRAME_TIMES.length>1)fps= 1000 / ((curr - FRAME_TIMES[0]) / (FRAME_TIMES.length - 1));fps=Number(fps.toFixed(2));paint(fps);//绘制fps图表if(fpsArr.length>30) fpsArr.splice(0,1);fpsArr.push(fps);//存储每个fps方便计算平均值// console.log(sum(fpsArr))average=(sum(fpsArr)/fpsArr.length).toFixed(2);//计算平均值if(fps>max)max=fps;if(fps&&fps<min)min=fps;//fpsArr.pushvar fshow=document.getElementById('fps');fshow.innerHTML="average: "+average+ " max: "+max+" min: "+min+" fps: "+fps+'fps';var timeDelta = curr - FRAME_TIMES[FRAME_TIMES.length - 2];for(var particle=0;particle<particles.length ;particle++){//绘制每一个点(实际上是改变每一个小球的坐标)particles[particle].draw(timeDelta);particles[particle].define(); /*当前小球绘制完后马上进行碰撞检测*/document.getElementsByClassName('tag')[0].className='';//检测完回来后置为空,以便下一个元素继续标记自己}}function distance(a,b){return Math.sqrt( Math.pow(a,2)+ Math.pow(b,2) )}function particle(){//小球位置颜色速度角度初始化并添加到dom树var velocity=(MAX_VELOCITY-MAX_VELOCITY/5)*Math.random()+MAX_VELOCITY/5;var x=STAGE_WIDTH/2-PARTICLE_RADIUS;var y=STAGE_HEIGHT/2-PARTICLE_RADIUS;var color=COLORS[Math.floor( COLORS.length*Math.random() )];var node=document.createElement('span');var angle=2*Math.PI*Math.random();node.style.backgroundColor=color;node.style.left=x+'px';node.style.top=y+'px';document.body.appendChild(node);function define(){//碰撞检测if(new Date().getTime()-time<5000) return var xx=x;var yy=y;var eles=document.getElementsByTagName('span'); //获取此时桌面上的所有小球,因为当前小球已经绘制完,故会连自己也会获取进来。而它自己与自己是永远相碰的故在draw中设置该小球的className,以便下面进行区分。for(var i=0;i<eles.length;i++){var dirtax=eles[i].offsetLeft-xx;var dirtay=eles[i].offsetTop-yy;if( distance( dirtax,dirtay) <16 && eles[i].className!='tag'){//检测是否是自己if(angle>=0&&angle<Math.PI){//在0 到180时变成大于180度角,并且break,不然进入下一条逻辑,又把角度变回来了!这相当于两种情况只执行一种,用if else即可angle=Math.PI+angle;break;}if(angle>=Math.PI&&angle<Math.PI*2){//angle=angle-Math.PI;break;}}}}function draw(){//每一个球坐标获取以及绘制var nextx=x + velocity*Math.cos(angle)/40;//(x,y) the current positon . (nextx,nexty) the next positionvar nexty=y - velocity*Math.sin(angle)/40;// for(var i=0;i<10000000;i++){}if(nextx>=STAGE_WIDTH-PARTICLE_RADIUS*2-13){// nextx=nextx-10;//if angle is between 3 o'clock and 12 o'clock if (angle>=0&&angle<Math.PI/2) angle=Math.PI-angle;//if angle is between 6 o'clock and 3 o'clock if(angle>3*Math.PI/2&&angle<Math.PI*2)angle=3*Math.PI-angle;}if(nexty<0){//if angle is between 3 o'clock and 9 o'clock if((angle-0.08)<=0) {angle=0.1;}if(angle+0.08>= Math.PI){angle=Math.PI-0.1}angle=Math.PI*2-angle;}if(nextx<0){if(angle>=Math.PI&&angle<Math.PI*1.5)//if angle is between 9 o'clock and 6 o'clock angle=3*Math.PI-angle;if(angle>Math.PI/2&&angle<Math.PI)//if angle is between 12 o'clock and 9 o'clock angle=Math.PI-angle;}if(nexty>STAGE_HEIGHT-PARTICLE_RADIUS*2-13)//if angle is between 9 o'clock and 3 o'clock angle=Math.PI*2-angle;//refresh the postition of the particlenode.style.left=nextx+'px';node.style.top=nexty+'px';node.className='tag';x=nextx;y=nexty;}return {//作为闭包返回。draw:draw,define:define}}var t=[];document.body.onresize=function(){//调整窗口大小时重新绘制//alert('1')// console.log('1')// var current=new Date().getTime();var spanlist=document.getElementsByTagName('span');while(spanlist.length!=0){document.body.removeChild(spanlist[0])}FRAME_TIMES=[];//重置clearInterval(timer);//清除定时器 max=0;min=60;particles=[];//将存闭包的particles清空init();//重绘开始}})()
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!
技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成
网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];
文章归档
文章标签
友情链接