在此页面https://spiritshare.org/circles.html上,我正在使用一些简单的代码来渲染一些在重力网格上移动的圆。网格沿圆形移动时的颜色给网格留下深刻的印象,然后在屏幕上绘制权重。但是某些东西正在吞噬整个宇宙,并将其像大爆炸一样倒塌到左上角!
我认为这可能是垃圾收集器,或者可能是代码中的某个数学错误? (所有数学运算都在第一页的底部)。这是相关的部分,其中颜色与圆圈混合在一起。
p = (y * fullW + x) * 3;
d = Math.sqrt(xd + yd);// * 0.5; //Math.sqrt( xd + yd );
// console.log(p);
//console.log( c.r, c.g, c.b );
if( cfg.safe_colors == true ) {
if( typeof cfg.max_color == 'undefined' ) cfg.max_color = 255;
gravity[p + 0] = (gravity[p + 0] * cfg.color_fade + cfg.color_speed * d * c.r) & cfg.max_color;
gravity[p + 1] = (gravity[p + 1] * cfg.color_fade + cfg.color_speed * d * c.g) & cfg.max_color;
gravity[p + 2] = (gravity[p + 2] * cfg.color_fade + cfg.color_speed * d * c.b) & cfg.max_color;
} else if( typeof cfg.max_color != 'undefined' ) {
gravity[p + 0] = (gravity[p + 0] * cfg.color_fade + cfg.color_speed * d * c.r);
gravity[p + 1] = (gravity[p + 1] * cfg.color_fade + cfg.color_speed * d * c.g);
gravity[p + 2] = (gravity[p + 2] * cfg.color_fade + cfg.color_speed * d * c.b);
if( gravity[p] > cfg.max_color ) gravity[p] = cfg.max_color;
if( gravity[p+1] > cfg.max_color ) gravity[p+1] = cfg.max_color;
if( gravity[p+2] > cfg.max_color ) gravity[p+2] = cfg.max_color;
} else {
gravity[p + 0] = (gravity[p + 0] * cfg.color_fade + cfg.color_speed * d * c.r);
gravity[p + 1] = (gravity[p + 1] * cfg.color_fade + cfg.color_speed * d * c.g);
gravity[p + 2] = (gravity[p + 2] * cfg.color_fade + cfg.color_speed * d * c.b);
}
一切似乎都可以正常工作,但是过了一会儿,也许当一些碎片开始堆积或者某个漏洞有机会散布在某个地方时,屏幕很快就会开始逐个堆积黑色像素。
不应该这样做...我已经对其进行了更新,因为它在更严格的CPU控制下执行的次数较少,但是当颜色变得过于浓密和模糊时仍会出现毛刺(按住B键以增加模糊,警告会消耗过多的CPU资源。
答案 0 :(得分:0)
通常,提高代码效率可以解决该问题,该问题在示例中不再存在,因此,由于我将发布分析,因此我将关闭它,随时删除或不删除它。
我认为最有可能的canvasrenderendertext.putImageData是一个线程化操作,当脚本的主要处理使用了太多的CPU时,该操作会耗尽时间来完成源图像的复制。
为解决此问题,我添加了以下处理程序以在处理重力网格时调整计时器间隔。
var gravTimeout;
function animate() {
if( !cfg.setup ) return;
var tn = new Date();
gravitate();
var tx = new Date();
var td = tx - tn;
var chg=false;
if( gravTimeout < td ) { // using too much cpu.
gravTimeout *= 1.5;
chg=true;
} else if( gravTimeout > td*2/3 ) { // going too slowly.
gravTimeout /= 1.5;
chg=true;
}
if(chg){
clearInterval(gravTimer);
gravTimer = setInterval( "animate()", gravTimeout );
if( gravTimeout > 600 )
console.log("gt="+gravTimeout);
}
//console.log(td, tn.getSeconds(), tx.getSeconds());
}