2

我刚开始学习 flash/actionscript 3,并决定编写一个简单的粒子模拟器。

最初的设计只是简单地用一个束粒子填充屏幕,如果你点击的话,这些粒子会从光标处散开。

这有效,但有点反应迟钝。我正在使用 graphics.drawCircle() 来绘制粒子,每个粒子都继承自 Sprite。

mouseclick 事件的监听器:

private function mouseClick(e:MouseEvent):void
{
    trace("click");
    var now:Date = new Date();
    trace("Before: "+now.getTime());
    for each (var p:Particle in particleList)
    {
        var dist:Number = distance(e.localX,e.localY,p.x,p.y);
        if (dist < 50)
        {
            var xVel:Number = p.x - e.localX;
            var yVel:Number = p.y - e.localY;

            xVel *=  Math.max(0,50 - dist) * 0.05;
            yVel *=  Math.max(0,50 - dist) * 0.05;
            p.xVel +=  xVel;
            p.yVel +=  yVel;
        }
    }

    var later:Date = new Date();
    trace("After: "+later.getTime());
    trace("Total: "+(later.getTime()-now.getTime()));

    //e.
}

在 Particle 中,有一个每帧都运行的帧侦听器:

public function loop(e:Event):void
{
    if (xVel != 0 || yVel != 0 || setup)
    {
        setup = false;
        x +=  xVel;
        y +=  yVel;


        if (x < 0)
        {
            x = 0;
            xVel =  -  xVel;
        }
        if (x > stageRef.stageWidth)
        {
            x = stageRef.stageWidth;
            xVel =  -  xVel;
        }
        if (y < 0)
        {
            y = 0;
            yVel =  -  yVel;
        }
        if (y > stageRef.stageHeight)
        {
            y = stageRef.stageHeight;
            yVel =  -  yVel;
        }


        graphics.clear();
        graphics.lineStyle(.25,0xFFFFFF,0.5);
        graphics.drawCircle(0,0,1);

        xVel *=  Engine.friction;
        yVel *=  Engine.friction;
    }

    if (xVel < 0.01 && xVel > -0.01)
    {
        xVel = 0;
    }

    if (yVel < 0.01 && yVel > -0.01)
    {
        yVel = 0;
    }
}

我应该如何提高效率?我计划稍后进行碰撞检测和其他物理交互,即使没有我打算稍后添加的大量数字运算代码,这已经有点慢了。

4

2 回答 2

3

对于太多形状,使用图形会很慢...无需对代码进行太多更改,您可以尝试在每一帧中在 BitmapData 中绘制形状(首先以单个形状或多种形状绘制它们,然后使用BitmapData 绘制然后清除所有图形)。我认为你应该得到一个小的改进。基本代码是这样的:

for(...) {
   shape.graphics.drawCircle(0,0,1);
}
bitmapData.draw(shape);
shape.graphics.clear();

另一方面,对于 1 个像素粒子,我知道的最快方法是对每个粒子使用 BitmapData 和 setPixel:

bitmapData.fillRect(bitmapData.rect, 0);
bitmapData.lock();
for(...) {
   bitmapData.setPixel(x,y,0xFFFFFF);
}
bitmapData.unlock();

对于更大或更复杂的粒子,我听说 copyPixels 是要走的路,但你需要事先对所有不同的粒子进行 blitt(不过我对这个没有太多经验,而且我发现了很多情况最好使用 BitmapData 绘制,甚至将每个 bitmapData 放在不同的精灵中):

bitmapData.fillRect(bitmapData.rect, 0);
for(...) {
   bitmapData.copyPixels(myParticle10, myParticle10.rect, new Point(tx, ty));
}

我希望这有帮助。

于 2011-05-17T08:41:20.160 回答
1

在 Actionscript 中拥有大量粒子的最好和最快的方法是将它们 blit 到位图数据。我有点喜欢粒子,我真的很喜欢这种方法。这是一个关于如何做到这一点的教程,带有一个看起来很酷的粒子效果时钟。

http://plasticsturgeon.com/2010/08/make-super-cool-as3-particle-effects-for-flash-games-with-bitmapdata/

于 2011-05-19T18:39:47.927 回答