慕函数0414863
各个小球渲染的时间不一样
qq_闎_ehpwzA
已经明白了,因为 balls 0 到 balls lenght 都是合适的小球 后面就的可以删除了
FrontEndBird
这个是因为你的时间没有设置对,倒计时结束了,所以出现上面的问题
qudawei
可以控制一下canvas上的小球数量,当小球数量达到一定值时就不画了。当切到其他页面小球不动这个是浏览器的机制。
Swatermelon
// 优化性能解决占内存问题
var cnt=0;
for(var i=0;i<balls.length;i++)
if(balls[i].x+R>0&&balls[i].x-R<WINDOW_HEIGHT)
balls[cnt++]=balls[i];
while(balls.length>cnt){
balls.pop();
}优化的这里,你写的是:
if(balls[i].x+R>0&&balls[i].x-R<WINDOW_HEIGHT)
应该是小于屏幕的宽度吧:
if(balls[i].x+R>0&&balls[i].x-R<WINDOW_WIDTH)
你应该是把宽度写成高度了
慕粉3553147
if(balls[i].x + RADIUS > 0 && balls[i].x - RADIUS < WINDOW_WIDTH);(童鞋你似乎这里写错了。。。多了个分号吧?)
balls[cnt++] = balls[i];
hahaxian321
但是这样倒计时不就不准了。。
慕丝0963956
function updateBalls () {
for (let 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.splice(i, 1);
}
}
}
慕后端9417217
而且弹出的小球弹出方向固定在分钟的第二位数。。:(求大佬帮忙看看~
喵喵小姐
那是因为cnt超过了300,Math.min只选择300或比300跟小的cnt,如果cnt超过了300那肯定选300.
慕粉1471129054
对于For循环后面的{},如果for后面只有一条语句,那么{}可写可不写,类似的,if后面的{}也是一样的;而这里的语句:
for (var i = 0; i<balls.length;i++)
if(balls[i].x + Rediaus >0 && balls[i].x - Rediaus < windowWidth )
balls[cnt++] = balls[i];
for后面只有if一条语句,而if后面也只有一条语句,所以这两者都可以不写{}
不是肥花
发个代码来看看
qq_春花花_0
不是,cnt=0; cnt++先是balls[0] = balls[i] 后再 cnt加1=1 ,后面++cnt是 cnt = 1;balls[1] = balls[i]
慕的地6791964
0<x<X轴长度,在这个范围内,小球就能看得到
标标哟
++i与i++不在赋值运算中的话,应该是相同的,都是自增,没有运算前运算后
慕粉1153222122
一种是设置全局变量,canvas就可用了,或者以 fn(time,canvas_content)方式,以参数形式同时传入时间和canvas的上下文
qq_感谢永远有歌把心境道破_03171663
if(curSeconds!==nextSeconds){
addBalls(MARGIN_LEFT+46.5*square, MARGIN_TOP, nextSeconds%10);
if(parseInt(curSeconds/10)!==parseInt(nextSeconds/10)){
addBalls(MARGIN_LEFT+39*square, MARGIN_TOP, parseInt(nextSeconds/10));
if(curMinutes%10!==nextMinutes%10){
addBalls(MARGIN_LEFT+27*square, MARGIN_TOP, curMinutes%10);
if(parseInt(curMinutes/10)!==parseInt(nextMinutes/10)){
addBalls(MARGIN_LEFT+19.5*square, MARGIN_TOP, parseInt(curMinutes/10));
if(curHours%10!==nextHours%10){
addBalls(MARGIN_LEFT+7.5*square, MARGIN_TOP, curHours%10);
if(parseInt(curHours/10)!==parseInt(nextHours/10)){
addBalls(MARGIN_LEFT, MARGIN_TOP, parseInt(curHours/10));
}
}
}
}
}
curTimeSeconds=nextTimeSeconds;
}
慕神2914858
是不是类似这样的问题:
这是要Html5中的Canvas宽度为100%,给页面添加下面的样式就可以正常显示了,并且跟着波波老师,随着对Canvas的深入学习,你可以随心所欲的制作出你想要的酷炫效果。
<style type="text/css">
*{margin: 0;padding: 0;}
body,canvas {width: 100%; height:100%;}
</style>
慕粉3584185
我觉得之所以用while而不是if,因为while是循环执行,如果满足条件会一直执行,所以不断删除满足条件的小球。而如果是if的话,那么执行一次updateBalls函数只执行一次 if也就是说只删除一个小球,while的话,执行一次upadate会执行好多次while里的代码删除多个小球。 pop执行一次删除一个,执行多次就删除多个。。。
谜语
这里有个Bug,就是离开页面以后小球会堆积或者说是小球不一会运动了。这个原因是因为我们没有停留在当前页面,计时器会照常执行但是不会一直刷新动画效果。解决这个问题的方式就是通过document.hidden来判断是否停留在当前页面,这个方式会存在兼容性问题,所以我们要这样写var hiddenProperty = 'hidden' in document ? 'hidden' :
'webkitHidden' in document ? 'webkitHidden' :
'mozHidden' in document ? 'mozHidden' :
null;
并在计时器内调用if(!document[hiddenProperty]){
render(context);
updateTime();
}else{
console.log('not current pages!');
}
苍白的尾巴
不能 delete 能把所有aball 数组删掉。
阳光正好
我也遇到这个问题,后来仔细看代码看出来了:
white(。。。)这个循环是放在for()外边的;
代码结构就是:
function{
for(if())//判断垂直
for(if())//判断水平
white()
}
我也纠结了点时间,希望这样含糊的说你能明白病解决问题
其实TAMA酱不是我名字
刚好在写这里的代码,共同学习,互相交流啦。
在这个函数里有三个循环。
前两个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数组。。。就会只剩第一项了吧~
000339043
这里有个Bug,就是离开页面以后小球会堆积或者说是小球不一会运动了。这个原因是因为我们没有停留在当前页面,计时器会照常执行但是不会一直刷新动画效果。解决这个问题的方式就是通过document.hidden来判断是否停留在当前页面,这个方式会存在兼容性问题,所以我们要这样写var hiddenProperty = 'hidden' in document ? 'hidden' :
'webkitHidden' in document ? 'webkitHidden' :
'mozHidden' in document ? 'mozHidden' :
null;
并在计时器内调用if(!document[hiddenProperty]){
render(context);
updateTime();
}else{
console.log('not current pages!');
}
暴走大熊
删除的是以整个数组为目标,当满足超出屏幕的小球就会被删除! balls.push(aBall);
//循环小球
for(var i = 0;i < digit[num].length;i++){
for(var j = 0;j <digit[num][i].length;j++){
if(digit[num][i][j] == 1){
var aBall = {
//坐标位置x
x:x+j*2*(cR+1)+(cR+1),
//坐标位置y
y:y+i*2*(cR+1)+(cR+1),
//加速度
g:1.5 + Math.random(),
//x方向速度
vx:Math.pow(-1,Math.ceil(Math.random()*1000)) * 4,
vy:-5,
color:colors[Math.floor(Math.random()*colors.length)]
}
balls.push(aBall);
}
}
}
//在屏幕中小球的数量
var cnt = 0;
for(var i = 0; i < balls.length;i++){
if(balls[i].x + cR > 0 && balls[i].x - cR < window_width){
balls[cnt++] = balls[i];
}
}
//超出屏幕小球的数量
while(balls.length > Math.min(300,cnt)){
balls.pop();
}
qq_你好世界_1
贴代码啊……你这么描述好模棱两可啊
qq_要你幸福_0
不打括号,默认只执行第一条语句的~
momoyy123
这里balls是之前定义的一个数组,balls.pop()用于删除并返回数组的最后一个元素。
shijieqianbei
并不能看出来你这上面有锯齿,或许你可以换个浏览器试试,或者换台电脑。
小kk06
自己的问题 检查代码后发现小球x轴位置判断出现问题 解决后正常运行