addChild () - DisplayObject не виден сразу - PullRequest
2 голосов
/ 17 августа 2011

Когда я добавляю DisplayObject к DisplayObjectContainer (например, Sprite к Sprite ) в функции, кажется, что DisplayObject фактически добавляется не сразу, а после завершения функции.

См. этот пример:

package {
    import flash.display.Sprite;
    import flash.events.MouseEvent;

    public class AddChildTest extends Sprite {

        private var _sprite:Sprite;

        public function AddChildTest():void{            
            var button:Sprite = new Sprite();
            button.graphics.beginFill(0x00ff00);
            button.graphics.drawRect(0, 0, 50, 50);
            button.graphics.endFill();
            button.buttonMode = true;
            button.addEventListener(MouseEvent.CLICK, onClick);
            addChild(button);               
        }

        private function onClick(event:MouseEvent):void {
            _sprite = new Sprite();
            _sprite.graphics.beginFill(0xff0000);
            _sprite.graphics.drawRect(0, 0, 50, 50);
            _sprite.graphics.endFill();
            _sprite.x = 50;
            _sprite.y = 50;                     

            //this red sprite is not visible immediateley!
            addChild(_sprite);      

            //put something time-consuming here
            for (var i:int = 0; i < 2000; i++){
                trace(i);
            }
        }
    }
}

Итак, у нас есть простая зеленая кнопка, и когда онанажата, есть красный Sprite , построенный и добавленный к сцене.Но на самом деле красный Sprite не виден до тех пор, пока функция onClick () не будет полностью выполнена.

Почему это так и что я могу сделать для красного Sprite должен быть виден немедленно?

Есть ли какая-нибудь (для разработчика невидимая) глобальная paint () или update () функция, то естьне выполняется, пока какой-либо стек не будет полностью выполнен или что-то еще?

Ответы [ 4 ]

2 голосов
/ 17 августа 2011

Есть ли какая-нибудь (для разработчика невидимая) глобальная краска () или обновление () функция, которая не выполняется, пока какой-либо стек не будет выполнен полностью или что-то?

Да, есть что-то. Вот случайная ссылка (через гугл): http://blog.johannest.com/2009/05/22/the-movieclip-life-cycle-event-frame_constructed-and-event-exit_frame/

Ваш экран прорисовывается или перерисовывается только после выполнения всего кода кадра.

1 голос
/ 18 августа 2011

Причина в следующем:

Flash Player отображает список отображения по кадрам . Он отправляет Event.ENTER_FRAME, чтобы подготовиться к рендерингу (перемещать игровые головы в MovieClips и т. Д.), Затем Event.RENDER (предположим, вы сделали сцену недействительной), , затем визуализирует , а затем отправляет Event.EXIT_FRAME после выхода .

Следовательно, любые последующие изменения в списке отображения не будут видны до визуализации следующего кадра - если не принудительно .

Однако между выходным кадром и следующим входным кадром отправляются все события ввода-вывода и таймеры. Мышь также находится в устройстве ввода, поэтому MouseEvent с обрабатываются в данный момент.

Некоторые события - не все, но самые важные, включая MouseEvent, TimerEvent и KeyboardEvent - имеют метод updateAfterEvent, который заставит заставить флеш-плеер рендерить сразу после событие обрабатывается.

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

1 голос
/ 17 августа 2011

Это больше относится к однопоточному характеру Flash, чем к чему-либо еще.Он работает так, что выполняет любой код в ответ на событие взаимодействия (ваш код).Затем любой код, который реагирует на событие prerender (используется не так часто) и после того, как все это сделано, в конечном итоге визуализируется.

Этот поток событий уподоблен упругой беговой дорожке .

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

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

 private function onClick(event:MouseEvent):void {
    // add sprite here

    var t:Timer = new Timer(50, 1);

    // i'm using an anonymous function here, however, a proper event handler 
    // function is probably cleaner

    t.addEventListener(TimerEvent.COMPLETE, function(e:Event):void {
        //put something time-consuming here
        for (var i:int = 0; i < 2000; i++){
            trace(i);
        }
    }
    t.start();
}
1 голос
/ 17 августа 2011

Предыдущий ответ имеет отношение к построению фрейма, также имейте в виду, что доступно несколько полезных событий, которые помогут вам справиться с медлительностью списка отображения при добавлении / удалении объектов:

  private function onClick(event:MouseEvent):void {
        _sprite = new Sprite();
        _sprite.graphics.beginFill(0xff0000);
        _sprite.graphics.drawRect(0, 0, 50, 50);
        _sprite.graphics.endFill();
        _sprite.x = 50;
        _sprite.y = 50;                     

        //this red sprite is not visible immediateley!
        _sprite.addEventListener(Event.ADDED_TO_STAGE, onReady);
        addChild(_sprite);      

    }

  private function onReady(e: Event): void {

        _sprite.removeEventListener(Event.ADDED_TO_STAGE, onReady);

        //put something time-consuming here
        for (var i:int = 0; i < 2000; i++){
            trace(i);
        }
    }

Здесь прослушивается Event.ADDED_TO_STAGE перед запуском трудоемкой процедуры, поэтому экран не остается пустым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...