Javascript 如何使用粒子对象优化画布粒子系统
因此,我用canvas和javascript(一些jQuery)制作了一个简单的粒子系统,但在我的旧计算机上,我似乎无法使它以8fps以上的速度运行,代码如下:Javascript 如何使用粒子对象优化画布粒子系统,javascript,jquery,canvas,Javascript,Jquery,Canvas,因此,我用canvas和javascript(一些jQuery)制作了一个简单的粒子系统,但在我的旧计算机上,我似乎无法使它以8fps以上的速度运行,代码如下: var starList = []; function Star(){ this.x = getRandomInt(0, canvas.width); this.y = getRandomInt(0, canvas.height); this.vx = getRandomInt(2,5); this.s
var starList = [];
function Star(){
this.x = getRandomInt(0, canvas.width);
this.y = getRandomInt(0, canvas.height);
this.vx = getRandomInt(2,5);
this.size = this.vx/5;
this.opacity = getRandomInt(0, 5000) / 10000;
this.color = getRandomFromArray(["239, 207, 174", "162, 184, 229", "255, 255, 255"]);
this.draw = function(){
ctx.fillStyle = "rgba("+this.color+","+this.opacity+")";
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
},
this.move = function(){
this.x = this.x - this.vx;
if(this.x < 0) {
this.x = canvas.width;
this.opacity = getRandomInt(0, 5000) / 10000;
this.color = getRandomFromArray(["239, 207, 174", "162, 184, 229", "255, 255, 255"]);
this.y = getRandomInt(0, canvas.height);
this.size = this.vx/5;
this.vx = getRandomInt(2,5);
}
}
}
var canvas, ctx;
function setCanvas(){
canvas = $('canvas')[0];
ctx = canvas.getContext("2d");
canvas.width = $(window).width()/5;
canvas.height = $(window).height()/5;
}
setCanvas();
function generateStars(){
for(var i = 0; i < 5000; i++){
var star = new Star();
starList.push(star);
}
for(var i = 0; i < starList.length; i++) {
star = starList[i];
star.draw();
}
}
generateStars();
function loop() {
window.requestAnimationFrame(loop);
//clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
//draw and move stars
for(var i = 0; i < starList.length; i++) {
star = starList[i];
star.draw();
star.move();
}
}
var starList=[];
函数星(){
this.x=getRandomInt(0,canvas.width);
this.y=getRandomInt(0,canvas.height);
this.vx=getRandomInt(2,5);
this.size=this.vx/5;
this.opacity=getRandomInt(0,5000)/10000;
this.color=getRandomFromArray([“239207174”,“162184229”,“255,255,255”]);
this.draw=函数(){
ctx.fillStyle=“rgba(“+this.color+”,“+this.opacity+”);
ctx.beginPath();
ctx.arc(this.x,this.y,this.size,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
},
this.move=函数(){
this.x=this.x-this.vx;
如果(此.x<0){
这个.x=canvas.width;
this.opacity=getRandomInt(0,5000)/10000;
this.color=getRandomFromArray([“239207174”,“162184229”,“255,255,255”]);
this.y=getRandomInt(0,canvas.height);
this.size=this.vx/5;
this.vx=getRandomInt(2,5);
}
}
}
var画布,ctx;
函数setCanvas(){
画布=$('canvas')[0];
ctx=canvas.getContext(“2d”);
canvas.width=$(window).width()/5;
canvas.height=$(window.height()/5;
}
setCanvas();
函数生成器(){
对于(变量i=0;i<5000;i++){
var-star=新星();
星列表。推(星);
}
对于(var i=0;i
我假设为粒子(恒星)使用对象,并在5000个索引对象数组中循环,在处理器/gpu上执行这两个函数很困难,但如何优化此代码
我看到其他人避免在构造函数上使用函数,而是在粒子在数组中循环时移动并绘制粒子。这会使它更快吗
编辑:忽略getRandomInt和类似函数,它们是我用来生成随机内容的简单函数。代码最慢的部分是路径绘制命令:
ctx.fillStyle = "rgba("+this.color+","+this.opacity+")";
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
画布绘制速度非常快,但5000张图纸需要一些时间
相反…
创建包含要显示的所有星星变体的精灵表
将像素从精灵表复制到显示画布要比执行绘图命令快得多。尤其是绘制圆弧时,必须围绕圆周计算多个点
重要的是
限制星星的变化——观众不会注意到你的星星不是无限随机的
然后使用drawimage
的剪裁版本从精灵表中快速绘制所需的每个星星精灵:
// set the global alpha
ctx.globalAlpha = getRandomInt(0, 5000) / 10000;
// cut the desired star-sprite from the spritesheet
// and draw it on the visible canvas
ctx.drawImage( spritesheet, // take from the spritesheet
this.sheetX, this.sheetY, this.width, this.height, // at this sprite's x,y
this.x, this.y, this.width, this.height) // and draw sprite to canvas
精灵表
您可以使用第二个内存画布作为精灵表,并在应用程序首次启动时在客户端创建星形精灵。drawImage
命令将接受内存中的第二个画布作为图像源(!)
代码中最慢的部分是路径绘制命令:
ctx.fillStyle = "rgba("+this.color+","+this.opacity+")";
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
画布绘制速度非常快,但5000张图纸需要一些时间
相反…
创建包含要显示的所有星星变体的精灵表
将像素从精灵表复制到显示画布要比执行绘图命令快得多。尤其是绘制圆弧时,必须围绕圆周计算多个点
重要的是
限制星星的变化——观众不会注意到你的星星不是无限随机的
然后使用drawimage
的剪裁版本从精灵表中快速绘制所需的每个星星精灵:
// set the global alpha
ctx.globalAlpha = getRandomInt(0, 5000) / 10000;
// cut the desired star-sprite from the spritesheet
// and draw it on the visible canvas
ctx.drawImage( spritesheet, // take from the spritesheet
this.sheetX, this.sheetY, this.width, this.height, // at this sprite's x,y
this.x, this.y, this.width, this.height) // and draw sprite to canvas
精灵表
您可以使用第二个内存画布作为精灵表,并在应用程序首次启动时在客户端创建星形精灵。drawImage
命令将接受内存中的第二个画布作为图像源(!)
除此之外,它是一个不完整的列表,无法测试想法,只能转发给您-最明显的一点似乎是draw函数。绘制5000个弧似乎需要一段时间。我会试着画5000个矩形。如果这要快得多,那么画一个圆形的透明png并用构图来给它上色还是值得的。计算弧的轮廓将是缓慢的,我想这不是硬件加速。另一方面,图像混合/缩放/着色也可以。这里有一些关于时间的东西:除了它是一个不完整的列表和想法不能被测试之外,仅仅是转发给你——看起来最明显的一点似乎是draw函数。绘制5000个弧似乎需要一段时间。我会试着画5000个矩形。如果这要快得多,那么画一个圆形的透明png并用构图来给它上色还是值得的。计算弧的轮廓将是缓慢的,我想这不是硬件加速。另一方面,图像混合/缩放/着色也可以。这里有一些关于时间的东西: