Руководство по actionscript. часть 4, стр. 113

4. Если необходимо, обновить экран, чтобы отразить все изменения, произошедшие на шаге 3.

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

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

7. Если необходимо, обновить экран, чтобы отразить все изменения, произошедшие на шаге 6.

8. Повторить шаги 5-7.

Шаги 5-8 из предыдущего описания процесса постоянно повторяются до тех пор, пока SWF-файл выполняется в среде Flash, привязывая тем самым последующее выполнение кода к циклу обновления экрана, который зависит от скорости кадров.

В гл. 20 мы узнали, что, когда пустая среда выполнения Flash открывает новый SWF-файл, она находит основной класс этого SWF-файла, создает его экземпляр и добавляет созданный экземпляр в список отображения в качестве первого ребенка экземпляра класса Stage. Для программ, разработанных исключительно с использованием языка ActionScript, обновление экрана происходит сразу после завершения выполнения метода-конструктора основного класса. Все последующие обновления экрана происходят в соответствии с циклом обновления экрана, описанном на шагах 5-8 предыдущего списка и зависящем от скорости кадров.

Например, рассмотрим следующую чрезвычайно простую программу рисования, которая увеличивает частоту обновления экрана среды выполнения Flash путем установки скорости кадров, равной одному кадру в секунду:

package { import flash. display.*; import flash. events.*;

public class SimpleScribble extends Sprite { public function SimpleScribble ( ) { stage. frameRate = 1;

graphics. moveTo(stage. mouseX, stage. mouseY);

stage. addEventLi stener(MouseEvent. M0USE_M0VE. mouseMoveLi stener);

}

private function mouseMoveListener (e;MouseEvent):void { graphics. lineStyle(2. OxFFOOOO); graphics. lineTo(e. stageX, e. stageY);

}

}

}

Метод-конструктор класса SimpleSribble не создает никакого графического содержимого, но регистрирует приемник mouseMoveListener ( ) для события MouseEvent. MOUSE_MOVE. При перемещении мыши метод mouseMoveLi stener ( ) рисует линию в точку, где на настоящий момент находится указатель мыши. Однако нарисованная линия не отображается на экране до следующего этапа обновления экрана, которое происходит один раз в секунду. Следовательно, каждую секунду среда выполнения Flash обновляет экран набором линий, отражающих траекторию перемещения указателя мыши в области отображения с момента последнего обновления экрана. Для более «плавного» рисования мы могли бы увеличить скорость кадров до 30 в секунду или инициировать немедленные обновления экрана, используя методики, описываемые далее, в разд. «Постсобытийные обновления экрана».

Руководство по actionscript. часть 4, стр. 114

Подведем промежуточные итоги, перечислив рассмотренные ключевые моменты.

? Система обновления экрана языка ActionScript является полностью автоматической.

? Для приложений, разработанных исключительно с использованием ActionScript, скорость кадров можно представить как количество автоматических проверок необходимости обновления экрана, проводимых средой выполнения Flash за одну секунду. Например, если скорость кадров среды выполнения Flash равна 1, все визуальные изменения, внесенные программой, будут автоматически отображаться один раз в секунду; если скорость кадров равна 10, визуальные изменения будут автоматически отображаться 10 раз в секунду (каждые 100 мс).

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

? Всякий раз, когда среда Flash выполняет проверку запланированного обновления экрана, она осуществляет диспетчеризацию события Event. ENTER_FRAME.

? Приложение Flash Player никогда не прерывает выполнение блока кода для того, чтобы обновить экран.

Последний из перечисленных моментов является чрезвычайно важным, поэтому рассмотрим его более подробно.

Никаких обновлений экрана внутри блоков кода

Повторим еще раз, что среда Flash никогда не прерывает выполнение блока кода для того, чтобы обновить экран. До того как произойдет запланированное обновление экрана, все функции в стеке вызовов и весь код в текущем кадре должны завершить свое выполнение. Подобным образом, перед тем как произойдет постсобытийное обновление экрана, приемник события, внутри которого был вызван метод updateAf terEvent ( ), должен завершить свое выполнение.

Руководство по actionscript. часть 4, стр. 115

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

В качестве золотого правила запомните, что в ActionScript обновление экрана не может произойти между двумя строками кода. Например, следующая функция displayMsg ( ) создает объект Text Fie Id и дважды устанавливает его горизонтальное положение: сначала 50, а затем 100:

public function displayMsg ( ):void { var t:TextField = new TextField( ); t. text = «Are we having fun yet?»: t. autoSize = TextFieldAutoSize. LEFT; addChild(t); t. x = 50; t. x = 100;

}

При выполнении функции displayMsg ( ) экран никогда не будет и не может быть обновлен между двумя последними строками в этой функции. В результате объект TextField никогда не появится на экране в горизонтальной позиции 50. Вместо этого выполнение функции полностью завершится перед визуализацией экрана и объект Text Field будет отображен в горизонтальной позиции 100. Хотя переменной х на самом деле кратковременно присваивается значение 50, визуальный результат этого изменения никогда не будет отображен на экране.

В некоторых случаях выполнение кода может задерживать обновления экрана на много секунд, вплоть до максимального значения, определяемого параметром компиляторатах-execution-time, которому по умолчанию присваивается значение 15. Любой сценарий, выполнение которого не завершается в течение времени, определяемого параметром max-execution-time, генерирует исключение ScriptTimeoutEr ror. Информацию по обработке этого исключения можно найти в описании исключения flash. errors. ScriptTimeoutError в справочнике по языку ActionScript корпорации Adobe.

Чтобы избежать появления исключений ScriptTimeoutError, весь код должен быть разработан таким образом, чтобы его выполнение завершалось в течение ин-

тервала, определяемого параметром компиляторатах-execution-time. Для выполнения задачи, которой требуется больше времени, чем позволяет разрешенный лимит времени, разбейте ее на части, которые могут быть выполнены в течение времени, определяемого параметром max-execution-time, а затем используйте класс Timer, чтобы организовать выполнение этих частей кода.

Установка скорости кадров

Установить скорость кадров приложения Flash Player можно одним из следующих способов:

? используя аргумент default-frame-rate компилятора mxmlc;

? в окне Document Properties (Свойства документа) среды разработки Flash;

? используя переменную экземпляра f rameRate класса Stage внутри выполняемого SWF-файла.

Руководство по actionscript. часть 4, стр. 116

Первый SWF-файл, загруженный в среду Flash, устанавливает начальную скорость кадров для всех SWF-файлов, которые будут загружены в дальнейшем.

Независимо от способа установки скорости кадров, она будет использована всеми загруженными в дальнейшем SWF-файлами (переопределяя их собственную заданную скорость кадров). Однако после загрузки первого SWF-файла установленная скорость кадров среды выполнения Flash может быть изменена переменной экземпляра f rameRate класса Stage, принимающей значения в диапазоне от 0 . 01 (один кадр каждые 100 с) до 10 0 0 (1000 кадров в секунду). Например, следующий код устанавливает скорость кадров, равную 150 кадрам в секунду:

package { import flash. display.*; public class SetFrameRate extends Sprite { public function SetFrameRate ( ) { stage. frameRate = 150;

}

}

}

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

До появления языка ActionScript 3.0 скорость кадров среды выполнения нельзя было изменять программным путем.

Назначенная скорость кадров в сравнении с реальной скоростью

Хотя среда Flash выполняет запланированные обновления экрана в соответствии со скоростью кадров, количество обновлений экрана в секунду, которое может быть

достигнуто на самом деле (реальная скорость кадров), зачастую оказывается меньше, чем скорость кадров, указанная программистом (назначенная скорость кадров). Реальная скорость кадров существенно зависит от таких факторов, как производительность компьютера, доступные системные ресурсы, физическая частота обновления устройства отображения и сложность содержимого, исполняемого в среде Flash. Следовательно, назначенную скорость кадров необходимо считать нижним пределом скорости. Реальная скорость никогда не будет меньше назначенной скорости, однако в некоторых условиях она не сможет достичь назначенной скорости кадров.

Руководство по actionscript. часть 4, стр. 117

^ I Приложение Flash Player не всегда сможет достигать назначенной скорости кадров.

—-3?’

Чтобы определить текущую назначенную скорость кадров, мы проверяем значение переменной экземпляра f rameRate класса Stage. Например, следующий класс отображает назначенную скорость кадров в объекте TextField:

package { import flash. display.*; import flash. text.*;

public class ShowFrameRate extends Sprite { public function ShowFrameRate ( ) { var t:TextField = new TextField( ); t. autoSize = TextFieldAutoSize. LEFT; t. text = stage. frameRate. toString( ); addChild(t);

}

}

}

Для того чтобы определить реальную скорость кадров, мы используем событие Event. ENTER FRAME, применяемое для измерения времени, прошедшего между проверками запланированных обновлений экрана среды выполнения Flash. Эта методика продемонстрирована в листинге 23.1. Более подробно с событием Event. ENTER_FRAME мы познакомимся в гл. 24.

Руководство по actionscript. часть 4, стр. 118

Листинг 23.1. Измерение реальной скорости кадров

package { import flash. display.*; import flash. events.*; import flash. utils.*; import flash. text.*;

public class FrameRateMeter extends Sprite { private var lastFrameTime:Number; private var output:TextField;

public function FrameRateMeter( ) { output = new TextField( ); output. autoSize = TextFieldAutoSize. LEFT; output. border = true;

output. background = true; output. selectable = false; addChild(output);

addEventListener(Event. ENTER_FRAME, enterFrameListener);

}

private function enterFrameListener (e:Event):void {

var now:Number = getTimer( );

var elapsed-.Number = now — lastFrameTime;

var framesPerSecond:Number = Math. rounddOOO/elapsed);

output. text = «Time since last frame: » + elapsed

+ «\nExtrapolated actual frame rate: » + framesPerSecond + «\nDesignated frame rate: » + stage. frameRate;

lastFrameTime = now;

}

}

}

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

Руководство по actionscript. часть 4, стр. 119

Постсобытийные обновления экрана

Из предыдущего раздела мы узнали, что запланированные обновления экрана происходят автоматически через интервалы, определяемые скоростью кадров. Мы также узнали, что визуальные изменения, вносимые приемниками событий, не отображаются до следующего запланированного этапа обновления экрана. При использовании стандартной скорости кадров, равной 24 кадрам в секунду, задержка между выполнением приемника события и отображением его визуальных результатов обычно незаметна. Тем не менее для визуальных изменений, возникающих в результате взаимодействия пользователя с мышью или клавиатурой, даже небольшие задержки могут привести к тому, что приложение будет выглядеть дрожащим или замедленным. В связи с этим язык ActionScript дает каждой функции-приемнику событий мыши и клавиатуры специальную возможность инициировать постсобытийное обновление экрана. Это обновление, которое происходит непосредственно после диспетчеризации события, перед следующим запланированным обновлением.

Для того чтобы запросить постсобытийное обновление экрана в ответ на событие мыши, мы вызываем метод MouseEvent. updateAf terEvent ( ) над объектом MouseEvent, передаваемым во все функции-приемники событий мыши. Например, следующий код вызывает постсобытийное обновление экрана в ответ на событие MouseEvent. MOUSE_MOVE:

private function mouseMoveListener (e:MouseEvent):void { e. updateAfterEvent( ); // Вызываем обновление

Чтобы запросить постсобытийное обновление экрана в ответ на событие клавиатуры, мы вызываем метод KeyboardEvent. updateAf terEvent ( ) над объектом KeyboardEvent, передаваемым во все функции-приемники событий клавиатуры. Например, следующий код вызывает постсобытийное обновление экрана в ответ на событие KeyboardEvent. KEY_DOWN:

private function keyDownListener (e:KeyboardEvent):void { e. updateAfterEvent( ); // Вызываем обновление

}

В обоих случаях вызов метода updateAf terEvent ( ) заставляет среду выполнения Flash обновить экран сразу после диспетчеризации события, перед следующим запланированным обновлением экрана. Тем не менее, хотя постсобытийное обновление экрана осуществляется перед следующим запланированным обновлением экрана, оно не произойдет до тех пор, пока все приемники событий, вызванные в процессе диспетчеризации события, не завершат свое выполнение.

^ I Как и в случае с запланированными обновлениями экрана, среда Flash никогда не преры-л * вает выполнение блока кода, чтобы осуществить постсобытийное обновление экрана. 4 4 -5л’

Пример использования метода updateAf terEvent ( ) в реальном сценарии продемонстрирован в классе пользовательского указателя мыши CustomMousePointer, который был представлен в подразд. «Определение позиции указателя мыши» разд. «События мыши» гл. 22. Класс CustomMousePointer рисует синий треугольник в объекте Sprite, представляющем указатель, и использует приемник события MouseEvent. MOUSE MOVE, чтобы реализовать перемещение этого объекта Sprite за мышью. Метод updateAf terEvent ( ) применяется внутри метода mouseMoveListener ( ) для вызова постсобытийного обновления экрана, чтобы обеспечить плавное перемещение указателя, не зависящее от скорости кадров.

Руководство по actionscript. часть 4, стр. 120

Рассмотрим код мeтoдamouseMoveListener ( ) из класса CustomMousePointer. Обратите внимание на вызов метода updateAf terEvent ( ), выделенный полужирным шрифтом:

private function mouseMoveListener (e:MouseEvent):void { // При перемещении мыши обновляем позицию пользовательского указателя // мыши, чтобы она соответствовала позиции системного указателя var pointlnParent:Point = parent. globalToLocal(new Point(e. stageX,

e. stageY));

x = pointlnParent. x; у = pointlnParent. у;

// Запрашиваем постсобытийное обновление экрана, чтобы анимация // указателя была максимально плавной е. updateAfterEvent( );

// Убеждаемся, что пользовательский указатель мыши отображается на экране // (он может быть скрыт, поскольку системный указатель мог покидать // пределы области отображения приложения Flash Player), if (!visible) f

visible = true;

}

}

Стоит отметить, что, когда среда Flash обновляет экран в ответ на вызов метода updateAf terEvent ( ), она отображает не только те изменения, которые были внесены функцией-приемником события, запросившей данное обновление, но и все визуальные изменения, произошедшие с момента последнего обновления экрана.

Руководство по actionscript. часть 4, стр. 121

Постсобытийные обновления для событий таймера

Для того чтобы разрешить обновление экрана сразу после истечения некоторого произвольного интервала времени, язык ActionScript предоставляет метод TimerEvent. updateAf terEvent ( ), который вызывает постсобытийное обновление экрана после возникновения события TimerEvent. TIMER.

Указанный метод точно так же используется внутри функций-приемников события TimerEvent. TIMER, как и методы MouseEvent. updateAf terEvent ( ) и KeyboardEvent. updateAf terEvent ( ) внутри функций-приемников событий мыши и клавиатуры.

Для демонстрации использования метода Time г Event. updateAf terEvent ( ) создадим расширенный пример, который генерирует событие TimerEvent. TIMER в десять раз чаще, чем скорость кадров среды выполнения Flash. Мы начнем с установки скорости, равной одному кадру в секунду:

stage. frameRate = 1:

Далее мы создаем объект Timer, который осуществляет диспетчеризацию события TimerEvent. TIMER каждые 100 мс (10 раз в секунду):

var timer:Timer = new TimerdOO, 0);

Затем мы регистрируем функцию-приемник timerListener ( ) в объекте timer для событий TimerEvent. TIMER, как показано в следующем коде:

timer. addEventListener(TimerEvent. TIMER, timerListener);

После этого мы запускаем таймер:

timer. start( );

Теперь внутри функции timerListener ( ) рисуем прямоугольник и помещаем его в случайное место на экране. Для того чтобы гарантировать, что прямоугольник появится на экране сразу после завершения процесса диспетчеризации события TimerEvent. TIMER (а не на следующем запланированном этапе обновления экрана), мы используем метод TimerEvent. updateAf terEvent ( ) для запроса постсобытийного обновления экрана. Рассмотрим получившийся код для метода timerListener ( ):

private function timerListener (e:TimerEvent):void { // Создаем прямоугольник var rect:Sprite = new Sprite( ); rect. graphi cs.1i neStyle(1); rect. graphics. beginFill(OxOOOOFF); rect. graphics. drawRect(0, 0, 150, 75);

rect. x = Math. floor(Math. random( )*stage. stageWidth); rect. у = Math. f1oor(Math. random( )*stage. stageHeight);

// Добавляем прямоугольник на экран addChild(rect):

// Запрашиваем постсобытийное обновление экрана e. updateAfterEvent( );

}

В результате такого вызова метода TimerEvent. updateAf terEvent ( ) отображение визуальных изменений, вносимых внутри метода timerListener ( ), происходит приблизительно каждые 100 мс, а не раз в секунду.

Руководство по actionscript. часть 4, стр. 122

Для информации следующий код демонстрирует наш предыдущий сценарий с таймером в контексте класса RandomRectangles:

package { import flash. display.*; import flash events.*; import flash. utils.*;

public class RandomRectangles extends Sprite { public function RandomRectangles ( ) { stage. frameRate = 1; var timer:Timer = new TimerdOO, 0); timer. start( );

timer. addEventLi stenerdimerEvent. TIMER, timerListener);

}

private function timerListener (e:TimerEvent):void { var rect:Sprite = new Sprite( ); rect. graphi cs.1i neSty1e(1): rect. graphics. beginFill(OxOOOOFF); rect. graphics. drawRectCO. 0. 150. 75); rect. x = Math. f1oor(Math. random( )*stage. stageWidth); rect. у = Math. f1oor(Math. random( )*stage. stageHeight);

addChild(rect);

e. updateAfterEvent( )

}

}

}

В гл. 24 мы продолжим наше изучение класса Timer, применяя его для создания движения и других форм анимации.



Полезные ссылки
Случайные записи
  • 01.03.2011">Руководство по actionscript. часть 5, стр. 122
  • 09.03.2011">Руководство по actionscript. часть 4, стр. 046
  • 15.03.2011">Руководство по actionscript. часть 3, стр. 035
  • 17.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.7
  • 11.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.9
  • 19.07.2012">На серверах Dropbox произошла утечка адресов e-mail
  • 21.03.2011">Руководство по actionscript. часть 2, стр. 048
  • 22.03.2011">Руководство по actionscript. часть 2, стр. 002
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.59
  • 22.01.2011">Руководство по actionscript. часть 1, стр. 128
  • 17.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.114
  • 24.02.2011">Руководство по actionscript. часть 6, стр. 105
  • 04.03.2011">Руководство по actionscript. часть 5, стр. 049
  • 04.03.2011">Руководство по actionscript. часть 5, стр. 042
  • 23.02.2011">Руководство по actionscript. часть 7, стр. 041
Опрос

Какие цвета вы предпочитаете?

View Results

Loading ... Loading ...