JavaScript面向物件的小球碰撞實現基本原理
阿新 • • 發佈:2018-12-16
主要記錄一下重點和難點
<!doctype html> <html> <head> <meta charset="utf-8"> <title>碰撞反彈</title> <style> *{margin:0;} .main{margin: 100px auto;border: 1px solid #000;position: relative;} .ball{border: 1px solid #000;position: absolute;} </style> </head> <body> <script> function PZ(options){ this.kwidth= options.kwidth || 600; this.kheight= options.kheight || 400; this.kclass=options.kclass || ""; this.bwidth= options.bwidth || 40; this.bheight= options.bheight || 40; this.bclass=options.bclass || ""; this.bnum=options.bnum || 1; this.balls=[]; this.K; this.ck=function(){ this.K=document.createElement("div"); this.K.style.width=this.kwidth+"px"; this.K.style.height=this.kheight+"px"; this.K.className=this.kclass document.body.appendChild(this.K); } this.cb=function(){ for(var i=0;i<this.bnum;i++){ var el=document.createElement("div"); var reg=2*Math.random()*Math.PI;//初始角度,弧度制 this.balls.push({el:el,reg:reg,x:this.kwidth/2,y:this.kheight/2}); el.style.width=this.bwidth+"px"; el.style.height=this.bheight+"px"; el.className=this.bclass this.K.appendChild(el); } } this.bmove=function(){ for(var i=0;i<this.balls.length;i++){ this.balls[i].x=this.balls[i].x+8*Math.cos(this.balls[i].reg); this.balls[i].y=this.balls[i].y+8*Math.sin(this.balls[i].reg); this.balls[i].el.style.top=this.balls[i].y+"px"; this.balls[i].el.style.left=this.balls[i].x+"px"; if(this.balls[i].y>this.kheight-this.bheight || this.balls[i].y<0){ this.balls[i].reg=-this.balls[i].reg; } if(this.balls[i].x>this.kwidth-this.bwidth || this.balls[i].x<0){ this.balls[i].reg=Math.PI-this.balls[i].reg; } } //setTimeout(this.bmove.bind(this),400); requestAnimationFrame(this.bmove.bind(this)); } this.init=function(){ this.ck(); this.cb(); this.bmove(); } } var z=new PZ({ kwidth:1000, kheight:800, kclass:"main", bclass:"ball", bnum:52}); z.init(); var z2=new PZ({kwidth:600, kheight:400, kclass:"main", bclass:"ball", bnum:22}); z2.init(); </script> </body> </html>
難點在於一個球的初始運動方向演算法
var reg=2*Math.random()*Math.PI;//初始角度,弧度制
這裡使用到了三角函式,產生一個0到2π的角度(弧度制)
this.balls[i].x=this.balls[i].x+8*Math.cos(this.balls[i].reg); this.balls[i].y=this.balls[i].y+8*Math.sin(this.balls[i].reg);
超出邊界反彈也使用了三角函式的特性,由此可見數學基礎的重要性。
if(this.balls[i].y>this.kheight-this.bheight || this.balls[i].y<0){ this.balls[i].reg=-this.balls[i].reg; } if(this.balls[i].x>this.kwidth-this.bwidth || this.balls[i].x<0){ this.balls[i].reg=Math.PI-this.balls[i].reg; }
新的動畫API,優於老的setTimeout、setInterval等
requestAnimationFrame(this.bmove.bind(this));
此處的坑是this.bmove.bind(this),一般我們用的時候都是直接寫方法,但是現在在面向物件裡面我們使用了this,這導致了一些問題,具體問題及分析見關於setInterval和setTImeout中的this指向問題