Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Оптимизация. на примере таблоида. (http://www.flasher.ru/forum/showthread.php?t=118498)

gen4 25.11.2008 19:14

Оптимизация. на примере таблоида.
 
Вложений: 1
делаю визуальный эфект напоминающий таблоид - массив "пикселей"-объектов, меняющих цвет или форму по какому-нибудь заданному алгоритму.

Стоило мне расставить около 3000 таких объектов и заставить их менять размер, фпс уже не поднимется выше 15.

Не думаю, что расчетов тут больше, чем, скажем, в 3д-движке, или 2д-физике.


Вывод: я делаю что-то координально неправильно)

Вопрос: Что именно? Какие подходы использовали бы Вы?

код 2х классов.

Код:

public class Main extends Sprite
        {
               
                private var radius:uint = 10;
                private var tArray:Array = new Array();
                private var table:Sprite = new Sprite();
                private var bmd:BitmapData = new BitmapData(800, 400, true, 0x00FF33bb);//
                private var bm:Bitmap = new Bitmap(bmd);
                private var nullRect:Rectangle = bmd.rect;
                private var frame:uint = 0 ;
                private var field:Boolean = false ;
               
                public function Main() {
                        fillTabloid();
                        addChild(table);
                        addChild( new Stats() )
                        addEventListener(Event.ENTER_FRAME, render);
                }
               
               
                private function render(ev = null) {
                        for (var i = 0; i < tArray.length;i++ ) {
                                        tArray[i].anim(frame);
                                }
                        frame++;
                }
               
                private function fillTabloid() {
                        for (var i = 0; i < 80; i++) {
                                for (var j = 0; j < 40; j++) {
                                        var t = new Tabl(i*radius*2, j*radius*2, radius);
                                        table.addChild(t);
                                        tArray.push(t);
                                }
                        }
                }
        }


Код:

        import flash.display.Shape;
        import flash.events.*;
       
        /**
        * ...
        * @author DefaultUser (Tools -> Custom Arguments...)
        */
        public class Tabl extends Shape
        {
                private var radius:uint;
                private var brightness:Number;
                private var offless:Number;
                private var frame:uint  = Math.round(Math.random() * 1000);
                private var tmp:uint = 0 ;
                private var color:Number = 0xFFFFFF * Math.random();
               
                public function Tabl(xx,yy,rr) {
                        x = xx;
                        y = yy;
                        radius = rr;
                }
               
               
                public  function  anim(f:uint) {
                        var n =        this.graphics;
                        n.clear();
                        var aa = (1 + Math.sin((frame + f) * 0.1)) * 0.5;
                        n.beginFill(color, aa);
                        n.drawCircle(0, 0, radius * aa);
                        n.endFill();
                       
                }

        }


BoUnd 26.11.2008 00:36

Вся оптимизация в рамках данной задачи - полная реорганизация алгоритма. Обновлять 3000 объектов в каждом кадре, нельзя отнести к удачной затее. На практике, в рамках одной задачи, даже простые внешние изменения с количеством графических объектов порядка 500 могли приводить к значительной потере производительности.

ZlPredator 26.11.2008 03:01

Во первых, не помешает объявлять тип локальных переменных (особенно важно для объектов). Иначе плеер будет при каждом вашем обращении к свойству или методу искать по таблице методов нужный (вместо быстрого вызова).

Во вторых, векторная графика требует много ресурсов (учитывая antialias краев и возможность сложных заполнителей). Необходимо избегать большого количества векторной графики и особенно ее постоянного изменения. Лучше было использовать свойства alpha и scale, чем постоянно перерисовывать. Еще можно попробовать создавать битмап по вектору и уже работать с ним:

Код AS3:

public class Tabl extends Sprite 
{
        private var radius:uint;
        private var frame:uint  = Math.round(Math.random() * 1000);
        private var color:Number = 0xFFFFFF * Math.random();
 
        public function Tabl(xx,yy,rr) {
                x = xx;
                y = yy;
                radius = rr;
                var n:Graphics = this.graphics;
                n.clear();
                n.beginFill(color);
                n.drawCircle(0, 0, radius);
                n.endFill();
                var b:BitmapData = new BitmapData(radius*2,radius*2);
                var m:Matrix = new Matrix();
                m.translate(radius,radius);
                b.draw(this,m);
                n.clear();
                var bmp:Bitmap = new Bitmap(b,"auto",true);
                bmp.x = bmp.y = -radius;
                addChild(bmp);
        }
 
        public  function  anim(f:uint):void
        {
                var aa:Number = (1 + Math.sin((frame + f) * 0.1)) * 0.5;
                alpha = aa;
                width = height = radius * aa;
        }
 
}

Если известно что фон фиксированного цвета, можно убрать альфа канал в изображении (будет быстрее).

Если и это не помогает, то необходимо уменьшать количество элементов (или площади перерисовки) или уменьшать качество отрисовки.

gen4 26.11.2008 14:36

ZlPredator: да, битмап в этом виде - хорошая затея, попробую.

BoUnd: Намекните, в пользу чего реорганизовывать?

Добавлено через 25 минут
ZlPredator: битмап в предложнном виде прироста производительности не дал, вопреки ожиданиям (

ZlPredator 26.11.2008 17:04

Можно еще попробовать альфа канал не использовать.

В теории от количества объектов не должно сильно зависеть (скорее от площади перерисовки). Если такая зависимость все таки есть, то можно попробовать разбить на небольшие блоки. Например, создать спрайты для каждой строки, добавить их на экран, а Tabl добавлять в спрайт конкретной строки (такая оптимизация ускоряет прорисовку при добавлении/удалении объектов, поможет ли она для этого случая - не знаю, необходимо пробовать).

Если нету наложений объектов друг на друга (наш случай), то в теории скорость можно довести до fps отрисовки битмапы на весь экран с включенным сглаживанием (кстати, сделал бы тест у себя - заодно узнал эту скорость).


Часовой пояс GMT +4, время: 18:45.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.