為什么要重新寫(xiě)一個(gè)for循環(huán),直接寫(xiě)在第一個(gè)循環(huán)里為什么不正常了?
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();
? ?}
? ? ? ?
}
2016-10-16
剛好在寫(xiě)這里的代碼,共同學(xué)習(xí),互相交流啦。
在這個(gè)函數(shù)里有三個(gè)循環(huán)。
前兩個(gè)for循環(huán),乍一看循環(huán)條件都是一樣的,貌似可以合并。我判斷這兩個(gè)for到底能不能合并寫(xiě)成一個(gè)for,主要是看他們是否互有影響。
老師的代碼中,第一個(gè)for在算小球下一個(gè)瞬間的運(yùn)動(dòng)位置(籠統(tǒng)地看,就是在計(jì)算每個(gè)球的運(yùn)動(dòng)軌跡),順便用if保證了碰到畫(huà)布下邊界后小球?qū)⒒貜?。第二個(gè)for,在if中限制了小球在左邊界的位置和小球在右邊界的位置。即保證小球一定出現(xiàn)在畫(huà)布上,計(jì)算所有在畫(huà)布上的小球,并把它們推到數(shù)組的最前方。這里是要得到cnt的值。內(nèi)容上看,這兩個(gè)for循環(huán)的內(nèi)容是可以合并的。
等價(jià)于
這里有個(gè)沒(méi)有聲明的默認(rèn)條件,即cnt永遠(yuǎn)小于等于balls.length,也就是說(shuō),第二個(gè)for循環(huán)的內(nèi)容不會(huì)改變balls.length的值,即不會(huì)影響 i 循環(huán)的次數(shù)。從邏輯上看,這兩個(gè)for循環(huán)的內(nèi)容也是可以合并的。所以我在代碼中把兩個(gè)for合并了,暫時(shí)未看到什么影響~
其實(shí)這也間接回答了你的問(wèn)題,因?yàn)樵趂or循環(huán)里,cnt的值是從0開(kāi)始遞增的,我們想得到的是畫(huà)布上的出現(xiàn)小球總數(shù)。而balls里面放的是所有球(即畫(huà)布上我們可視區(qū)域內(nèi)和從畫(huà)布邊緣消失的不可見(jiàn)但存在的球)。while做的事情就是去掉balls數(shù)組中我們不可見(jiàn)的球,及時(shí)縮減維護(hù)數(shù)組的總長(zhǎng)度(每個(gè)瀏覽器都對(duì)數(shù)組的最長(zhǎng)值有限制的,而且數(shù)組過(guò)長(zhǎng)還會(huì)帶來(lái)性能卡頓等等問(wèn)題,,),所以要等到 cnt 確定后再進(jìn)行操作。舉個(gè)例子,按照樓主的寫(xiě)法,如果while放在離他最近那個(gè)for循環(huán)里的話,第一次循環(huán)時(shí),i=0,cnt=1,當(dāng)?balls.length > 1 時(shí)刪除數(shù)組末尾的項(xiàng)。。。balls數(shù)組。。。就會(huì)只剩第一項(xiàng)了吧~
2016-05-20
如果要是想少寫(xiě)一個(gè)for,可以這樣寫(xiě):
??? 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();//消除數(shù)組末尾的小球
?? ?}