Руководство по 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, применяя его для создания движения и других форм анимации.

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

Ш4_ Q Метод setlnterval() языка ActionScript 2.0 может также использовать метод updateAfterEvent() } для вызова постсобытийного обновления экрана, однако вместо метода setlnterval() предпочтительнее использовать класс flash. utils. Timer, поскольку он предоставляет возможность запускать и останавливать события таймера, а также уведомлять о таймерных событиях сразу несколько приемников. Старайтесь избегать использования метода setlnterval() в языке ActionScript 3.0.

Автоматические постсобытийные обновления экрана

В приложении Flash Player 9 определенные «кнопочные» взаимодействия с объектами любого класса, наследуемого от класса Sprite, приводят к автоматическому постсобытийному обновлению экрана (аналогично тому, как программист вызывает метод updateAf terEvent ( ) ). В частности, автоматическое постсобытийное обновление экрана будут вызывать следующие взаимодействия:

? перемещение указателя мыши над экземпляром класса, который наследуется от класса Sprite, или за пределы этого экземпляра;

? нажатие или отпускание основной кнопки мыши, когда указатель мыши находится над экземпляром класса, наследуемого от Sprite;

? использование клавиши Пробел или Enter для активизации экземпляра класса, наследуемого от класса Sprite.

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

Область перерисовки

Как уже известно из разд. «Запланированные обновления экрана», среда выполнения Flash обновляет экран только в тех случаях, когда это необходимо (то есть когда графическое содержимое было изменено или добавлено). Точнее говоря, когда среда выполнения обновляет экран, она визуализирует только те области, которые изменились с момента последнего обновления. Например, представим анимацию, состоящую из двух кадров, первый из которых содержит круг, а второй — тот же круг, но вместе с треугольником. Когда среда Flash визуализирует второй кадр, она перерисовывает прямоугольную область, содержащую треугольник, но не перерисовывает круг. Прямоугольная область, включающая все содержимое, которое было изменено, называется областью перерисовки (в программировании графики данная область иногда называется измененным прямоугольником).



Полезные ссылки
Случайные записи
  • 23.02.2011">Руководство по actionscript. часть 7, стр. 037
  • 22.03.2011">Руководство по actionscript. часть 2, стр. 015
  • 17.03.2011">Руководство по actionscript. часть 3, стр. 006
  • 04.03.2011">Руководство по actionscript. часть 5, стр. 026
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 024
  • 06.03.2011">Руководство по actionscript. часть 4, стр. 151
  • 11.03.2011">Руководство по actionscript. часть 3, стр. 153
  • 03.06.2010">Самоучитель по креативному веб-дизайну. Книга 3, стр.90
  • 02.03.2011">Руководство по actionscript. часть 5, стр. 099
  • 28.02.2011">Руководство по actionscript. часть 6, стр. 015
  • 24.02.2011">Руководство по actionscript. часть 7, стр. 002
  • 02.03.2011">Руководство по actionscript. часть 5, стр. 085
  • 18.03.2011">Руководство по actionscript. часть 2, стр. 127
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.120
  • 10.08.2011">Педиатр – лучший друг молодых родителей
Опрос

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

View Results

Loading ... Loading ...