Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用粒子对象优化画布粒子系统_Javascript_Jquery_Canvas - Fatal编程技术网

Javascript 如何使用粒子对象优化画布粒子系统

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

因此,我用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.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并用构图来给它上色还是值得的。计算弧的轮廓将是缓慢的,我想这不是硬件加速。另一方面,图像混合/缩放/着色也可以。这里有一些关于时间的东西: