Эффективный способ перерисовать сотни частиц во вспышке? - PullRequest
2 голосов
/ 17 мая 2011

Я только начинаю изучать flash / actionscript 3 и решил написать простой симулятор частиц.

Сам первоначальный дизайн просто включает заполнение экрана кучкой частиц, которые рассеиваются от курсора, если вы нажмете.

Это работает, но немного не отвечает. Я использую graphics.drawCircle () для рисования частиц, и каждая частица наследуется от Sprite.

Слушатель события щелчка мышью:

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;
    }
}

Как мне сделать это более эффективным? Я планирую сделать обнаружение столкновений и другие физические взаимодействия позже, и это уже немного медленно, даже без большого кода, который я собираюсь добавить позже.

Ответы [ 2 ]

3 голосов
/ 17 мая 2011

Использование графики довольно медленно для слишком большого числа фигур ... Без особых изменений в вашем коде вы можете попытаться каждый кадр рисовать свои фигуры в BitmapData (либо сначала нарисовать их в одной фигуре, либо во многих фигурах, а затем используйте BitmapData draw, а затем очистите всю вашу графику). Я думаю, что вы должны получить небольшое улучшение. Основной код такой:

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 - это то, что нужно, но вам нужно заранее пометить все ваши различные частицы (хотя у меня нет большого опыта с этим, и я Было много ситуаций, когда было лучше использовать рисование BitmapData или даже иметь каждый bitmapData в другом спрайте):

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

Надеюсь, это поможет.

1 голос
/ 19 мая 2011

Лучший и самый быстрый способ иметь огромное количество частиц в Actionscript - это преобразовать их в растровые данные.Я отчасти схожу с ума по частицам, и мне очень нравится этот метод.Вот учебник о том, как это сделать, с классно выглядящими часами с эффектом частиц.

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

...