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

pall92 29.01.2014 22:58

Движение группы объектов. вопрос по оптимизации!
 
Столкнулся с проблемой - собственно тормозами... делаю проект, в котором на фоне падают монеты.
так вот: в среднем их одновременно на экране - около 20, ну плюс минус, но при этом возникают заметные глазу подтормаживания((( Собственно, я поискал советов по оптимизации, и парочку использовал... дело несколько улучшилось, но подвисания пока слишком заметны. эксперементальным путем установил, что они именно из-за этого элемента программы(((

Реализую я все это дело следующим образом -есть функция droping(), отвечающая за выброс монет. и функция moving() отвечающая за их падения.

первая вызывается с помощью setInterval с периодом = 350 - на практике показалось что он работает лучше таймера(вроде бы)

ну а moving -из слушателя события enterFrame.

вот. плюс положение и параметры монетки определяются с использованием math.random(), который вроде прожорливый, как говорят.

выглядит все это следующим образом:
Код AS3:

package Src {
        import flash.display.MovieClip;
        import flash.events.TimerEvent;
        import flash.events.Event;
 
        public class FallingBack extends MovieClip{
 
                //static parameters:
                static var maxDrop = 2;
                public static var addFB:Number=0;
                static var arr:Array = new Array();
                static var level = 1;
                static var nominals:Array = new Array(1,10,100,500);
                static var freq:int;
 
                static var speed:int=5;
                static var angSpeed:int = 5;
 
                var realSpeed:int;
                var realAS:int;
                //static var
                public static function droping(e=null):void
                {
 
                        //Main.THIS.ltx.text = String(arr.length);
                        //addFB = 2;
//если набралось больше одной монетки для сбрасывания, но их не больше чем критическое кол-во:
                        if(addFB >= 1 && arr.length < 26)
                        {
 
                                var t:FallingBack;
 
                                freq = int(addFB);
                                if(freq> maxDrop) freq = maxDrop;
                                //c = freqs[level];
 
 
                        //так я определяют номинал монетки
                                var nom:int;
                                for(var i:int=0; i< freq; i++)
                                {
                                        if(addFB >= 10000)
                                        {
                                                nom=6;
                                                addFB -= 10000;
                                        }
                                        else if(addFB>= 5000)
                                        {
                                                nom=5;
                                                addFB -= 1000;
                                        }
                                        else if(addFB>= 1000)
                                        {
                                                addFB -= 500;
                                                nom =4;
                                        }
                                        else if(addFB>= 500)
                                        {
                                                addFB -= 100;
                                                nom=3;
                                        }
                                        else if(addFB>= 100)
                                        {
                                                addFB -= 10;
                                                nom=2;
                                        }
                                        else
                                        {
                                                addFB --;
                                                nom=1;
                                        }
                                        t = new FallingBack(nom);
                                        Main.THIS.FB_mc.addChild(t);
                                }
 
 
                        }
 
 
                }
                public static function moving():void
                {
                        var L:int = arr.length;//обходим все созданные монетки
                        for (var key:int=L-1; key>=0; key--)
                        {
                                arr[key].mov();//двигаем с учетом персональных угловой и линейной скоростей
                                if(arr[key].y>800)
                                {
 
                                        Main.THIS.FB_mc.removeChild(arr[key]);
 
                                        arr.splice(key,1);
 
 
                                }
                        }
                }
                function mov():void
                {
                        y+= realSpeed;
                        rotation += realAS;
                }
                public function FallingBack(t:int) {
 
 
                        //определяем стартовое положение и скорости
                        gotoAndStop(t);
                        x=int(Math.random()*610)+ 110;
                        y=100;
                        //rotation = int(Math.random()*360);
                        arr.push(this);
 
                        realSpeed = speed+ int(10*Math.random());
                        //trace('speed='+realSpeed);
                        realAS = int(Math.random()*angSpeed) - angSpeed/2;
                }
 
        }
 
}


Вот. Вопрос - реально ли как-то реализовать обход 20-30ти объектов и их перемещение без чертовых тормозов? Собственно не так. Я видел, что реально... но КАК?

Буду рад любому совету, спасибо)

ps: fps= 24, имеет ли это значение вообще?

bav 29.01.2014 23:26

Вы бы выложили swf-ку, может у вас там графика навороченная, которая все и тормозит. Код, на мой взгляд, тормозным не выглядит. Можно "оптимизировать" функцию moving так:
Код AS3:

// Создать ссылку на клип, чтобы всякий раз не искать в массиве по индексу.
var clip:FallingBack;
for (var key:int=L-1; key>=0; key--)
{
        clip = arr[key] as FallingBack;
        clip.mov();//двигаем с учетом персональных угловой и линейной скоростей
        if(clip.y>800)
        {
                Main.THIS.FB_mc.removeChild(clip);
                arr.splice(key,1);
        }
}


Akopalipsis 29.01.2014 23:35

А Вы монеты всегда новые создаёте?

illuzor 29.01.2014 23:38

Поддерживаю bav. Можно ещё массивы на векторы поменять.
И ещё смысл вот этого не совсем понятен:
Код AS3:

arr.push(this);


pall92 30.01.2014 00:06

Цитата:

Сообщение от illuzor (Сообщение 1158414)
Поддерживаю bav. Можно ещё массивы на векторы поменять.
И ещё смысл вот этого не совсем понятен:
Код AS3:

arr.push(this);


ну эта строчка добавляет монетку в массив.. как иначе она там появится то?)

-------------------------
про вектор - спасибо ... надо попробовать)
-------------------------------

монеты - да, всегда новые. когда падают ниже "плинтуса" - удаляю.

Akopalipsis 30.01.2014 00:11

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

Bletraut 30.01.2014 00:11

а почему бы вам это через EnterFrame не сделать?

код действительно тормозным не выглядит.

pall92 30.01.2014 00:13

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

версия плейера - 10.3, выше не могу - ругаются используемые мной библиотеки.

Добавлено через 2 минуты
Цитата:

Сообщение от Bletraut (Сообщение 1158419)
а почему бы вам это через EnterFrame не сделать?

код действительно тормозным не выглядит.


в каком смысле? moving и вызвается по enterframe-у. а дропать монетки можно и лучше реже - визуально разницы нет, а вроде как разгружается процессор )

GBee 30.01.2014 00:16

почему бы монетке самой не падать, а достигая дна не переносится вверх и падать опять с новыми параметрами (скорости, размерами)? Это же просто дождик/снег с него многие начинали.

Akopalipsis 30.01.2014 00:16

Вектор на двадцать объектов может и в обратную сказаться.. Плюсов он не даст.

pall92 30.01.2014 00:17

вектор - исправил. (не знаю как). вроде лучше. спасибо. буду тестить)

Добавлено через 41 секунду
Цитата:

Сообщение от Akopalipsis (Сообщение 1158423)
Вектор на двадцать объектов может и в обратную сказаться.. Плюсов он не даст.

вообще я читал они быстрее работают... типизация же

Akopalipsis 30.01.2014 00:31

я тоже читал и смеялся, когда мне говорили, что вектор это корявенько, думал, ну как же это, я же читал.
А когда начал проверять, то оказалось, что он эффективен только на большом кол-ве элементов. И чтобы не соврать, я просто не помню с чем конкретно связанно, но он даже замедлял работу кода, после чего я и перестал пользоваться им. до больших объёмов ещё не дорос.

GBee 30.01.2014 00:32

Вложений: 1
Код AS3:

package 
{
        import flash.display.Sprite;
        import flash.events.Event;
 
        public class Main extends Sprite
        {
                private var _coins:Array = [];
                public function Main():void
                {
                        addEventListener(Event.ENTER_FRAME, enterFrame);
                        for (var i:int = 0; i < 1000; i++)
                        {
                                var coin:Coin = new Coin();
                                addChild(coin);
                                coin.start();
                                _coins.push(coin);
                        }
                }
 
                private function enterFrame(e:Event = null):void
                {
                        for each(var coin:Coin in _coins)
                                coin.move();
                }
        }
}

Код AS3:

package  
{
        import flash.display.Sprite;
 
        public class Coin extends Sprite
        {
                private const BOTTOM:int = 600;
                private const RIGHT:int = 600;
                private const SPEED:int = 10;
 
                private var _speed:int = 0;
                public function Coin()
                {
                        graphics.beginFill(0x0000FF);
                        graphics.drawCircle(0, 0, 10);
                        y = Math.random() * BOTTOM;
                }
 
                public function start():void
                {
                        _speed = int(Math.random() * SPEED) + 1;
                        alpha = _speed / SPEED;
                        scaleX = scaleY = alpha;
                        x = Math.random() * RIGHT;
                }
 
                public function move():void
                {
                        y += _speed;
                        if (y > BOTTOM)
                        {
                                y = -_speed;
                                start();
                        }
                }
        }
 
}

Snow.swf   (1.5 Кб)

pall92 30.01.2014 00:41

Цитата:

Сообщение от GBee (Сообщение 1158422)
почему бы монетке самой не падать, а достигая дна не переносится вверх и падать опять с новыми параметрами (скорости, размерами)? Это же просто дождик/снег с него многие начинали.

это не просто фон. я должен точно контролировать их поток)

Добавлено через 1 минуту
Цитата:

Сообщение от Akopalipsis (Сообщение 1158427)
я тоже читал и смеялся, когда мне говорили, что вектор это корявенько, думал, ну как же это, я же читал.
А когда начал проверять, то оказалось, что он эффективен только на большом кол-ве элементов. И чтобы не соврать, я просто не помню с чем конкретно связанно, но он даже замедлял работу кода, после чего я и перестал пользоваться им. до больших объёмов ещё не дорос.

я просто подглядел его использование у больших дядей) вроде в box2d он используется.. и точно в парочке алгоритмов с ним связанных....

в любом случае - мне судя по всему помогло)

Добавлено через 2 минуты
по идеи - все типизированое работает быстрее.. нет разве?

GBee 30.01.2014 00:51

Цитата:

это не просто фон. я должен точно контролировать их поток)
У вас по коду не очень понятно, что там контролировать. Тем более точно.

У вас 3 раза в секунду бегаем в цикле по огромному условию, а все остальное то же самое.

pall92 30.01.2014 00:55

кстати при тестах выявилась еще одна проблема.... часть монеток походу не удаляется... знаю это другая проблема, но не хочу новую тему открывать)

подзрения возникли после того как саметил, что длинна массива медленно но увеличивается... если не первой минуте количество монет на экране(после того как они заполнили экран) колеблется от 34 до 40.. то спустя пару минут возрастает до 40-50!

код вы видели, может кто-нибудь сказать почему это может происходить?

GBee 30.01.2014 00:58

:D Да уж
Цитата:

Код AS3:

arr.length < 26


Цитата:

колеблется от 34 до 40.. то спустя пару минут возрастает до 40-50!

pall92 30.01.2014 01:00

Цитата:

Сообщение от GBee (Сообщение 1158433)
У вас по коду не очень понятно, что там контролировать. Тем более точно.

У вас 3 раза в секунду бегаем в цикле по огромному условию, а все остальное то же самое.

ну нужно контролировать их число в частности... у меня в переменную addFB добавляется некоторое кол-во монет для сброса... и ровно столько и надо сбросить(с учетом валют, но это не важно).

а если пользоваться вашим алгоритмом, то что делать есть монетка упала, мы ее кидаем снова вверх, а падать ничего больше не должно. мы ее должны "застопорить". а запускать по надобности. ну так это будет шар вид с боку... с той лишь разницей, что мы не создаем монетку и не добавляем на сцену. но врятли это сыграет решающую роль

Добавлено через 1 минуту
Цитата:

Сообщение от GBee (Сообщение 1158435)
:D Да уж

пардон.. я тестил и убрал ограничение на длинну, чтобы проверить работу вектора)

длинна так и так не должна расти после достижения максимума.. вроде бы....

GBee 30.01.2014 01:15

Непонятный код, а где addFB растет?

pall92 30.01.2014 02:36

Цитата:

Сообщение от GBee (Сообщение 1158438)
Непонятный код, а где addFB растет?

извне) это для описываемого мной вопроса не существенно)


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

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