其实TAMA酱不是我名字
2016-05-13 20:15
function updateBalls(){
for(var i = 0;i<balls.length;i++){
balls[i].x += balls[i].vx;
balls[i].y += balls[i].vy;
balls[i].vy += balls[i].g;
if(balls[i].y >= WINDOW_HEIGHT - RADIUS){
balls[i].y = WINDOW_HEIGHT - RADIUS;
balls[i].vy = -balls[i].vy*0.5;
}
}
var cnt = 0;
for( var i = 0 ; i < balls.length ; i ++ )
if( balls[i].x + RADIUS > 0 && balls[i].x -RADIUS < WINDOW_WIDTH )
balls[cnt++] = balls[i];
while( balls.length > cnt ){
balls.pop();
}
}
刚好在写这里的代码,共同学习,互相交流啦。
在这个函数里有三个循环。
前两个for循环,乍一看循环条件都是一样的,貌似可以合并。我判断这两个for到底能不能合并写成一个for,主要是看他们是否互有影响。
老师的代码中,第一个for在算小球下一个瞬间的运动位置(笼统地看,就是在计算每个球的运动轨迹),顺便用if保证了碰到画布下边界后小球将回弹。第二个for,在if中限制了小球在左边界的位置和小球在右边界的位置。即保证小球一定出现在画布上,计算所有在画布上的小球,并把它们推到数组的最前方。这里是要得到cnt的值。内容上看,这两个for循环的内容是可以合并的。
balls[cnt++] = balls[i];
等价于
balls[cnt] = balls[i]; cnt = cnt + 1;
这里有个没有声明的默认条件,即cnt永远小于等于balls.length,也就是说,第二个for循环的内容不会改变balls.length的值,即不会影响 i 循环的次数。从逻辑上看,这两个for循环的内容也是可以合并的。所以我在代码中把两个for合并了,暂时未看到什么影响~
// 我的代码↓ // ps.这里的ballAmount就是老师代码中的cnt,globalHeight、globalWidth是老师代码中的画布高宽 var ballAmount = 0; for (var i = 0; i < balls.length; i++) { balls[i].x += balls[i].vx; balls[i].y += balls[i].vy; balls[i].vy += balls[i].g; // 小球碰到画布下边界后向上回弹 if (balls[i].y >= globalHeight - RADIUS) { balls[i].y = globalHeight - RADIUS; balls[i].vy = -balls[i].vy*0.75; } // 小球在左边界位置、小球在右边界位置。即保证小球出现在画布上 if (balls[i].x + RADIUS > 0 && balls[i].x - RADIUS < globalWidth) { balls[ballAmount++] = balls[i]; } }
其实这也间接回答了你的问题,因为在for循环里,cnt的值是从0开始递增的,我们想得到的是画布上的出现小球总数。而balls里面放的是所有球(即画布上我们可视区域内和从画布边缘消失的不可见但存在的球)。while做的事情就是去掉balls数组中我们不可见的球,及时缩减维护数组的总长度(每个浏览器都对数组的最长值有限制的,而且数组过长还会带来性能卡顿等等问题,,),所以要等到 cnt 确定后再进行操作。举个例子,按照楼主的写法,如果while放在离他最近那个for循环里的话,第一次循环时,i=0,cnt=1,当 balls.length > 1 时删除数组末尾的项。。。balls数组。。。就会只剩第一项了吧~
如果要是想少写一个for,可以这样写:
var cnt = 0;
for( var i = 0 ; i < balls.length ; i ++ ){
balls[i].x += balls[i].vx;
balls[i].y += balls[i].vy;
balls[i].vy += balls[i].g;
if( balls[i].y >= WINDOW_HEIGHT-RADIUS ){
balls[i].y = WINDOW_HEIGHT-RADIUS;//小球落地的位置,垂直
balls[i].vy = - balls[i].vy*0.75;//小球弹起的速度,垂直
}
if(balls[i].x+RADIUS>0&&balls[i].x-RADIUS<WINDOW_WIDTH){
balls[cnt++]=balls[i];
}
}
while(balls.length>Math.min(300,cnt)){
balls.pop();//消除数组末尾的小球
}
炫丽的倒计时效果Canvas绘图与动画基础
96746 学习 · 1000 问题
相似问题
回答 1
回答 1