Форум 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=215146)

in4core 04.03.2018 16:30

Об оптимизации графики(растр/вектор) и анимаций
 
Коллеги вот такой вопрос к игроделам, которые собаку на этом съели, что будет быстрее работать. У самого очень мощный комп, и тесты провести сложновато.

Рендерим 100 кадров 3д анимации, просто тупо 100 картинок, размером от 100*100 до 300*300 например.
Загоняем во флеш. Запускаем таймер на 50-100 мс

1) Мы добавим сразу все 100 картинок в спрайт и будем менять visible по очереди.
2) Мы будем делать addChild/removeChild
3) До импорта, создаем одну большую битмапу как спрайтшит ( получается если 100 картинок по 300 (10х10) , 3000 * 3000 битмапка) добавляем ее и под маской меняем x-y битмапки
4) Аналогично пунтк 3, только добавляем одну битмапку 300*300 и потом методом draw из большой получаем bitmapData которую скармливаем этой битмапке.
5) ваш варинат

Какой из варинатов будет самым шустрым? ( мне кажется 1й будет быстрее, так как мы сразу забиваем память нужным кол-вом, и держим ее пока анимируем, чем например посл варинат, так как каждые 50 мс делать draw будет напрягать проц еще, - но могу сильно ошибаться )

--------------
Отдельный вопрос по шейпам (статика). Допустим мне надо зарисовать ( программно ) 1000 шейпов, различные фигуры. Будет ли правильным после такой зарисовки, сделать draw общего контейнера и добавить как одну битмпаку, а зарисованные шейпы просто удалить, заодно вписав их в null ?

undefined 04.03.2018 17:00

5)Загнать большую битмапдату в Bitmap и выставить ей scrollRect.По идеи это оптимизированный метод как раз для таких задач.
Цитата:

У самого очень мощный комп, и тесты провести сложновато.
Так сделай итераций побольше.Ставлю на метод 4.

Wolsh 04.03.2018 17:59

draw() медленный, самым шустрым считается copyPixels().

in4core 04.03.2018 22:21

Цитата:

draw() медленный, самым шустрым считается copyPixels().
Это какой пункт будет? И если я верно понял, копирует он с уже готовой даты, а мне с чего копировать? Или типа создать основноую битмапДату, пихать большую картинку и из нее копировать в основную?
Цитата:

5)Загнать большую битмапдату в Bitmap и выставить ей scrollRect.По идеи это оптимизированный метод как раз для таких задач.
Тесты проводились? Это самый шустрый варинат будет считаешь?

Zebestov 04.03.2018 22:59

А если сделать массив из 100500 экземпляров BitmapData и при каждой итерации bitmapData одной единственной Bitmap будет ссылаться на текущий кадр?

undefined 05.03.2018 00:29

Цитата:

Сообщение от in4core (Сообщение 1204445)
Тесты проводились? Это самый шустрый варинат будет считаешь?

Цитата:

Ставлю на метод 4.
С поправкой от Wolsh'а.
Думаю copyPixels и scrollRect дадут одинаковые результаты, но у copyPixels оверхед по памяти меньше.
Тесты никто за тебя делать не будет.

in4core 05.03.2018 00:55

Цитата:

А если сделать массив из 100500 экземпляров BitmapData и при каждой итерации bitmapData одной единственной Bitmap будет ссылаться на текущий кадр?
Не понял предложения. Если подсовывать битмапке новую битмап дату, то да будет ссылать только на нее, на конкретную.

Bletraut 05.03.2018 01:19

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

Добавлено через 6 минут
Пример кода 5-ти летней давности, нарезает длинную .png c кадрами на битмадаты и затем проигрывает их.
Код AS3:

package engine.graphic 
{
        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.events.TimerEvent;
        import flash.geom.Point;
        import flash.geom.Rectangle;
        import flash.utils.Timer;
 
        /**
        * ...
        * @author Bletraut
        */

        public class AnimatedBitmap extends Bitmap
        {
                private var _currentFrame:uint = 0;
                private var _totalFrames:uint = 0;
                private var _frameSize:Rectangle = new Rectangle(0, 0, 0, 0);
 
                private var _animationTimer:Timer;
                private var _animationDelay:Number = 100;
                private var ON_PLAY:Boolean = true;
                private var ON_PAUSE:Boolean = false;
 
                private var _framesCache:Vector.<BitmapData> = new Vector.<BitmapData>();
 
                // Set & Get
                public function get currentFrame():uint { return _currentFrame; }
                public function get totalFrames():uint { return _totalFrames; }
                public function get frameSize():Rectangle { return _frameSize; }
                public function get animationDelay():Number { return _animationDelay; }
                public function set animationDelay(n:Number):void
                {
                        if (ON_PAUSE) return;
                        _animationDelay = n;
                        if (_animationTimer.hasEventListener(TimerEvent.TIMER)) _animationTimer.removeEventListener(TimerEvent.TIMER, onTick);
                        _animationTimer = new Timer(_animationDelay);
                        _animationTimer.addEventListener(TimerEvent.TIMER, onTick);
                        if (ON_PLAY) _animationTimer.start();
                }
 
                public function AnimatedBitmap(bitmapData:BitmapData, frame:Rectangle)
                {
                        super(null, "auto", false);
 
                        _frameSize = frame;
 
                        createCache(bitmapData, _frameSize);
 
                        _animationTimer = new Timer(_animationDelay);
                        _animationTimer.addEventListener(TimerEvent.TIMER, onTick);
                        _animationTimer.start();
                        ON_PLAY = true;
                }
 
                public function play():void
                {
                        if (ON_PAUSE) return;
                        ON_PLAY = true;
                        _animationTimer.start();
                }
 
                public function stop():void
                {
                        if (ON_PAUSE) return;
                        ON_PLAY = false;
                        _animationTimer.stop();
                }
 
                public function pause():void
                {
                        if (ON_PAUSE)
                        {
                                if (ON_PLAY) _animationTimer.start();
                                ON_PAUSE = false;
                        }
                        else
                        {
                                var f:Boolean = ON_PLAY;
                                this.stop();
                                ON_PLAY = f;
 
                                ON_PAUSE = true;
                        }
                }
 
                public function gotoAndPlay(frame:uint = 0):void
                {
                        if (frame >= _totalFrames || ON_PAUSE) return;
                        _currentFrame = frame;
                        this.bitmapData = _framesCache[_currentFrame];
                        this.play();
                }
 
                public function gotoAndStop(frame:uint = 0):void
                {
                        gotoAndPlay(frame);
                        this.stop();
                }
 
                private function onTick(e:TimerEvent):void
                {
                        _currentFrame = (_currentFrame + 1 < _totalFrames) ? _currentFrame + 1 : 0;
                        this.bitmapData = _framesCache[_currentFrame];
                }
 
                private function createCache(src:BitmapData, frame:Rectangle):void
                {
                        var w:int = Math.floor(src.width / frame.width);
                        var h:int = Math.floor(src.height / frame.height);
 
                        for (var i:int = 0; i < h; i++)
                        {
                                for (var j:int = 0; j < w; j++)
                                {
                                        var b:BitmapData = new BitmapData(frame.width, frame.height, true, 0x000000);
                                        b.copyPixels(src, new Rectangle(j * frame.width, i * frame.height, frame.width, frame.height), new Point(0, 0));
                                        _framesCache.push(b);
                                }
                        }
 
                        _totalFrames = _framesCache.length;
                }
        }
 
}


Bletraut 05.03.2018 01:30

Вложений: 1
Пример портянки с кадрами
http://www.flasher.ru/forum/attachme...1&d=1520198995

Bletraut 05.03.2018 01:36

Для одинаковых объектов можно создать глобальный массив с кадрами-битмапдатами, но возможно для этого уже есть отдельная оптимизация в самом ФП, я не проверял.


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

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