主要记录一下重点和难点
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>碰撞反弹</title>
<style>
*{margin:0;}
.main{margin: 100px auto;border: 1px solid #000;position: relative;}
.ball{position: absolute;border-radius: 200px;}
</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;//初始角度,弧度制
var bcolor=this.colors();
var sudu=this.sudu();
this.balls.push({el:el,reg:reg,x:this.kwidth/2,y:this.kheight/2,bcolor:bcolor,sudu:sudu});
el.style.width=this.bwidth+"px";
el.style.height=this.bheight+"px";
el.style.backgroundColor=bcolor;
el.className=this.bclass
this.K.appendChild(el);
}
}
this.colors=function(){
var bcolor="";
for(var j=0;j<3;j++){
bcolor+=parseInt(Math.random()*255)+",";
}
return "rgba("+bcolor+Math.random()+")";
}
this.sudu=function(){
return parseInt(Math.random()*10+5);
}
this.bmove=function(){
for(var i=0;i<this.balls.length;i++){
var sudu=this.balls[i].sudu;
this.balls[i].x=this.balls[i].x+sudu*Math.cos(this.balls[i].reg);
this.balls[i].y=this.balls[i].y+sudu*Math.sin(this.balls[i].reg);
this.balls[i].el.style.backgroundColor=this.balls[i].bcolor;
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;
this.balls[i].bcolor=this.colors();
}
if(this.balls[i].x>this.kwidth-this.bwidth || this.balls[i].x<0){
this.balls[i].reg=Math.PI-this.balls[i].reg;
this.balls[i].bcolor=this.colors();
}
}
//setTimeout(this.bmove.bind(this),400);
requestAnimationFrame(this.bmove.bind(this));
//console.log(this.balls[0].bcolor);
}
this.init=function(){
this.ck();
this.cb();
this.bmove();
}
}
var z=new PZ({
kwidth:1000,
kheight:800,
kclass:"main",
bclass:"ball",
bwidth:60,
bheight:60,
bnum:62});
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指向问题