В этом уроке:
tTimer() для точного отсчета времени – на примере 
Часть проекта Make My
Day , который мы с вами построим в этом уроке.
На выполнение этого урока требуется примерно один час.
Файлы-носители:
Нет
Стартовые файлы:
Lesson15/Assets/makeMyDay1.fla Lesson15/Assets/preloader1.fla
Законченные проекты:
makeMyDay4.fla preloader2.fla
Бонус:
preloaderBytes.fla
Для измерения времени во
Используя эти элементы, вы можете снабдить свой проект следующими возможностями:
В , позволяющий вызывать какую-либо функцию раз за разом с определенным интервалом (измеряемым в миллисекундах). Для примера рассмотрим такой скрипт:
function rotateClip() {
myMovieClip._rotation += 10;
}
setInterval (rotateClip, 1500);
В первых трех строках описана функция. Затем следует действие , вызывающее функцию rotateClip() каждые полторы секунды (1000 миллисекунд = 1 секунде).
Если вызываемой функции требуется передать значения аргументов, они просто добавляются в качестве параметров действия :
setInterval (updateMessageFunction, 2000, "Hello", arg2, arg3);
Действие можно включать и отключать – для этого следует "присвоить" ему
myVariable = setInterval (rotateClip, 1500);
Тем самым имя myVariable назначается данному действию . Теперь, чтобы прекратить выполнение действия , достаточно использовать следующую команду:
delete myVariable;
Действие можно инициировать в любое время, например, вставив его вызов в какую-либо функцию. В следующем уроке мы с вами применим это действие для создания вращающихся рекламных
Все мы пользуемся календарем; многие вообще не представляют себе, как можно без него обойтись – ведь нужно планировать свои дела на будущее и т.д.. Во
Чтобы использовать во Date:
myDate = new Date(year, month, date);
Эта строка скрипта создает новый объект Date под именем myDate. Параметры в скобках связывают этот объект с определенной датой. Например:
myDate = new Date(66, 6, 27);
Этим скриптом будет создан новый объект Date, связанный с 27 июля 1966 года. Первый параметр определяет год, второй – месяц, третий – день. Кстати, не удивляйтесь, тут нет никаких опечаток, хотя июль – седьмой месяц, а в скрипте указано 6. Дело в том, что в
Примечание Числа месяцев и годы имеют истинные значения. Так, 66 соответствует 1966 году, а 27 – 27-му дню месяца.

Совет Список параметров создаваемого объекта можно продолжить, указав час, минуту, секунду и миллисекунду, если в вашем приложении нужна такая точность.
Если нужно создать объект Date, содержащий текущую дату и время (по системным часам компьютера), достаточно просто не указывать параметры, оставив скобки конструктора объекта пустыми. Например:
myDate = new Date();
После того, как объект Data создан, можно извлечь из него любую информацию о хранящейся в нем дате при помощи соответствующих методов. Возьмем предыдущий пример – объект, содержащий текущую системную дату. Чтобы выяснить, какой сейчас месяц, мы используем следующий синтаксис:
currentMonth = myDate.getMonth();
После выполнения этой строки переменная currentMonth получит числовое значение, например, 5 – это будет означать месяц июнь. Чтобы узнать день недели, используем другой метод:
currentDay = myDate.getDay();
После выполнения этой строки переменная currentDay получит числовое значение, например, 4, что соответствует четвергу.
Примечание Проект может содержать несколько объектов Data, предназначенных для разных целей.
В следующем упражнении мы создадим объект Data и применим различные методы для отображения текущей даты на экране.
Этот проект состоит из двух сцен –
Непосредственно под надписью "Today is:" вы видите четыре текстовых поля. Называются они (по порядку сверху вниз) currentDay, currentMonth, currentDate и currentYear. В этих полях будут динамически отображаться составляющие текущей даты:
В каждом поле стиль текста будет разным, чтобы наш календарь выглядел красиво.

В самом низу этого окна вы видите бессмысленный набор букв. Эти буквы – набор символов, специфическое начертание которых мы хотим внедрить в фильм для этого поля. Названия всех дней недели состоят только из букв, которые здесь перечислены. Это текстовое поле будет содержать динамически генерируемый текст, и внедрение шрифта позволит отображать текст в этом поле со
Для прочих текстовых полей календаря тоже указан тот или иной внедряемый набор символов (в зависимости от того, что должно отображать каждое поле).

stop(); today = new Date();
Первое действие воспрещает дальнейшее воспроизведение монтажного стола до особых на то указаний.
Следующая строка скрипта создает новый объект Date под именем today, как только начнется воспроизведение фильма. Поскольку в скобках мы не указали особых значений параметров, этот объект Data будет содержать текущую системную дату на компьютере пользователя (на момент воспроизведения фильма).
nameOfDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; nameOfMonths = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
Первая строка создает массив под названием nameOfDays ; вторая строка – массив nameOfMonths. Каждый массив содержит набор строковых значений, представляющих собой, соответственно, названия дней недели и месяцев. Для чего нужны эти массивы? Ну, это ведь люди называют дни и месяцы разными словами, а
currentDay.text = nameOfDays[today.getDay()];
Этим действием мы выводим информацию в текстовом поле currentDay. Поясним, как это получается.
С помощью метода getDay() (в квадратных скобках) мы определяем день недели даты, хранящейся в объекте today. Этот метод возвратит некое значение от 0 до 6 (напомним, 0 соответствует воскресенью, 6 – субботе). Допустим, метод вернул значение 3; это значение подставляется вместо выражения в квадратных скобках, и мы получаем такую строку:
currentDay.text = nameOfDays[3];
Как видите, в поле currentDay будет отображено значение элемента с индексом 3 массива nameOfDays, то есть строковое значение "Wednesday". Как видите, мы, зная, что метод getDay() выдает числовые значения от 0 до 6, создали на предыдущем шаге массив, элементами которого являются названия дней недели, причем этих элементов имеют индексы тоже от 0 до 6.
currentMonth.text = nameOfMonths[today.getMonth()];
Этим действием мы выводим информацию в текстовом поле currentMonth. Принцип действия тот же, что и на предыдущем шаге – метод getMonth() выдает некоторое числовое значение от 0 до 11, из массива nameOfMonths берется строковое значение элемента с соответствующим индексом.
currentDate.text = today.getDate();
Это действие выводит информацию в текстовом поле currentDate. Здесь использован метод getDate(), возвращающий числовое значение от 1 до 31, соответствующее числу месяца для даты, хранящейся в объекте today. В данном случае нам требуется именно число, поэтому никакого массива для преобразования номера в строку здесь не нужно.
currentYear.text = today.getFullYear();
Это действие выводит информацию в текстовом поле currentYear. Здесь использован метод getFullYear(), возвращающий числовое значение, соответствующее году даты, хранящейся в объекте today (например, 2002). В данном случае опять нас вполне устраивает число, и массива для преобразования в строку не требуется.
Как только фильм запустится, текстовые поля календарного листка на экране заполнятся информацией, соответствующей сегодняшней дате.

Мы продолжим работу с этим проектом в следующем упражнении урока.
Функция getTimer() возвращает время (в миллисекундах), прошедшее с момента запуска фильма. Если, к примеру, на момент вызова этой функции фильм воспроизводится уже шесть секунд, то скрипт
playBackTime = getTimer();
присвоит переменной playBackTime значение 6000 (1000 миллисекунд в каждой секунде). Это – точное время, отсчитываемое по системным часам пользовательского компьютера; оно не зависит ни от частоты кадров фильма, ни от быстродействия процессора, ни от того, воспроизводится ли фильм или стоит на одном и том же кадре. Подчеркнем, что функция возвращает время, прошедшее с момента запуска всего фильма, а не отдельных монтажных столов.
Промежуток времени между двумя событиями внутри фильма все же можно измерить. Для этого следует в нужный момент присвоить какой-либо переменной значение, возвращенное функцией getTimer(), а потом сравнить с этой переменной новое значение, возвращенное функцией. Поясним это на следующем примере:
// Скрипт для кнопки A
on (release) {
startTime = getTimer();
}
// Скрипт для кнопки B
on (release) {
nowTime = getTimer();
if (nowTime – startTime < 1000) {
message.text = "Вы нажали кнопку слишком быстро";
} else {
message.text = "Слишком поздно";
}
}
Здесь, если нажата и отпущена одна из кнопок (кнопка A), фиксируется стартовая точка отсчета времени. Когда нажата и отпущена кнопка B, время снова фиксируется.
on (release) {
if (getTimer() – lastClick < 500) {
// Действия
}
lastClick = getTimer();
}
Используя функцию getTimer() совместно с событием enterFrame и
onClipEvent (enterFrame) {
if (getTimer() > 5000) {
// Действия
}
if (getTimer() > 10000) {
// Действия
}
if (getTimer() > 15000) {
// Действия
}
}
Этот скрипт будет выполнять действия каждые пять секунд по ходу воспроизведения фильма – зачастую это единственный способ, если требуется точный отсчет времени.
В следующем упражнении мы с вами, используя функцию getTimer(), создадим
Примечание Функцию getTimer() можно найти в списке инструментов панели Действия в разделе Functions.

Мы продолжаем работу над проектом, начатым в предыдущем упражнении. Напомним, что в этом файле имеется две сцены, minutesToAlarm, secondsToAlarm и numberOfLoops (сверху вниз). Это текстовые поля для ввода; первые два предназначены для установки времени, по прошествии которого должен сработать будильник, третье будет определять, сколько раз будильник должен прозвонить.
Ниже этих текстовых полей находится кнопка Start, которой будет запускаться
Под этой кнопкой расположен экземпляр фильма-символа под названием , содержащий движущиеся элементы (подобно настоящему секундомеру). Давайте познакомимся с ним поближе.

Монтажный стол этого клипа состоит из двух слоев: слой secondHand, представляет секундную стрелку часов; она будет вращаться при запущенном таймере. Непосредственно под этим экземпляром находится второй экземпляр – minuteHand; это будет минутная стрелка. Третий экземпляр клипа выглядит как маленькая красная метка в верхней части циферблата. Этот экземпляр называется alarmHand, эта метка переместится на сколько-то делений после установки и запуска

on (release) {
clock.alarmOn = true;
clock.startingTime = getTimer();
}
Когда эта кнопка будет нажата и отпущена, будут присвоены значения двум переменным в экземпляре клипа . Как вы вскоре увидите, то, что переменная alarmOn получила значение true, будет знаком к "включению" скрипта, присоединенного к этому экземпляру. Переменная startingTime получает возвращенное функцией getTimer() значение, равное числу миллисекунд, прошедших с момента запуска фильма. Фиксация точного времени запуска
onClipEvent (enterFrame) {
if (alarmOn) {
}
}
В этом скрипте alarmOn каждый раз, когда происходит событие enterFrame. Как вы помните, на предыдущем шаге мы запрограммировали, что при нажатии на кнопку Start эта переменная получает значение true. На нескольких следующих шагах мы добавим действия в этот alarmOn равно true. Действия будут перемещать стрелки часов и подавать сигнал в нужный момент. Таким образом, кнопка Start запускает
totalTimeToAlarm = (Number(_root.minutesToAlarm.text) * 60) + Number(_root.secondsToAlarm.text);

Вы помните, что в нашей сцене имеется одно текстовое поле для ввода минут, и другое – для ввода секунд. Оба они нам понадобятся, чтобы определить, через какой промежуток времени должен сработать будильник. Во введенной нами строке общее время получается так: число минут, введенное в соответствующее поле, умножая на 60, превращаем в число секунд, а то, что получилось, прибавляем к числу секунд, введенное в другое поле.
(Number(_root.minutesToAlarm.text * 60)) складываем с (Number(_root.secondsToAlarm.text)) и получаем значение totalTimeToAlarm.
В обеих частях выражения мы применили функцию Number() – ради уверенности, что значения minutesToAlarm.text и secondsToAlarm.text будут восприниматься как числовые, а не строковые. Сейчас мы поясним, почему это необходимо. Возьмем пример. Предположим, пользователь ввел в текстовое поле minutesToAlarm число 5, а в текстовое поле secondsToAlarm – число 37. С этими значениями наше выражение будет выглядеть так:
(Number("5") * 60) + Number("37")
Как видите, введенные значения изначально трактуются как строковые, а в этом случае у нас не получилось бы никаких математических вычислений. Однако с помощью функции Number() мы преобразуем эти значения в числовые, и выражения принимает такой вид:
(5 * 60) + 37
Примечание Значение свойства text текстового поля всегда считается строкой, поэтому для математических операций следует преобразовывать их в числа.
В минуте 60 секунд, поэтому введенное число минут мы умножаем на 60. В нашем примере получится 300. Это число мы прибавляем к введенному числу секунд, и получаем 337 (секунд) – это значение и присваивается переменной totalTimeToAlarm. В дальнейшем мы будем сравнивать с этим значением число секунд, прошедших с момента запуска
Совет Наш totalTimeToAlarm единожды, однако мы поместили эту строку скрипта в обработчик события enterFrame, и значит, значение этой переменной может обновляться, если надо, 24 раза в секунду (частота кадров в нашем фильме). Это дает пользователю возможность динамически менять настройку totalTimeToAlarm будет при этом автоматически обновляться.
secondsElapsed = Math.round((getTimer() – startingTime) / 1000);
Для нас очень важно отслеживать время, прошедшее с момента, когда пользователь нажал кнопку Start и активировал
Текущее время, полученное с помощью функции getTimer() (проверяется 24 раза в секунду, поскольку эта строка скрипта выполняется обработчиком события enterFrame ), вычитается из значения переменной startingTime:
getTimer() – startingTime
Как вы помните, переменная startingTime содержит время, прошедшее от начала фильма до нажатия кнопки Start. Постоянно проверяя текущее время и сравнивая его с этим значением, скрипт определяет, сколько прошло от нажатия кнопки Start до текущего момента. Эта часть выражения дает результат в миллисекундах, ну, например, 29349. Разделив это число на 1000 (следующая часть выражения),
/ 1000
Мы получаем число прошедших секунд – 29,349. Последняя часть выражения округляет это значение до целого числа:
Math.round()
В конце концов, переменной secondsElapsed присваивается значение 29. Следует помнить, что это значение будет увеличиваться при каждом выполнении скрипта (ведь время идет). При этом увеличение будет происходить только в целых числах – 29, 30, 31 и так далее. Новое значение мы будем получать каждую 1/24 секунды – именно с такой частотой будет выполняться эта строка скрипта.
Итак, у нас есть две переменные, необходимые для остальных действий данного скрипта.
alarmHand._rotation = totalTimeToAlarm / 10;
Как вы помните, alarmHand – это имя экземпляра клипа – красной метки внутри экземпляра клипа , показывающей на циферблате часов момент срабатывания сигнала. Эта строка скрипта поворачивает alarmHand, устанавливая в нужное положение. Например, если сигнал должен прозвучать через 20 минут, alarmHand необходимо повернуть так, чтобы красная метка оказалась напротив 20-минутной отметки на циферблате. Посмотрим, каким же образом это получается.
Полный круг составляет 360 градусов. Наш циферблат разделен на 60 минутных отметок, отсюда мы получаем, что одной минуте соответствует поворот на 6 градусов (6 x 60 = 360). Таким образом, чтобы установить метку на 20-минутную отметку, необходимо повернуть экземпляр клипа alarmHand на 120 градусов (6 градусов в минуту x 20 минут). Выражение, присваивающее значение переменной totalTimeToAlarm (шаг 5) пересчитывает 20 минут в 1200 секунд. Теперь мы делим это число на 10, и получаем 120 – именно на столько градусов нам нужно повернуть alarmHand, чтобы отметить 20 минут.

secondHand._rotation = secondsElapsed * 6; minuteHand._rotation = secondsElapsed / 10;
Эти две строки вращают экземпляры клипов secondHand и minuteHand, основываясь на постоянно обновляющемся значении secondsElapsed. Логика здесь та же, что и на предыдущем шаге – круг состоит из 360 градусов, наш циферблат имеет 60 делений, по 6 градусов на каждую минуту или секунду. За каждую прошедшую секунду секундная стрелка должна переместиться на 6 градусов. Поэтому первое действие добавленного нами скрипта поворачивает экземпляр клипа secondHand на значение secondsElapsed, умноженное на 6. Таким образом, через одну секунду он повернется на 6 градусов, через две – на 12, и так далее, создавая эффект движения секундной стрелки на настоящих часах. С минутной стрелкой дело обстоит несколько иначе. Минутная стрелка на часах проходит 1/60 того пути, что прошла секундная. Например, за 60 секунд секундная стрелка проходит полный круг. Минутная стрелка к этому моменту должна пройти по циферблату только 6 градусов, указывая, что прошла одна минута. Поэтому второе действие в нашем скрипте поворачивает экземпляр клипа minuteHand на значение secondsElapsed, деленное на 10. Так, если прошло 60 секунд, это выражение даст результат 6 – на столько градусов и переместится minuteHand.
if (secondsElapsed == totalTimeToAlarm) {
activateAlarm();
}

Этот secondsElapsed со значением totalTimeToAlarm. Если эти значения равны – значит, пора подавать звуковой сигнал, и оператор выполняет соответствующее действие. Действие это заключается в вызове функции activateAlarm(). Функцию мы сейчас опишем.
onClipEvent(load) {
function activateAlarm() {
alarmOn = false;
secondHand._rotation = 0;
minuteHand._rotation = 0;
alarmHand._rotation = 0;
alarmSound = new Sound();
alarmSound.attachSound("annoying");
alarmSound.start(0, _root.numberOfLoops.text);
}
}
Этим скриптом, сразу после загрузки экземпляра клипа , будет описана функция activateAlarm(). Функция первым делом присваивает alarmOn значение false. Тем самым будет "отключен" скрипт, связанный с событием enterFrame, и под именем alarmSound. Этот объект будет представлять собой, как вы понимаете, сигнал будильника. Следующее действие присоединяет к созданному объекту файл звукозаписи из библиотеки, который называется "annoying". Последним действием, с помощью метода start(), запускается воспроизведение звука. Первый параметр определяет, с какой секунды звукозаписи должно начаться воспроизведение, второй параметр – сколько раз следует повторить звукозапись. Мы хотим воспроизводить звукозапись с самого начала, поэтому в качестве первого параметра указываем 0. Значение второго параметра будет зависеть от числа, которое ввел пользователь в текстовое поле numberOfLoops на основном монтажном столе.
Когда фильм запустится, введите в текстовые поля для numberOfLoops.
Вы убедились, что функция getTimer() играет важнейшую роль там, где требуется точный отсчет и измерение времени.
Мы продолжим работу над этим проектом в следующем упражнении.
В нормальной ситуации монтажный стол фильма проигрывается в прямом направлении и со скоростью, определяемой значением (кадры в секунду), указанным в настройках параметров фильма. Однако вы можете сами управлять как направлением, так и скоростью воспроизведения монтажного стола при помощи enterFrame с различными элементами
Здесь первым делом нам с вами следует поговорить о таких методах объекта , как nextFrame() и prevFrame(). C их помощью можно перемещать монтажный стол к следующему или предыдущему кадру:
on (release) {
myMovieClip.nextFrame();
}
или
on (release) {
myMovieClip.prevFrame();
}
Присоединив такие скрипты к кнопкам, мы получим кнопки навигации, обеспечивающие продвижение по монтажному столу вперед или назад, по одному кадру за каждое нажатие кнопки.
Нельзя не упомянуть о таком свойстве монтажного стола, как _currentframe (свойство только для чтения). Его значение – это номер кадра, на котором в данный момент находится курсор воспроизведения. Например, предположим, что основной монтажный стол воспроизводится, тогда следующий скрипт поместит в переменную whereWeAre числовое значение, соответствующее номеру текущего кадра:
whereWeAre = _root._currentframe;

Используя это свойство вместе с
onClipEvent (enterFrame) {
if (_root._currentframe >= 50 _root.currentframe <= 100)
// Выполнить эти действия
}
}
В этом скрипте действия в теле условного оператора выполняются только в том случае, если курсор воспроизведения основного монтажного стола находится между 50-м и 100-м кадрами.
А если использовать свойство _currentframe вместе с действием gotoAndPlay(), то можно управлять и направлением, и скоростью воспроизведения монтажного стола. Возьмем такой пример:
_root.gotoAndPlay(_currentframe + 10);
Эта строка приведет к тому, что курсор воспроизведения основного монтажного стола "перепрыгнет" на 10 кадров вперед от текущей позиции. Точно так же можно переместиться по монтажному столу на 10 кадров назад:
_root.gotoAndPlay(_currentframe - 10);
Как вы увидите в этом упражнении, используя для выполнения подобной строки скрипта событие enterFrame, можно запрограммировать кнопки "перемотки" вперед и назад.
Мы продолжаем работу над проектом, начатым в предыдущем упражнении. На сей раз мы будем работать по большей части со сценой Messages. Однако сначала нужно обеспечить в нашем проекте саму возможность перехода к этой сцене. Для этого у нас предназначена кнопка с надписью "Get
on (release) {
nextFrame();
}
Когда пользователь нажмет и отпустит эту кнопку, основной монтажный стол продвинется на один кадр вперед. А поскольку в этой сцене всего один кадр, следующим кадром будет считаться следующая сцена. Таким образом, это действие переместит монтажный стол к сцене Messages, с которой мы дальше и будем работать.
Эта сцена состоит из четырех слоев. Слой Background содержит общее графическое оформление. В слое Buttons находятся четыре кнопки: messages, и сейчас мы познакомимся с ним поближе.

Монтажный стол этого клипа состоит из двух слоев – stop(), предотвращающее самопроизвольное проигрывание этого монтажного стола. В слое
onClipEvent (enterFrame) {
if (action == "ff") {
gotoAndStop (_currentframe + 3);
} else if (action == "rew") {
gotoAndStop (_currentframe - 10);
} else if (action == "play") {
play();
} else if (action == "stop") {
stop();
}
}
Этот скрипт выполняется обработчиком события enterFrame, а значит, action и выполнять те или иные действия. А значение этой переменной, как вы вскоре увидите, будет меняться при нажатии кнопок
Первая часть условного оператора гласит, что если переменная action имеет значение "ff" (она получит его при нажатии кнопки FF), текущий фильм (то есть клип messages ) должен перейти на три кадра вперед от текущего положения и остановиться. Учитывая, что этот скрипт выполняется 24 раза в секунду, вы поймете, что пока action равно "ff" (то есть, пока нажата кнопка FF), монтажный стол будет продвигаться вперед, прыгая через три кадра, имитируя процесс "быстрой перемотки" вперед.

Следующая часть условного оператора имеет эффект прямо противоположный. Здесь говорится, что если action имеет значение "rew" (так будет при нажатии кнопки Rew), текущий фильм должен переместиться на 10 кадров назад от текущего положения и там остановиться. Опять же, поскольку этот скрипт выполняется 24 раза в секунду, пока action равно "rew" (пока нажата кнопка Rew), монтажный стол будет продвигаться назад, прыгая через 10 кадров, что даст эффект "быстрой перемотки" назад.
Третья часть условного оператора гласит, что если action имеет значение " (это значение переменная может получить при щелчке на кнопке
Последняя часть условного оператора выполняется, если action имеет значение "stop" (если нажата и отпущена кнопка Stop). В этом случае воспроизведение текущего фильма останавливается.
А теперь давайте займемся нашими кнопками.
on (release) {
messages.action = "play";
}
Если пользователь нажмет и отпустит эту кнопку, переменная action (на монтажном столе messages ) получит значение ". В результате присоединенный к этому экземпляру скрипт (описанный на предыдущем шаге) выполнит соответствующее действие.
on (release) {
messages.action = "stop";
}
Когда пользователь нажмет и отпустит эту кнопку, переменная action (на монтажном столе messages ) получит значение "stop". В результате присоединенный к этому экземпляру скрипт (описанный на шаге 5) выполнит соответствующее действие.
on (press) {
messages.action = "ff";
fastSound = new Sound();
fastSound.attachSound("rewind");
fastSound.start(0, 50);
}
on (release) {
messages.action = "play";
fastSound.stop();
}
Для этой кнопки обрабатываются два события: нажатие и отпускание. Когда пользователь нажмет кнопку, переменная action (на монтажном столе messages ) получит значение "ff", и присоединенный к этому экземпляру скрипт (описанный на шаге 5) выполнит соответствующее действие. Но это не все. Для имитации звука перемотки создается объект типа , к нему присоединяется библиотечный файл звукозаписи ", после чего этот звук воспроизводится, повторяясь 50 раз.

Примечание Для простоты мы использовали звук " для имитации звука перемотки и вперед (здесь), и назад (на следующем шаге) – ведь и в действительности эти звуки похожи.
on (press) {
messages.action = "rew";
fastSound = new Sound();
fastSound.attachSound("rewind");
fastSound.start(0, 50);
}
on (release) {
messages.action = "play";
fastSound.stop();
}
Эта кнопка работает точно так же, что и предыдущая, за исключением того, что здесь переменной action присваивается значение "rew".
Когда фильм запустится, нажмите кнопку "Get messages. При нажатой кнопке FF монтажный стол будет быстро "перематываться" вперед, при нажатой кнопке Rew – назад (это можно понять по тем звуковым клипам, которые будут воспроизводиться после "перемотки").
Кнопки управления воспроизведением, подобные тем, что мы создали, могут найти самое широкое применение – не только при потоковом воспроизведении звукозаписей (как у нас), но и в любом проекте, содержащем сотни кадров.
Число кадров в фильме и размер входящих в его состав файлов определяют общую длину фильма и размер SWF-файла – этот факт станет очевидным, если даже просто взглянуть на главный монтажный стол фильма. Общее число кадров в фильме представлено значением свойства _totalframes. Так, если основной монтажный стол содержит 400 кадров (в одной сцене или нескольких), мы могли бы установить это следующим образом:
_root._totalframes = 400;
Это свойство можно использовать в скриптах, чтобы определить общую длину фильма (в кадрах).
Примечание Свойство totalframes имеет атрибут "только для чтения", то есть его значение автоматически устанавливает
Итак, зная это значение, мы можем использовать его, вместе с другими свойствами фильма, для контроля хода воспроизведения или загрузки. Например, сравнивая значение свойства _totalframes со значением свойства _currentframe, мы можем определить, сколько осталось до конца фильма:
framesLeft = _root._totalframes - _root._currentframe; message.text = "До конца осталось " + framesLeft + " кадров."
Поскольку _framesloaded, содержит общее число уже загруженных кадров. Значение этого свойства можно сравнить со значением свойства _totalframes, чтобы получить информацию о ходе загрузки. В следующем упражнении мы продемонстрируем создание
Этот проект состоит из двух сцен: Preloader и Content. Сцена Content содержит несколько слоев графики и анимации, которые нужны нам просто для демонстрации работы stop(), предотвращающее самопроизвольное проигрывание монтажного стола. Слой Preloader содержит два элемента: надпись "now loading…" и экземпляр клипа под названием preloader, состоящий из элементов, которые должны показывать ход загрузки. Давайте познакомимся с этим экземпляром поближе.
Монтажный стол этого клипа состоит из четырех слоев, названных в соответствии с их содержимым. Наиболее важными на этом монтажном столе являются два элемента: текстовое поле под названием info, расположенное в слое Text, и анимацию (с построением промежуточных изображений) в слое Amount. Анимация представляет собой 100-кадровый индикатор выполнения – от 0 до 100 процентов. Наш скрипт будет, среди прочего, продвигать этот монтажный стол от кадра к кадру по мере загрузки кадров основного фильма. В результате будет "двигаться" и индикатор выполнения.

onClipEvent (enterFrame) {
framesLoaded = (Math.ceil (( _parent._framesloaded / _parent._totalframes) * 100));
gotoAndStop (framesLoaded);
info.text = framesLoaded + "% completed";
if (framesLoaded >= 90) {
_root.gotoAndPlay (2);
}
}
Выполнение этого скрипта будет происходить с наступлением события enterFrame (24 раза в секунду), то есть он будет немедленно реагировать на изменения, происходящие в процессе загрузки, точно отображая его ход на экране.
Первым делом этот скрипт определяет процентное отношение загруженных кадров к общему их числу. Это число округляется до целого в большую сторону, и то, что получилось, присваивается переменной framesLoaded. Рассмотрим это выражение по порядку его выполнения.
_parent._framesloaded / _parent._totalframes
В этой части выражения берется число уже загруженных кадров главного монтажного стола и делится на общее число кадров главного монтажного стола.
Примечание Поскольку этот скрипт присоединен к экземпляру клипа preloader, который находится на главном монтажном столе, мы использовали для указания на главный монтажный стол адресную ссылку _parent. Благодаря этому клип preloader можно без всяких изменений вставить и в любой другой проект.

Для примера предположим, что фильм содержит 735 кадров, из которых 259 уже загружено. В этом случае данная часть выражения получится такой:
259 / 735
В результате получится 0,3523. На следующем этапе выражения этот результат умножается на 100:
* 100
В результате получаем 35,23. И наконец, с помощью метода Math.ceil() это значение округляется до целого числа в большую сторону, и переменной framesLoaded присваивается значение 36. Напомним, что этот скрипт выполняется 24 раза в секунду, это число будет увеличиваться по мере загрузки фильма.
Совет Свойства _framesloaded и _totalframes, примененные в этом скрипте, можно заменить методами объекта и getBytesTotal(), если вы хотите, чтобы индикатор выполнения вел отсчет, основываясь на реально загруженных байтах, а не кадрах. Иногда такой способ предпочтительнее, поскольку кадр будет считаться загруженным (и индикатор продвинется) только после того, как будут загружено все, что в кадре содержится. Поэтому, если в процессе загрузки будут встречаться сложные, многобайтные кадры, индикатор будет приостанавливаться на заметное время, продвигаться рывками. Если же отслеживать загрузку по байтам, то индикатор будет двигаться гладко, ведь данные о загрузке байтов данных обновляются гораздо чаще (с каждым загруженным байтом). На CD вы найдете бонусный файл, демонстрирующий именно такой индикатор.
Вернемся к нашему скрипту. Второе действие отсылает текущий фильм к кадру, номер которого равен значению framesLoaded. Поскольку текущий фильм содержит анимацию, изображающую заполняющийся слева направо индикатор выполнения, получается, что это действие управляет движением framesLoaded заполняется индикатор.
Следующее действие скрипта отображает текст в поле info. Здесь значение framesLoaded соединяется со строкой "% completed". Если framesLoaded имеет значение 36, то получится "36% completed".
Последняя часть этого скрипта – framesLoaded больше или равно 90, главный монтажный стол должен перейти к кадру 2 (которым на самом деле будет сцена Content) и оттуда продолжить воспроизведение фильма.
Совет Значение 90 в этом условном операторе легко можно заменить любым другим – все зависит от того, в какой момент вы хотите прекратить работу предзагрузчика и запустить основной фильм.
Так мы сможем получить достаточно точную симуляцию загрузки фильма через модем на скорости 56K, и сможем увидеть работу нашего предзагрузчика. По мере загрузки фильма вы увидите, как обновляется процент загрузки и движется индикатор выполнения. Как и было сказано на предыдущем шаге, индикатор продвигается до 90 процентов, после чего монтажный стол перемещается к сцене Content и проигрывает фильм дальше.
Упражнение закончено.
В этом уроке:
tTimer() для точного отсчета времени – на примере 
Часть проекта Make My
Day , который мы с вами построим в этом уроке.
На выполнение этого урока требуется примерно один час.
Файлы-носители:
Нет
Стартовые файлы:
Lesson15/Assets/makeMyDay1.fla Lesson15/Assets/preloader1.fla
Законченные проекты:
makeMyDay4.fla preloader2.fla
Бонус:
preloaderBytes.fla
Для измерения времени во
Используя эти элементы, вы можете снабдить свой проект следующими возможностями:
В , позволяющий вызывать какую-либо функцию раз за разом с определенным интервалом (измеряемым в миллисекундах). Для примера рассмотрим такой скрипт:
function rotateClip() {
myMovieClip._rotation += 10;
}
setInterval (rotateClip, 1500);
В первых трех строках описана функция. Затем следует действие , вызывающее функцию rotateClip() каждые полторы секунды (1000 миллисекунд = 1 секунде).
Если вызываемой функции требуется передать значения аргументов, они просто добавляются в качестве параметров действия :
setInterval (updateMessageFunction, 2000, "Hello", arg2, arg3);
Действие можно включать и отключать – для этого следует "присвоить" ему
myVariable = setInterval (rotateClip, 1500);
Тем самым имя myVariable назначается данному действию . Теперь, чтобы прекратить выполнение действия , достаточно использовать следующую команду:
delete myVariable;
Действие можно инициировать в любое время, например, вставив его вызов в какую-либо функцию. В следующем уроке мы с вами применим это действие для создания вращающихся рекламных
Все мы пользуемся календарем; многие вообще не представляют себе, как можно без него обойтись – ведь нужно планировать свои дела на будущее и т.д.. Во
Чтобы использовать во Date:
myDate = new Date(year, month, date);
Эта строка скрипта создает новый объект Date под именем myDate. Параметры в скобках связывают этот объект с определенной датой. Например:
myDate = new Date(66, 6, 27);
Этим скриптом будет создан новый объект Date, связанный с 27 июля 1966 года. Первый параметр определяет год, второй – месяц, третий – день. Кстати, не удивляйтесь, тут нет никаких опечаток, хотя июль – седьмой месяц, а в скрипте указано 6. Дело в том, что в
Примечание Числа месяцев и годы имеют истинные значения. Так, 66 соответствует 1966 году, а 27 – 27-му дню месяца.

Совет Список параметров создаваемого объекта можно продолжить, указав час, минуту, секунду и миллисекунду, если в вашем приложении нужна такая точность.
Если нужно создать объект Date, содержащий текущую дату и время (по системным часам компьютера), достаточно просто не указывать параметры, оставив скобки конструктора объекта пустыми. Например:
myDate = new Date();
После того, как объект Data создан, можно извлечь из него любую информацию о хранящейся в нем дате при помощи соответствующих методов. Возьмем предыдущий пример – объект, содержащий текущую системную дату. Чтобы выяснить, какой сейчас месяц, мы используем следующий синтаксис:
currentMonth = myDate.getMonth();
После выполнения этой строки переменная currentMonth получит числовое значение, например, 5 – это будет означать месяц июнь. Чтобы узнать день недели, используем другой метод:
currentDay = myDate.getDay();
После выполнения этой строки переменная currentDay получит числовое значение, например, 4, что соответствует четвергу.
Примечание Проект может содержать несколько объектов Data, предназначенных для разных целей.
В следующем упражнении мы создадим объект Data и применим различные методы для отображения текущей даты на экране.
Этот проект состоит из двух сцен –
Непосредственно под надписью "Today is:" вы видите четыре текстовых поля. Называются они (по порядку сверху вниз) currentDay, currentMonth, currentDate и currentYear. В этих полях будут динамически отображаться составляющие текущей даты:
В каждом поле стиль текста будет разным, чтобы наш календарь выглядел красиво.

В самом низу этого окна вы видите бессмысленный набор букв. Эти буквы – набор символов, специфическое начертание которых мы хотим внедрить в фильм для этого поля. Названия всех дней недели состоят только из букв, которые здесь перечислены. Это текстовое поле будет содержать динамически генерируемый текст, и внедрение шрифта позволит отображать текст в этом поле со
Для прочих текстовых полей календаря тоже указан тот или иной внедряемый набор символов (в зависимости от того, что должно отображать каждое поле).

stop(); today = new Date();
Первое действие воспрещает дальнейшее воспроизведение монтажного стола до особых на то указаний.
Следующая строка скрипта создает новый объект Date под именем today, как только начнется воспроизведение фильма. Поскольку в скобках мы не указали особых значений параметров, этот объект Data будет содержать текущую системную дату на компьютере пользователя (на момент воспроизведения фильма).
nameOfDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; nameOfMonths = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
Первая строка создает массив под названием nameOfDays ; вторая строка – массив nameOfMonths. Каждый массив содержит набор строковых значений, представляющих собой, соответственно, названия дней недели и месяцев. Для чего нужны эти массивы? Ну, это ведь люди называют дни и месяцы разными словами, а
currentDay.text = nameOfDays[today.getDay()];
Этим действием мы выводим информацию в текстовом поле currentDay. Поясним, как это получается.
С помощью метода getDay() (в квадратных скобках) мы определяем день недели даты, хранящейся в объекте today. Этот метод возвратит некое значение от 0 до 6 (напомним, 0 соответствует воскресенью, 6 – субботе). Допустим, метод вернул значение 3; это значение подставляется вместо выражения в квадратных скобках, и мы получаем такую строку:
currentDay.text = nameOfDays[3];
Как видите, в поле currentDay будет отображено значение элемента с индексом 3 массива nameOfDays, то есть строковое значение "Wednesday". Как видите, мы, зная, что метод getDay() выдает числовые значения от 0 до 6, создали на предыдущем шаге массив, элементами которого являются названия дней недели, причем этих элементов имеют индексы тоже от 0 до 6.
currentMonth.text = nameOfMonths[today.getMonth()];
Этим действием мы выводим информацию в текстовом поле currentMonth. Принцип действия тот же, что и на предыдущем шаге – метод getMonth() выдает некоторое числовое значение от 0 до 11, из массива nameOfMonths берется строковое значение элемента с соответствующим индексом.
currentDate.text = today.getDate();
Это действие выводит информацию в текстовом поле currentDate. Здесь использован метод getDate(), возвращающий числовое значение от 1 до 31, соответствующее числу месяца для даты, хранящейся в объекте today. В данном случае нам требуется именно число, поэтому никакого массива для преобразования номера в строку здесь не нужно.
currentYear.text = today.getFullYear();
Это действие выводит информацию в текстовом поле currentYear. Здесь использован метод getFullYear(), возвращающий числовое значение, соответствующее году даты, хранящейся в объекте today (например, 2002). В данном случае опять нас вполне устраивает число, и массива для преобразования в строку не требуется.
Как только фильм запустится, текстовые поля календарного листка на экране заполнятся информацией, соответствующей сегодняшней дате.

Мы продолжим работу с этим проектом в следующем упражнении урока.
Функция getTimer() возвращает время (в миллисекундах), прошедшее с момента запуска фильма. Если, к примеру, на момент вызова этой функции фильм воспроизводится уже шесть секунд, то скрипт
playBackTime = getTimer();
присвоит переменной playBackTime значение 6000 (1000 миллисекунд в каждой секунде). Это – точное время, отсчитываемое по системным часам пользовательского компьютера; оно не зависит ни от частоты кадров фильма, ни от быстродействия процессора, ни от того, воспроизводится ли фильм или стоит на одном и том же кадре. Подчеркнем, что функция возвращает время, прошедшее с момента запуска всего фильма, а не отдельных монтажных столов.
Промежуток времени между двумя событиями внутри фильма все же можно измерить. Для этого следует в нужный момент присвоить какой-либо переменной значение, возвращенное функцией getTimer(), а потом сравнить с этой переменной новое значение, возвращенное функцией. Поясним это на следующем примере:
// Скрипт для кнопки A
on (release) {
startTime = getTimer();
}
// Скрипт для кнопки B
on (release) {
nowTime = getTimer();
if (nowTime – startTime < 1000) {
message.text = "Вы нажали кнопку слишком быстро";
} else {
message.text = "Слишком поздно";
}
}
Здесь, если нажата и отпущена одна из кнопок (кнопка A), фиксируется стартовая точка отсчета времени. Когда нажата и отпущена кнопка B, время снова фиксируется.
on (release) {
if (getTimer() – lastClick < 500) {
// Действия
}
lastClick = getTimer();
}
Используя функцию getTimer() совместно с событием enterFrame и
onClipEvent (enterFrame) {
if (getTimer() > 5000) {
// Действия
}
if (getTimer() > 10000) {
// Действия
}
if (getTimer() > 15000) {
// Действия
}
}
Этот скрипт будет выполнять действия каждые пять секунд по ходу воспроизведения фильма – зачастую это единственный способ, если требуется точный отсчет времени.
В следующем упражнении мы с вами, используя функцию getTimer(), создадим
Примечание Функцию getTimer() можно найти в списке инструментов панели Действия в разделе Functions.

Мы продолжаем работу над проектом, начатым в предыдущем упражнении. Напомним, что в этом файле имеется две сцены, minutesToAlarm, secondsToAlarm и numberOfLoops (сверху вниз). Это текстовые поля для ввода; первые два предназначены для установки времени, по прошествии которого должен сработать будильник, третье будет определять, сколько раз будильник должен прозвонить.
Ниже этих текстовых полей находится кнопка Start, которой будет запускаться
Под этой кнопкой расположен экземпляр фильма-символа под названием , содержащий движущиеся элементы (подобно настоящему секундомеру). Давайте познакомимся с ним поближе.

Монтажный стол этого клипа состоит из двух слоев: слой secondHand, представляет секундную стрелку часов; она будет вращаться при запущенном таймере. Непосредственно под этим экземпляром находится второй экземпляр – minuteHand; это будет минутная стрелка. Третий экземпляр клипа выглядит как маленькая красная метка в верхней части циферблата. Этот экземпляр называется alarmHand, эта метка переместится на сколько-то делений после установки и запуска

on (release) {
clock.alarmOn = true;
clock.startingTime = getTimer();
}
Когда эта кнопка будет нажата и отпущена, будут присвоены значения двум переменным в экземпляре клипа . Как вы вскоре увидите, то, что переменная alarmOn получила значение true, будет знаком к "включению" скрипта, присоединенного к этому экземпляру. Переменная startingTime получает возвращенное функцией getTimer() значение, равное числу миллисекунд, прошедших с момента запуска фильма. Фиксация точного времени запуска
onClipEvent (enterFrame) {
if (alarmOn) {
}
}
В этом скрипте alarmOn каждый раз, когда происходит событие enterFrame. Как вы помните, на предыдущем шаге мы запрограммировали, что при нажатии на кнопку Start эта переменная получает значение true. На нескольких следующих шагах мы добавим действия в этот alarmOn равно true. Действия будут перемещать стрелки часов и подавать сигнал в нужный момент. Таким образом, кнопка Start запускает
totalTimeToAlarm = (Number(_root.minutesToAlarm.text) * 60) + Number(_root.secondsToAlarm.text);

Вы помните, что в нашей сцене имеется одно текстовое поле для ввода минут, и другое – для ввода секунд. Оба они нам понадобятся, чтобы определить, через какой промежуток времени должен сработать будильник. Во введенной нами строке общее время получается так: число минут, введенное в соответствующее поле, умножая на 60, превращаем в число секунд, а то, что получилось, прибавляем к числу секунд, введенное в другое поле.
(Number(_root.minutesToAlarm.text * 60)) складываем с (Number(_root.secondsToAlarm.text)) и получаем значение totalTimeToAlarm.
В обеих частях выражения мы применили функцию Number() – ради уверенности, что значения minutesToAlarm.text и secondsToAlarm.text будут восприниматься как числовые, а не строковые. Сейчас мы поясним, почему это необходимо. Возьмем пример. Предположим, пользователь ввел в текстовое поле minutesToAlarm число 5, а в текстовое поле secondsToAlarm – число 37. С этими значениями наше выражение будет выглядеть так:
(Number("5") * 60) + Number("37")
Как видите, введенные значения изначально трактуются как строковые, а в этом случае у нас не получилось бы никаких математических вычислений. Однако с помощью функции Number() мы преобразуем эти значения в числовые, и выражения принимает такой вид:
(5 * 60) + 37
Примечание Значение свойства text текстового поля всегда считается строкой, поэтому для математических операций следует преобразовывать их в числа.
В минуте 60 секунд, поэтому введенное число минут мы умножаем на 60. В нашем примере получится 300. Это число мы прибавляем к введенному числу секунд, и получаем 337 (секунд) – это значение и присваивается переменной totalTimeToAlarm. В дальнейшем мы будем сравнивать с этим значением число секунд, прошедших с момента запуска
Совет Наш totalTimeToAlarm единожды, однако мы поместили эту строку скрипта в обработчик события enterFrame, и значит, значение этой переменной может обновляться, если надо, 24 раза в секунду (частота кадров в нашем фильме). Это дает пользователю возможность динамически менять настройку totalTimeToAlarm будет при этом автоматически обновляться.
secondsElapsed = Math.round((getTimer() – startingTime) / 1000);
Для нас очень важно отслеживать время, прошедшее с момента, когда пользователь нажал кнопку Start и активировал
Текущее время, полученное с помощью функции getTimer() (проверяется 24 раза в секунду, поскольку эта строка скрипта выполняется обработчиком события enterFrame ), вычитается из значения переменной startingTime:
getTimer() – startingTime
Как вы помните, переменная startingTime содержит время, прошедшее от начала фильма до нажатия кнопки Start. Постоянно проверяя текущее время и сравнивая его с этим значением, скрипт определяет, сколько прошло от нажатия кнопки Start до текущего момента. Эта часть выражения дает результат в миллисекундах, ну, например, 29349. Разделив это число на 1000 (следующая часть выражения),
/ 1000
Мы получаем число прошедших секунд – 29,349. Последняя часть выражения округляет это значение до целого числа:
Math.round()
В конце концов, переменной secondsElapsed присваивается значение 29. Следует помнить, что это значение будет увеличиваться при каждом выполнении скрипта (ведь время идет). При этом увеличение будет происходить только в целых числах – 29, 30, 31 и так далее. Новое значение мы будем получать каждую 1/24 секунды – именно с такой частотой будет выполняться эта строка скрипта.
Итак, у нас есть две переменные, необходимые для остальных действий данного скрипта.
alarmHand._rotation = totalTimeToAlarm / 10;
Как вы помните, alarmHand – это имя экземпляра клипа – красной метки внутри экземпляра клипа , показывающей на циферблате часов момент срабатывания сигнала. Эта строка скрипта поворачивает alarmHand, устанавливая в нужное положение. Например, если сигнал должен прозвучать через 20 минут, alarmHand необходимо повернуть так, чтобы красная метка оказалась напротив 20-минутной отметки на циферблате. Посмотрим, каким же образом это получается.
Полный круг составляет 360 градусов. Наш циферблат разделен на 60 минутных отметок, отсюда мы получаем, что одной минуте соответствует поворот на 6 градусов (6 x 60 = 360). Таким образом, чтобы установить метку на 20-минутную отметку, необходимо повернуть экземпляр клипа alarmHand на 120 градусов (6 градусов в минуту x 20 минут). Выражение, присваивающее значение переменной totalTimeToAlarm (шаг 5) пересчитывает 20 минут в 1200 секунд. Теперь мы делим это число на 10, и получаем 120 – именно на столько градусов нам нужно повернуть alarmHand, чтобы отметить 20 минут.

secondHand._rotation = secondsElapsed * 6; minuteHand._rotation = secondsElapsed / 10;
Эти две строки вращают экземпляры клипов secondHand и minuteHand, основываясь на постоянно обновляющемся значении secondsElapsed. Логика здесь та же, что и на предыдущем шаге – круг состоит из 360 градусов, наш циферблат имеет 60 делений, по 6 градусов на каждую минуту или секунду. За каждую прошедшую секунду секундная стрелка должна переместиться на 6 градусов. Поэтому первое действие добавленного нами скрипта поворачивает экземпляр клипа secondHand на значение secondsElapsed, умноженное на 6. Таким образом, через одну секунду он повернется на 6 градусов, через две – на 12, и так далее, создавая эффект движения секундной стрелки на настоящих часах. С минутной стрелкой дело обстоит несколько иначе. Минутная стрелка на часах проходит 1/60 того пути, что прошла секундная. Например, за 60 секунд секундная стрелка проходит полный круг. Минутная стрелка к этому моменту должна пройти по циферблату только 6 градусов, указывая, что прошла одна минута. Поэтому второе действие в нашем скрипте поворачивает экземпляр клипа minuteHand на значение secondsElapsed, деленное на 10. Так, если прошло 60 секунд, это выражение даст результат 6 – на столько градусов и переместится minuteHand.
if (secondsElapsed == totalTimeToAlarm) {
activateAlarm();
}

Этот secondsElapsed со значением totalTimeToAlarm. Если эти значения равны – значит, пора подавать звуковой сигнал, и оператор выполняет соответствующее действие. Действие это заключается в вызове функции activateAlarm(). Функцию мы сейчас опишем.
onClipEvent(load) {
function activateAlarm() {
alarmOn = false;
secondHand._rotation = 0;
minuteHand._rotation = 0;
alarmHand._rotation = 0;
alarmSound = new Sound();
alarmSound.attachSound("annoying");
alarmSound.start(0, _root.numberOfLoops.text);
}
}
Этим скриптом, сразу после загрузки экземпляра клипа , будет описана функция activateAlarm(). Функция первым делом присваивает alarmOn значение false. Тем самым будет "отключен" скрипт, связанный с событием enterFrame, и под именем alarmSound. Этот объект будет представлять собой, как вы понимаете, сигнал будильника. Следующее действие присоединяет к созданному объекту файл звукозаписи из библиотеки, который называется "annoying". Последним действием, с помощью метода start(), запускается воспроизведение звука. Первый параметр определяет, с какой секунды звукозаписи должно начаться воспроизведение, второй параметр – сколько раз следует повторить звукозапись. Мы хотим воспроизводить звукозапись с самого начала, поэтому в качестве первого параметра указываем 0. Значение второго параметра будет зависеть от числа, которое ввел пользователь в текстовое поле numberOfLoops на основном монтажном столе.
Когда фильм запустится, введите в текстовые поля для numberOfLoops.
Вы убедились, что функция getTimer() играет важнейшую роль там, где требуется точный отсчет и измерение времени.
Мы продолжим работу над этим проектом в следующем упражнении.
В нормальной ситуации монтажный стол фильма проигрывается в прямом направлении и со скоростью, определяемой значением (кадры в секунду), указанным в настройках параметров фильма. Однако вы можете сами управлять как направлением, так и скоростью воспроизведения монтажного стола при помощи enterFrame с различными элементами
Здесь первым делом нам с вами следует поговорить о таких методах объекта , как nextFrame() и prevFrame(). C их помощью можно перемещать монтажный стол к следующему или предыдущему кадру:
on (release) {
myMovieClip.nextFrame();
}
или
on (release) {
myMovieClip.prevFrame();
}
Присоединив такие скрипты к кнопкам, мы получим кнопки навигации, обеспечивающие продвижение по монтажному столу вперед или назад, по одному кадру за каждое нажатие кнопки.
Нельзя не упомянуть о таком свойстве монтажного стола, как _currentframe (свойство только для чтения). Его значение – это номер кадра, на котором в данный момент находится курсор воспроизведения. Например, предположим, что основной монтажный стол воспроизводится, тогда следующий скрипт поместит в переменную whereWeAre числовое значение, соответствующее номеру текущего кадра:
whereWeAre = _root._currentframe;

Используя это свойство вместе с
onClipEvent (enterFrame) {
if (_root._currentframe >= 50 _root.currentframe <= 100)
// Выполнить эти действия
}
}
В этом скрипте действия в теле условного оператора выполняются только в том случае, если курсор воспроизведения основного монтажного стола находится между 50-м и 100-м кадрами.
А если использовать свойство _currentframe вместе с действием gotoAndPlay(), то можно управлять и направлением, и скоростью воспроизведения монтажного стола. Возьмем такой пример:
_root.gotoAndPlay(_currentframe + 10);
Эта строка приведет к тому, что курсор воспроизведения основного монтажного стола "перепрыгнет" на 10 кадров вперед от текущей позиции. Точно так же можно переместиться по монтажному столу на 10 кадров назад:
_root.gotoAndPlay(_currentframe - 10);
Как вы увидите в этом упражнении, используя для выполнения подобной строки скрипта событие enterFrame, можно запрограммировать кнопки "перемотки" вперед и назад.
Мы продолжаем работу над проектом, начатым в предыдущем упражнении. На сей раз мы будем работать по большей части со сценой Messages. Однако сначала нужно обеспечить в нашем проекте саму возможность перехода к этой сцене. Для этого у нас предназначена кнопка с надписью "Get
on (release) {
nextFrame();
}
Когда пользователь нажмет и отпустит эту кнопку, основной монтажный стол продвинется на один кадр вперед. А поскольку в этой сцене всего один кадр, следующим кадром будет считаться следующая сцена. Таким образом, это действие переместит монтажный стол к сцене Messages, с которой мы дальше и будем работать.
Эта сцена состоит из четырех слоев. Слой Background содержит общее графическое оформление. В слое Buttons находятся четыре кнопки: messages, и сейчас мы познакомимся с ним поближе.

Монтажный стол этого клипа состоит из двух слоев – stop(), предотвращающее самопроизвольное проигрывание этого монтажного стола. В слое
onClipEvent (enterFrame) {
if (action == "ff") {
gotoAndStop (_currentframe + 3);
} else if (action == "rew") {
gotoAndStop (_currentframe - 10);
} else if (action == "play") {
play();
} else if (action == "stop") {
stop();
}
}
Этот скрипт выполняется обработчиком события enterFrame, а значит, action и выполнять те или иные действия. А значение этой переменной, как вы вскоре увидите, будет меняться при нажатии кнопок
Первая часть условного оператора гласит, что если переменная action имеет значение "ff" (она получит его при нажатии кнопки FF), текущий фильм (то есть клип messages ) должен перейти на три кадра вперед от текущего положения и остановиться. Учитывая, что этот скрипт выполняется 24 раза в секунду, вы поймете, что пока action равно "ff" (то есть, пока нажата кнопка FF), монтажный стол будет продвигаться вперед, прыгая через три кадра, имитируя процесс "быстрой перемотки" вперед.

Следующая часть условного оператора имеет эффект прямо противоположный. Здесь говорится, что если action имеет значение "rew" (так будет при нажатии кнопки Rew), текущий фильм должен переместиться на 10 кадров назад от текущего положения и там остановиться. Опять же, поскольку этот скрипт выполняется 24 раза в секунду, пока action равно "rew" (пока нажата кнопка Rew), монтажный стол будет продвигаться назад, прыгая через 10 кадров, что даст эффект "быстрой перемотки" назад.
Третья часть условного оператора гласит, что если action имеет значение " (это значение переменная может получить при щелчке на кнопке
Последняя часть условного оператора выполняется, если action имеет значение "stop" (если нажата и отпущена кнопка Stop). В этом случае воспроизведение текущего фильма останавливается.
А теперь давайте займемся нашими кнопками.
on (release) {
messages.action = "play";
}
Если пользователь нажмет и отпустит эту кнопку, переменная action (на монтажном столе messages ) получит значение ". В результате присоединенный к этому экземпляру скрипт (описанный на предыдущем шаге) выполнит соответствующее действие.
on (release) {
messages.action = "stop";
}
Когда пользователь нажмет и отпустит эту кнопку, переменная action (на монтажном столе messages ) получит значение "stop". В результате присоединенный к этому экземпляру скрипт (описанный на шаге 5) выполнит соответствующее действие.
on (press) {
messages.action = "ff";
fastSound = new Sound();
fastSound.attachSound("rewind");
fastSound.start(0, 50);
}
on (release) {
messages.action = "play";
fastSound.stop();
}
Для этой кнопки обрабатываются два события: нажатие и отпускание. Когда пользователь нажмет кнопку, переменная action (на монтажном столе messages ) получит значение "ff", и присоединенный к этому экземпляру скрипт (описанный на шаге 5) выполнит соответствующее действие. Но это не все. Для имитации звука перемотки создается объект типа , к нему присоединяется библиотечный файл звукозаписи ", после чего этот звук воспроизводится, повторяясь 50 раз.

Примечание Для простоты мы использовали звук " для имитации звука перемотки и вперед (здесь), и назад (на следующем шаге) – ведь и в действительности эти звуки похожи.
on (press) {
messages.action = "rew";
fastSound = new Sound();
fastSound.attachSound("rewind");
fastSound.start(0, 50);
}
on (release) {
messages.action = "play";
fastSound.stop();
}
Эта кнопка работает точно так же, что и предыдущая, за исключением того, что здесь переменной action присваивается значение "rew".
Когда фильм запустится, нажмите кнопку "Get messages. При нажатой кнопке FF монтажный стол будет быстро "перематываться" вперед, при нажатой кнопке Rew – назад (это можно понять по тем звуковым клипам, которые будут воспроизводиться после "перемотки").
Кнопки управления воспроизведением, подобные тем, что мы создали, могут найти самое широкое применение – не только при потоковом воспроизведении звукозаписей (как у нас), но и в любом проекте, содержащем сотни кадров.
Число кадров в фильме и размер входящих в его состав файлов определяют общую длину фильма и размер SWF-файла – этот факт станет очевидным, если даже просто взглянуть на главный монтажный стол фильма. Общее число кадров в фильме представлено значением свойства _totalframes. Так, если основной монтажный стол содержит 400 кадров (в одной сцене или нескольких), мы могли бы установить это следующим образом:
_root._totalframes = 400;
Это свойство можно использовать в скриптах, чтобы определить общую длину фильма (в кадрах).
Примечание Свойство totalframes имеет атрибут "только для чтения", то есть его значение автоматически устанавливает
Итак, зная это значение, мы можем использовать его, вместе с другими свойствами фильма, для контроля хода воспроизведения или загрузки. Например, сравнивая значение свойства _totalframes со значением свойства _currentframe, мы можем определить, сколько осталось до конца фильма:
framesLeft = _root._totalframes - _root._currentframe; message.text = "До конца осталось " + framesLeft + " кадров."
Поскольку _framesloaded, содержит общее число уже загруженных кадров. Значение этого свойства можно сравнить со значением свойства _totalframes, чтобы получить информацию о ходе загрузки. В следующем упражнении мы продемонстрируем создание
Этот проект состоит из двух сцен: Preloader и Content. Сцена Content содержит несколько слоев графики и анимации, которые нужны нам просто для демонстрации работы stop(), предотвращающее самопроизвольное проигрывание монтажного стола. Слой Preloader содержит два элемента: надпись "now loading…" и экземпляр клипа под названием preloader, состоящий из элементов, которые должны показывать ход загрузки. Давайте познакомимся с этим экземпляром поближе.
Монтажный стол этого клипа состоит из четырех слоев, названных в соответствии с их содержимым. Наиболее важными на этом монтажном столе являются два элемента: текстовое поле под названием info, расположенное в слое Text, и анимацию (с построением промежуточных изображений) в слое Amount. Анимация представляет собой 100-кадровый индикатор выполнения – от 0 до 100 процентов. Наш скрипт будет, среди прочего, продвигать этот монтажный стол от кадра к кадру по мере загрузки кадров основного фильма. В результате будет "двигаться" и индикатор выполнения.

onClipEvent (enterFrame) {
framesLoaded = (Math.ceil (( _parent._framesloaded / _parent._totalframes) * 100));
gotoAndStop (framesLoaded);
info.text = framesLoaded + "% completed";
if (framesLoaded >= 90) {
_root.gotoAndPlay (2);
}
}
Выполнение этого скрипта будет происходить с наступлением события enterFrame (24 раза в секунду), то есть он будет немедленно реагировать на изменения, происходящие в процессе загрузки, точно отображая его ход на экране.
Первым делом этот скрипт определяет процентное отношение загруженных кадров к общему их числу. Это число округляется до целого в большую сторону, и то, что получилось, присваивается переменной framesLoaded. Рассмотрим это выражение по порядку его выполнения.
_parent._framesloaded / _parent._totalframes
В этой части выражения берется число уже загруженных кадров главного монтажного стола и делится на общее число кадров главного монтажного стола.
Примечание Поскольку этот скрипт присоединен к экземпляру клипа preloader, который находится на главном монтажном столе, мы использовали для указания на главный монтажный стол адресную ссылку _parent. Благодаря этому клип preloader можно без всяких изменений вставить и в любой другой проект.

Для примера предположим, что фильм содержит 735 кадров, из которых 259 уже загружено. В этом случае данная часть выражения получится такой:
259 / 735
В результате получится 0,3523. На следующем этапе выражения этот результат умножается на 100:
* 100
В результате получаем 35,23. И наконец, с помощью метода Math.ceil() это значение округляется до целого числа в большую сторону, и переменной framesLoaded присваивается значение 36. Напомним, что этот скрипт выполняется 24 раза в секунду, это число будет увеличиваться по мере загрузки фильма.
Совет Свойства _framesloaded и _totalframes, примененные в этом скрипте, можно заменить методами объекта и getBytesTotal(), если вы хотите, чтобы индикатор выполнения вел отсчет, основываясь на реально загруженных байтах, а не кадрах. Иногда такой способ предпочтительнее, поскольку кадр будет считаться загруженным (и индикатор продвинется) только после того, как будут загружено все, что в кадре содержится. Поэтому, если в процессе загрузки будут встречаться сложные, многобайтные кадры, индикатор будет приостанавливаться на заметное время, продвигаться рывками. Если же отслеживать загрузку по байтам, то индикатор будет двигаться гладко, ведь данные о загрузке байтов данных обновляются гораздо чаще (с каждым загруженным байтом). На CD вы найдете бонусный файл, демонстрирующий именно такой индикатор.
Вернемся к нашему скрипту. Второе действие отсылает текущий фильм к кадру, номер которого равен значению framesLoaded. Поскольку текущий фильм содержит анимацию, изображающую заполняющийся слева направо индикатор выполнения, получается, что это действие управляет движением framesLoaded заполняется индикатор.
Следующее действие скрипта отображает текст в поле info. Здесь значение framesLoaded соединяется со строкой "% completed". Если framesLoaded имеет значение 36, то получится "36% completed".
Последняя часть этого скрипта – framesLoaded больше или равно 90, главный монтажный стол должен перейти к кадру 2 (которым на самом деле будет сцена Content) и оттуда продолжить воспроизведение фильма.
Совет Значение 90 в этом условном операторе легко можно заменить любым другим – все зависит от того, в какой момент вы хотите прекратить работу предзагрузчика и запустить основной фильм.
Так мы сможем получить достаточно точную симуляцию загрузки фильма через модем на скорости 56K, и сможем увидеть работу нашего предзагрузчика. По мере загрузки фильма вы увидите, как обновляется процент загрузки и движется индикатор выполнения. Как и было сказано на предыдущем шаге, индикатор продвигается до 90 процентов, после чего монтажный стол перемещается к сцене Content и проигрывает фильм дальше.
Упражнение закончено.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.