#flash #actionscript #graphics #performance #particles
#flash #actionscript #графика #Производительность #частицы
Вопрос:
Я только начинаю изучать 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 amp;amp; xVel > -0.01)
{
xVel = 0;
}
if (yVel < 0.01 amp;amp; yVel > -0.01)
{
yVel = 0;
}
}
Как мне сделать это более эффективным? Я планирую позже выполнять обнаружение столкновений и другие физические взаимодействия, и это уже немного медленно, даже без большого кода для обработки чисел, который я собираюсь добавить позже.
Комментарии:
1. ИМХО, самый быстрый вариант — метод SetPixel из ответа @ Cay. Если вам нужны частицы несколько большего размера, вы можете установить три / четыре / сколько угодно пикселей для каждой. Но если частицы действительно большие, используйте
BitmapData.draw
.
Ответ №1:
Использование графики довольно медленно для слишком большого количества фигур… Без особых изменений в вашем коде вы могли бы попробовать каждый кадр рисовать свои фигуры в 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 draw или даже иметь каждый BitmapData в другом спрайте):
bitmapData.fillRect(bitmapData.rect, 0);
for(...) {
bitmapData.copyPixels(myParticle10, myParticle10.rect, new Point(tx, ty));
}
Я надеюсь, что это поможет.
Комментарии:
1. Копипиксели будут хороши только для прямоугольных, не так ли? Если частица имеет прозрачные края, ее нужно нарисовать, а не просто скопировать.
2. У меня должен быть только 1 экземпляр bitmapdata, верно? Не по одной на частицу
3. Только один. Ваш экран отрисован на больших bitmapdata, particle — это всего лишь пиксель на нем.
Ответ №2:
Лучший и быстрый способ получить огромное количество частиц в Actionscript — это перенести их в bitmapdata. Я своего рода помешан на частицах, и мне действительно нравится этот метод. Вот руководство о том, как это сделать, с классно выглядящими часами с эффектом частиц.