Низкая производительность (?) С 200 движущимися кругами в Starling
У меня есть этот код, который рисует анимацию в виде дождя с 200 круговыми формами. В основном 200 круговых фигур со случайными значениями x, y, радиусом и скоростью, которые идут сверху вниз и сбрасываются обратно на вершину в случайном порядке x (снова), когда он существует на экране... на LG G2 я получаю 26FPS с 200 кругами, и я подозреваю, что я делаю что-то не так, так как я знаю, что Старлинг может сделать НАМНОГО лучше, чем это...
Главный:
[SWF(width="640", height="960", frameRate="60", backgroundColor="#ffffff")]
public class ParticleTest extends Sprite
{
private var _starling:Starling;
public function ParticleTest()
{
var screenWidth:int = stage.fullScreenWidth;
var screenHeight:int = stage.fullScreenHeight;
var viewPort:Rectangle = new Rectangle(0, 0, screenWidth, screenHeight)
_starling = new Starling(Particle, stage, viewPort);
_starling.stage.stageWidth = 640;
_starling.stage.stageHeight = 960;
_starling.showStats = true;
_starling.start();
}
}
Particle:
private var particles:Array = [];
public function Particle()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(event:Event):void {
for (var i:int=0;i<200;i++) {
particles[i] = new Circle();
addChild(particles[i]);
}
addEventListener(Event.ENTER_FRAME, update);
}
private function update(event:Event):void {
for (var i:int=0;i<particles.length;i++) {
particles[i].update();
}
}
Круг:
private var _x:int = 0;
private var _y:int = 0;
private var _speed:int = 0;
private var _radius:int = 0;
private var _color:uint = 0x000000;
private var MIN_RADIUS:int = 2;
private var MAX_RADIUS:int = 14;
private var MIN_SPEED:int = 8;
private var MAX_SPEED:int = 14;
private var COLORS:Array = [0xff7729, 0x1ab58a, 0xffebca, 0xff2151, 0xffad29];
private var _shape:Shape = new Shape();
private var _graphics:Graphics = _shape.graphics;
private var _bmpData:BitmapData;
private var _image:Image;
public function Circle()
{
shuffle();
init();
draw();
}
private function shuffle():void {
this._radius = Math.floor(Math.random() * this.MAX_RADIUS) + this.MIN_RADIUS;
this._color = this.COLORS[Math.floor(Math.random() * this.COLORS.length)];
this._speed = Math.floor(Math.random() * this.MAX_SPEED) + this.MIN_SPEED;
this._x = Math.floor(Math.random() * Starling.current.nativeStage.stageWidth);
this._y = Math.floor(Math.random() * Starling.current.nativeStage.stageHeight) - Starling.current.nativeStage.stageHeight;
}
private function init():void {
this._graphics.clear();
this._graphics.beginFill(this._color, 1);
this._graphics.drawCircle(this._radius, this._radius, this._radius);
this._graphics.endFill();
this._bmpData = new BitmapData(this._radius*2, this._radius*2, true, 0x000000);
this._bmpData.draw(this._shape);
this._image = Image.fromBitmap(new Bitmap(this._bmpData, "auto", true));
addChild(this._image);
}
private function draw():void {
this._image.x = this._x;
this._image.y = this._y;
}
public function update():void {
this._image.x = this._x;
this._image.y += this._speed;
if (this._image.y > Starling.current.nativeStage.stageHeight) {
shuffle();
draw();
}
}
Я делаю это неправильно? Есть ли лучший способ добиться того же эффекта?
Спасибо!
1 ответ
Решение
Вы не можете копировать и вставлять старый код из классического AS3 в Starling, вам нужно использовать новую логику, чтобы оптимизировать и использовать преимущества
private var particles:Array = [];
private var speeds:Array = [];
private var MAX_SPEED = 10;
private var MIN_SPEED = 1;
private var filter0:ColorMatrixFilter = new ColorMatrixFilter();
private var filter1:ColorMatrixFilter = new ColorMatrixFilter();
private var filter2:ColorMatrixFilter = new ColorMatrixFilter();
private var filter3:ColorMatrixFilter = new ColorMatrixFilter();
private var filter4:ColorMatrixFilter = new ColorMatrixFilter();
private var COLORS:Array = [filter0, filter1, filter2, filter3, filter4];
// Embed the texture:
[Embed(source="circle.png")] //<---- EMBED A CRICLE PNG
public static const Circle:Class;
public function Particle()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
var texture:Texture = Texture.fromBitmap(new Circle());
private function init(event:Event):void {
filterRed.tint(0xff7729, 1);
filterRed.tint(0x1ab58a, 1);
filterRed.tint(0xffebca, 1);
filterRed.tint(0xff2151, 1);
filterRed.tint(0xffad29, 1);
for (var i:int=0;i<200;i++) {
particles[i] = new Image(texture);
shuffle(i);
addChild(particles[i]);
}
addEventListener(Event.ENTER_FRAME, update);
}
private function update(event:Event):void {
for (var i:int=0;i<particles.length;i++) {
update(i);
}
}
public function update(imageID:int):void {
particles[imageID].x = x;
particles[imageID].y += speeds[imageID];
if (_image.y > Starling.current.nativeStage.stageHeight) {
shuffle(i);
}
}
public function shuffle(i:int):void {
particles[i].scaleX = particles[i].scaleY = Math.floor(Math.random() * this.MAX_RADIUS/particles[i].width) + this.MIN_RADIUS/particles[i].width;
particles[i].filter = this.COLORS[Math.floor(Math.random() * this.COLORS.length)];
speeds[i] = Math.floor(Math.random() * this.MAX_SPEED) + this.MIN_SPEED;
particles[i]._x = Math.floor(Math.random() * Starling.current.nativeStage.stageWidth);
particles[i]._y = Math.floor(Math.random() * Starling.current.nativeStage.stageHeight) - Starling.current.nativeStage.stageHeight;
}