1. 程式人生 > >JavaScript面向物件的小球碰撞實現基本原理

JavaScript面向物件的小球碰撞實現基本原理

主要記錄一下重點和難點

<!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指向問題