Статьи

Go Retro с музыкальным плеером в стиле фанк

Мы собираемся использовать как инструменты разработки ActionScript 3, так и Flash, чтобы создать ретро-кассетный музыкальный проигрыватель. В этом руководстве вы найдете множество тем, включая потоковую передачу музыки, анимацию по временной шкале, пользовательские классы видеоклипов и обработку событий.


Большинство программистов ActionScript избегают временной шкалы, как чума, предпочитая писать сотни строк кода для выполнения задачи, которая могла бы быть достигнута за считанные секунды с использованием инструментов рисования и анимации, предоставляемых Flash IDE.

Из этого туториала Вы узнаете, как получить лучшее из обоих миров, когда создаете простой, но увлекательный ретро-музыкальный проигрыватель. Это побудит вас воспользоваться временной шкалой, где это уместно, что позволит вам сосредоточиться на ActionScript, который действительно имеет значение.


Я использую Flash CS5, но это руководство будет работать со всеми версиями Flash CS. Прилагаемые исходные FLA-файлы были сохранены в формате Flash CS3, а также могут использоваться с любой версией Flash CS.

Запустите Flash и создайте новый документ ActionScript 3.0. Установите размер сцены 800x530px, а частоту кадров 24fps.



Вот интерфейс, над которым мы будем работать. Это аудиокассета старой школы с кассетой, которая катится по роликам при потоковой передаче музыки.


Это может показаться немного сложным, но есть только несколько движущихся частей — остальное статично. Ниже вы можете увидеть различные символы фрагмента ролика, на которые разбита кассета.

Корпус кассеты разделен на заднюю панель …


… и передняя панель.


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



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

Импортируйте растровое изображение конечной кассеты из: source / reference.png и используйте его в качестве ориентира.

Выберите: Файл | Импорт | Импорт в библиотеку … Найдите и выберите эталонное растровое изображение.


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

Создайте новый символ видеоклипа, выбрав: Вставить | Новый символ (Ctrl + F8). Назовите символ «Назад» и установите его тип «Movie Clip». Нажмите ОК.


Создайте направляющий слой и назовите его «Reference». Выберите слой. Перетащите экземпляр reference.png из библиотеки и отцентрируйте его на сцене.

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


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


Выделенные контуры ниже выделяют отдельные слои, которые я использовал.


Ваша законченная задняя панель должна выглядеть примерно так:


Чтобы увидеть мою версию с открытым исходным кодом / cassette-no-code.fla, найдите символ «Назад» в библиотеке и откройте его:



Передняя панель кассеты ничем не отличается от задней.

Создайте новый символ видеоклипа и назовите его «Front».

Опять же, создайте направляющий слой и используйте эталонное растровое изображение из библиотеки в качестве руководства.

Когда цвет


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

Для вашего цвета заливки


просто выберите альфа-процент от цвета


Панель выбора. Я выбрал цвет


#A89FBD и 10% альфа.


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


Выделенные контуры ниже выделяют отдельные слои, которые я использовал.


Ваша законченная передняя панель должна выглядеть примерно так:


Чтобы увидеть мою версию с открытым исходным кодом / cassette-no-code.fla, найдите символ Front Front clip в библиотеке и откройте его:



Корпус кассеты укомплектован и хранится в библиотеке как передний и задний. На этом этапе вы можете захотеть создать в своей библиотеке папку под названием «Корпус» и переместить в нее оба клипа вместе с любыми дополнительными клипами, которые они используют.

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



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

Создайте новый символ видеоклипа и назовите его «Reel».

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

Ниже цвет


Выделенные контуры дают некоторое представление о том, как я сконструировал свою катушку, и вы также можете увидеть, как должна выглядеть ваша готовая катушка.


Чтобы увидеть мою версию с открытым исходным кодом / cassette-no-code.fla, найдите символ фрагмента ролика Reel в библиотеке и откройте его:



У нас есть символ клипа, который представляет ролик. Теперь мы можем создать анимацию поворота барабана.

Создайте новый символ видеоклипа и назовите его «Reel Turning».

Переименуйте слой в «Reel» и перетащите символ ролика Reel из библиотеки на сцену. Центрируйте экземпляр фрагмента ролика на сцене.

Переместите кадр 90 и создайте ключевой кадр, выбрав: «Вставить | Хронология | Keyframe.


Вернитесь к началу временной шкалы и щелкните правой кнопкой мыши кадр 1. В контекстном меню выберите «Создать классическую анимацию». (Если вы используете Flash CS3, выберите «Создать анимацию движения»)

На панели «Свойства» фрейма установите для поля «Поворот» значение: CCW . (Если вы используете Flash CS4 или CS5, то вам может потребоваться расширить категорию Tweening, чтобы открыть поле Rotate)


В настоящее время кадры 1 и 90 идентичны, что не позволяет нашей анимации зацикливаться идеально.

Переместитесь к концу временной шкалы и щелкните правой кнопкой мыши на кадре 89. В контекстном меню выберите «Вставить ключевой кадр». Теперь щелкните правой кнопкой мыши на кадре 90 и выберите «Удалить кадры». У вас останется 89 кадров на вашей временной шкале.

Это небольшое изменение позволит анимации поворота плавно зацикливаться.

Чтобы увидеть мою версию с открытым исходным кодом / cassette-no-code.fla, найдите символ клипа Reel Turning в библиотеке и откройте его:



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

Создайте новый символ видеоклипа и назовите его «Ролик».

Ваш готовый ролик должен выглядеть так:


Моя окончательная версия может быть найдена в библиотеке source / cassette-no-code.fla:



Процедура анимации направляющего ролика практически идентична процедуре на барабане.

Создайте новый символ видеоклипа и назовите его «Roller Turning».

Переименуйте слой в «Ролик» и перетащите символ ролика ролика из библиотеки на сцену. Центрируйте экземпляр фрагмента ролика на сцене.

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

Перейдите к кадру 45 и создайте ключевой кадр, выбрав: «Вставить | Хронология | Keyframe.


Вернитесь к началу временной шкалы и щелкните правой кнопкой мыши кадр 1. В контекстном меню выберите «Создать классическую анимацию». (Пользователи Flash CS3 должны выбрать «Создать анимацию движения»).

На панели «Свойства» фрейма установите для поля «Поворот» значение: CCW .


Как и в случае с символом ролика «Поворот ролика», и первый, и последний кадры анимации движения будут идентичны, что препятствует плавному циклу анимации.

Переместитесь к концу временной шкалы и щелкните правой кнопкой мыши на кадре 44. Выберите «Вставить ключевой кадр». Теперь щелкните правой кнопкой мыши на кадре 45 и выберите «Удалить кадры».

Теперь ролик будет плавно зацикливаться при анимации.

Чтобы увидеть мою версию с открытым исходным кодом / cassette-no-code.fla, найдите символ ролика «Поворот ролика» в библиотеке и откройте его:



Давайте создадим новый символ фрагмента ролика под названием «Детали» и перетащим в него два экземпляра Turning Turning и два экземпляра Roller Turning из библиотеки.

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

Сядьте барабаны на слой с именем «Катушки», а ролики — на слой с именем «Катушки».

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

Назовите экземпляры барабана «reel_left» & «reel_right», а экземпляры ролика «roller_left» & «roller_right».

Символ клипа «Детали» должен выглядеть следующим образом (исключая направляющий слой):



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

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

Мы пока проигнорируем реальную ленту и вернемся к ней в шаге 15.

Вот как должен выглядеть символ вашего готового фрагмента ролика:


Для более подробной информации, ознакомьтесь с моей окончательной версией символа фрагмента ролика. Откройте символ фрагмента ролика в библиотеке source / cassette-no-code.fla:



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

Создайте новую папку и назовите ее «PartsFolder». Теперь переместите символ фрагмента ролика Parts и все связанные клипы в эту новую папку. Также разместите здесь символы видеоклипа, связанные с барабанами и роликами. Теперь переименуйте папку в «Детали».

Примечание: Flash будет жаловаться, когда вы пытаетесь создать папку с таким же именем, что и символ на том же уровне. Вот почему мы изначально назвали нашу папку PartsFolder, а затем переименовали ее после перемещения символа фрагмента ролика.

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

Ваша библиотека должна быть аккуратнее и выглядеть примерно так:



Время почувствовать, как развивается наша аудиокассета.

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

Создайте новый символ видеоклипа и назовите его «Audio Cassette».

Внутри этого клипа создайте три слоя и назовите их «Front», «Parts» и «Back». Фронт должен быть верхним слоем, а сзади — снизу.

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


Перетащите символ Back мувиклипа из библиотеки на задний слой. Используйте направляющий слой, чтобы помочь расположить его.

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

Наконец, поместите передний символ видеоклипа на передний слой.

Вернитесь к корневой временной шкале и перетащите клип Audio Cassette на сцену. Назовите экземпляр «кассета».

Вещи должны начать собираться вместе:



Мы почти закончили создание пользовательского интерфейса. Последняя задача — создать ленту, которая наматывается на катушки и катится по роликам.

Мы создадим отдельный символ фрагмента ролика, который будет представлять ленту, и поместим его в наш фрагмент ролика. Вот то, над чем мы будем работать в следующие несколько шагов:


А вот как будет выглядеть окончательный символ клипа на ленте:


Клип на самом деле разделен на три отдельные части. Один для ленты, обернутой вокруг левой катушки и ролика. Другой для ленты, обернутой вокруг правой катушки и ролика. И горизонтальная линия внизу, соединяющая обе стороны.


Начнем с создания ленты, обернутой вокруг левой катушки и ролика.

Создайте новый символ видеоклипа и назовите его «Лента слева». Нам снова понадобится направляющий слой с эталонным растровым изображением, поэтому давайте его создадим. Также создайте два дополнительных слоя над ним. Назовите самый верхний слой «Лента», а второй слой — «Slack».

Слой ленты будет представлять ленту, которая наматывается на катушку. Слой Slack представляет ленту, которая отходит от катушки и проходит через ролик в нижней левой части кассеты.

Давайте сначала сконцентрируемся на слое «Лента».

Мы собираемся создать черный круг, чтобы представить ленту, которая намотана на катушку. Для этого мы воспользуемся инструментом Oval Primitive, так как кругу понадобится пробить отверстие в его центре.

Сначала нам нужно перетащить на сцену правителей, чтобы помочь. Если линейки не включены, выберите из выпадающего меню: View | Линейки. (Ctrl + Alt + Shift + R)

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


Теперь давайте сделаем то же самое с внешними краями ленты катушки.


По сути, мы использовали линейки для создания внешней коробки и внутренней коробки.

Выберите инструмент «Овальный примитив» на панели «Инструменты». Вы можете выбрать его, удерживая левую кнопку мыши над Rectangle Tool, а затем выбрав Oval Primitive Tool из появившейся всплывающей панели. Или нажмите Shift + O дважды.


В инспекторе свойств выберите цвет без обводки


и цвет заливки


из #000000 .

Используя Oval Primitive Tool, нарисуйте круг от верхнего левого угла внешнего блока до его правого нижнего угла (удерживая нажатой клавишу Shift, сделайте это, чтобы ограничить его кругом, а не овалом). На панели «Свойства» настраивайте внутренний радиус овального примитива, пока не получите отверстие, которое прочно закреплено во внутренней коробке, созданной линейками.


Вставьте пустой ключевой кадр в кадр 480 слоя Tape, выбрав: Вставить | Хронология | Пустой ключевой кадр из выпадающего меню.

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


Фактически мы создали начальное и конечное состояние ленты на левой катушке. Для начала вся лента находится на левой катушке. Конец только тонкий слайд останется.

Последний шаг — создание анимации формы между двумя ключевыми кадрами. Выберите первый кадр, затем в раскрывающемся меню выберите: Вставить | Форма Твин. Проведите по временной шкале, чтобы увидеть сжатие ленты в течение 480 кадров.


Оставаясь внутри символа фрагмента ролика Tape Left, заблокируйте слой Tape и выберите первый кадр слоя Slack.

Выберите инструмент Line Tool (N) на панели инструментов и установите его цвет


до #000000 .

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


для вашей строки (я выбрал #ff0000 ), как показано здесь:


Перейдите к кадру 480 и создайте ключевой кадр, выбрав: «Изменить» | Хронология | Преобразовать в ключевой кадр из выпадающего меню. Это создаст точную копию строки в кадре 480.

Вернитесь к кадру 1.

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


Изменить цвет линии


вернуться к #000000 .

Снова перейдите к кадру 480.

С помощью инструмента «Выделение» (V) перетащите верхнюю точку, пока она не коснется левой стороны барабана. Я бы порекомендовал вам скрыть направляющий слой при этом.


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


Измените цвет линии обратно на #000000 .

Скройте слой Справочного руководства.

Создайте анимацию формы между двумя ключевыми кадрами. Щелкните правой кнопкой мыши первый кадр, затем в меню выберите «Создать анимацию формы».

Проведите по временной шкале, чтобы просмотреть анимацию. Обратите внимание, что в течение 480 кадров, провисание начинает отдаляться от ленты, намотанной на катушку. Это можно исправить, добавив подсказки формы в анимацию.

Вернитесь к началу временной шкалы. Выберите: Изменить | Форма | Добавьте Shape Hint (Ctrl + Shift + H) из выпадающего меню.

Красный круг с буквой «а» появится на сцене.


Скройте слой Tape и просто переместите круг к вершине линии на слое Slack.


Перейдите к кадру 480 и еще раз переместите красный кружок к верхнему концу линии в слэке Slack. На этот раз круг должен изменить цвет


зеленым, указывая, что Flash понял подсказку.


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

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

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

Взгляните на ленту слева в файле source / cassette-no-code.fla.


Вы можете видеть, что я применил дополнительные подсказки формы к слою Slack в кадрах 89 и 222.


Процедура более или менее идентична для правой катушки.

Создайте новый символ видеоклипа и назовите его «Лента справа». Создайте слои, идентичные слоям в клипе Tape Left.

Вы можете сэкономить время, скопировав начальный и конечный кадры со слоя ленты в Tape Left и вставив их в символ клипа Tape Right. Просто не забудьте поменять свои позиции. Первый кадр слева от ленты должен быть конечным кадром справа от ленты, а конец кадра слева от ленты должен быть первым кадром ленты справа.

Вы также можете скопировать и вставить слабые линии. Опять же, помните, что строка в первом кадре ленты слева должна быть скопирована в конечный кадр ленты справа, а линия в конце кадра ленты слева должна быть первым кадром ленты справа.

Вам также нужно будет перевернуть обе строки, выбрав: Изменить | Преобразовать | Отразить по горизонтали из раскрывающегося меню.

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


И это на последнем кадре:



Создайте новый символ видеоклипа и назовите его «Лента».

Добавьте направляющий слой и перетащите на него эталонный растр. Заблокируйте слой.

Создайте дополнительный слой над ним с именем «Лента». Перетащите экземпляр Tape Left и Tape Right из библиотеки на слой. Использование эталонного растрового изображения в качестве вспомогательного средства, расположить оба экземпляра. Пометить экземпляры «слева» и «справа» соответственно.

С помощью инструмента «Линия» (N) нарисуйте горизонтальную линию между обеими секциями ленты. Выберите цвет


и толщину обводки для линии, которая соответствует ширине провисания ленты в символах фрагмента ролика Tape Left и Tape Right.

Ваш символ клипа Tape должен выглядеть следующим образом:


Шаги 15 — 19 охватили много вопросов. Если вы находите их трудными, вы можете изучить мою версию. Откройте файл source / cassette-no-code.fla, найдите клип в ленте и откройте его.


Потратьте некоторое время, копаясь глубже в своих видеоклипах. Обратите особое внимание на анимацию намотки ленты.


Теперь, когда у нас есть символ фрагмента ролика ленты, давайте добавим его в символ фрагмента фрагмента ролика.

Найдите клип частей в своей библиотеке и откройте его.

Создайте слой с именем Tape.

Организуйте слои так, чтобы слой Rollers находился над слоем Tape, а слой Reels — под слоем Tape.


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



Пришло время еще раз привести в порядок библиотеку.

Переместите все связанные с лентой клипы, которые находятся в корне вашей библиотеки, в папку Tape.



Визуальные эффекты теперь завершены.

Проверьте свой фильм, выбрав: Control | Тестовый фильм | в Flash Professional (Ctrl + Enter) из выпадающего меню. (Если вы используете Flash CS3 или CS4, выберите: Control | Test Movie)

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


Время написать какой-нибудь ActionScript. Мы начнем с создания класса документа и добавления некоторого кода для первоначального прекращения анимации на временной шкале, которая автоматически запускается при тестировании нашего фильма.

Итак, создайте новый файл ActionScript 3 и добавьте в него следующее:

Сохраните класс в том же месте, где находится ваш FLA, и назовите его Application.as .

Щелкните левой кнопкой мыши по сцене (не нажимайте ни на какие экземпляры фрагмента ролика, сидящие на сцене) и установите в поле «Класс документа» на панели «Свойства» значение: Application .

Наш класс документов не делает ничего ужасно захватывающего в данный момент. Объявлена ​​переменная-член, представляющая cassette клип, который находится на сцене. Внутри конструктора мы слушаем событие ADDED_TO_STAGE , и когда оно отправляется, мы не позволяем ADDED_TO_STAGE перемещаться вдоль различных временных шкал фрагмента ролика, которые представляют барабаны, ролики и ленту.

Проверьте свой фильм (Ctrl + Enter). Вы должны увидеть аудиокассету, неподвижно сидящую на сцене.


Давайте сосредоточимся сейчас на фактическом коде, необходимом для потоковой передачи mp3.

Если вы посмотрите окончательный SWF для этого урока, вы увидите, что пользователь может проигрывать и приостанавливать музыку, нажимая на кассету. Кроме того, позволяя музыкальному потоку в течение короткого периода времени, должно стать очевидным, что анимация намотки ленты привязана к продолжительности и текущей точке, воспроизводимой в mp3.

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

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

Давайте создадим новый класс ActionScript 3 и объявим эти два события:

Класс выше просто создает две статические константы, которые представляют каждое событие — PLAYING и STOPPED . На следующих нескольких шагах мы создадим менеджер звука, который фактически создает и отправляет эти события в ответ на потоковую передачу и остановку музыки.

Сохраните класс как SoundEvents.as в той же папке, что и ваш FLA.


Как обсуждалось на шаге 24, именно диспетчер звука будет реагировать на то, что пользователь нажимает на экземпляр кассеты.

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

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

Отсюда мы можем начать создавать класс для представления менеджера звука. Создайте новый файл класса ActionScript 3 и добавьте следующий код:

Сохраните класс как SoundManager.as в той же папке, что и ваш FLA.

Наш класс менеджера звука имеет три метода и три свойства, которые представляют его общедоступный API.

Есть метод setup() который принимает строку, представляющую URL воспроизводимого mp3-файла. А для воспроизведения класс предоставляет методы play() и pause() .

Также можно запросить диспетчер звука, чтобы определить, в каком состоянии он находится в данный момент, через свойства paused , playing и stopped которые мы определили.

Класс внутренне отслеживает свое собственное состояние через объявленную переменную закрытого состояния. В классе объявлены три частные константы, представляющие состояния, в которых может находиться диспетчер звука: STOPPED , PAUSED , PAUSED .

Менеджер звука начинает жизнь в состоянии STOPPED . Когда вызывается метод play() , менеджер звука переходит в состояние PLAYING . Вызов pause() переведет диспетчер звука в состояние PAUSED . Когда воспроизведение mp3 завершено, менеджер звука перейдет в состояние STOPPED .

Поскольку управляемый звук должен иметь возможность отправлять SoundEvent класса SoundEvent и STOPPED класса SoundEvent , мы расширили библиотеку классов ActionScript 3 Flash, класс EventDispatcher . Посмотрите на методы play() и pause() . Вы увидите отправленные события PLAYING и STOPPED .

Подробнее о классе EventDispatcher Flash можно EventDispatcher на его странице на справочном сайте Adobe ActionScript 3.0 .

Постарайтесь не путать внутренние состояния менеджера звука со звуковыми событиями, которые он отправляет. Внутренние состояния ( STOPPED , PAUSED и PAUSED ) являются частными константами класса и используются внутри системы для отслеживания состояния. С другой стороны, события ( PLAYING и STOPPED ) являются общедоступными статическими константами, которые находятся в классе SoundEvents .

Также обратите внимание на комментарии @todo разбросанные по всему классу в данный момент. Это указывает на функциональность, которую мы еще должны добавить.


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

Переместитесь в класс Application.as и добавьте новую переменную-член:

И добавьте следующие строки в конце метода addedToStage() :

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

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

Опубликуйте и протестируйте свой фильм. Ваши операторы трассировки будут отправлены на панель «Вывод» и должны выглядеть следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
sound manager instantiated
playing?
paused?
stopped?
  
play()
playing?
paused?
stopped?
  
pause()
playing?
paused?
stopped?
  
play()
playing?
paused?
stopped?

Как и следовало ожидать, результаты, приведенные выше, показывают, что менеджер звука изначально находится в состоянии STOPPED . После выполнения вызова play() менеджер звука переходит в состояние PLAYING . Затем вызывается метод pause() звукового менеджера, переводящий его в состояние PAUSED . Наконец, выполняется второй вызов play() , который снова PAUSED диспетчер звука из состояния PAUSED состояние PAUSED .

Убедившись, что ваш первоначальный удар в диспетчере звука работает должным образом, удалите тестовый код. Оставьте строку, которая объявляет менеджер звука, и строку, которая его создает, но удалите все остальное. Ваш addedToStage() теперь должен выглядеть так:


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

Добавьте следующие строки кода в метод addedToStage() :

Теперь напишите следующие два метода прослушивания событий:

Когда диспетчер звука отправил событие musicPlaying() будет вызван метод musicPlaying() класса документа. Когда диспетчер звука отправляет событие STOPPED , musicStopped() метод musicStopped() класса документа.

На данный момент оба метода просто отправляют оператор trace на панель Output, но позже мы напишем некоторый код для запуска и остановки анимации кассеты в ответ на эти события.

Давайте напишем некоторый тестовый код, чтобы убедиться, что слушатели событий действительно вызваны в ответ на события, отправленные менеджером звука. Мы сделаем те же вызовы, что и на шаге 26, при тестировании внутреннего состояния менеджера звука. Просто добавьте следующие строки кода в конце метода addedToStage() :

Опубликовать и запустить фильм. Вы должны увидеть следующие следы в ответ на каждый из вызовов:

Удалите три строки тестового кода, которые мы только что добавили.


Пришло время на самом деле транслировать музыку.

Мы будем использовать следующие два класса из библиотеки классов ActionScript: Sound и SoundChannel .

Класс Sound позволяет загружать и воспроизводить внешний mp3-файл. Класс SoundChannel используется для управления воспроизводимой музыкой. Мы будем использовать его для определения текущей точки, которая воспроизводится в mp3, достигнут ли она конца, и приостановить ее.

Более подробную информацию о классах Flash и SoundChannel можно найти на справочном сайте Adobe ActionScript 3.0 .

Перейдите в свой класс SoundManager и добавьте следующие переменные-члены:

Первые две переменные будут указывать на экземпляры классов Sound и SoundChannel , которые необходимы для воспроизведения и управления музыкальным файлом. Третья переменная, pos , используется для хранения в миллисекундах текущей позиции mp3. Эта переменная полезна, когда музыка приостановлена, что позволяет нам позже возобновить воспроизведение музыки с той же самой позиции.

Давайте добавим некоторый код в метод setup() для загрузки указанного mp3-файла:

Метод довольно тривиальный. Запрос URL создается из строки URL музыкального файла, а затем используется при создании экземпляра объекта Sound . Ссылка на объект Sound хранится в переменной-члене snd мы объявили ранее на этом шаге.

Теперь мы готовы завершить код нашего метода play() с помощью нашей переменной-члена snd а также получить и использовать ссылку на объект SoundChannel .

Метод play() должен обрабатывать две ситуации. Когда музыка в данный момент остановлена ​​и когда музыка в данный момент приостановлена. Добавьте следующий код в ваш метод play() :

Код практически идентичен для обоих случаев. Класс Sound предоставляет собственный метод play() который используется для запуска воспроизведения открытого mp3-файла. Наш код вызывает метод play() переменной snd member, который начинает воспроизведение потокового mp3-файла и возвращает ссылку на SoundChannel . Мы сохраняем ссылку на объект sndChan переменной-члене sndChan .

Объект SoundChannel отправил событие SOUND_COMPLETE после завершения воспроизведения mp3-файла. Мы добавляем прослушиватель событий в наш экземпляр sndChan для прослушивания этого события.

Обратите внимание, что переменная-член pos передается в качестве аргумента методу play() объекта snd . Это заставляет mp3-файл начать воспроизведение определенного количества миллисекунд в музыке.

Единственное различие между кодом в двух операторах if состоит в том, что переменная-член pos сбрасывается в 0 если менеджер звука ранее находился в своем stopped состоянии. Это гарантирует, что музыка начинает воспроизводиться с начала mp3-файла. Если ранее он PAUSED состоянии PAUSED , мы не сбрасывали переменную-член pos поскольку хотим, чтобы mp3-файл продолжал воспроизводиться с того места, где он остановился.

Добавьте версию-заполнитель метода soundFinishedPlaying() который вызывается после завершения воспроизведения mp3-файла:

Мы использовали несколько классов из встроенной библиотеки классов Flash. Добавьте следующие операторы импорта рядом с существующими операторами импорта в вашем классе SoundManager :


Давайте проверим последнюю версию звукового менеджера.

Сначала перейдите к классу документа и добавьте новую константу, содержащую URL-адрес mp3-файла для воспроизведения. Мы предполагаем, что mp3-файл будет находиться в том же месте, что и ваш SWF:

Вы можете найти mp3 файл по адресу: source/any-other-way.mp3. Скопируйте его в то же место, что и ваш FLA.

Огромное спасибо Brown Eye Superfly за предоставленную возможность использовать их трек Any Other Way.

Теперь addedToStage()сделайте вызов setup()метода звукового менеджера , передав ему URL-адрес mp3-файла. Наконец, вызовите его play()метод. Вот изменения:

Опубликуйте и протестируйте свой фильм. Должен начаться воспроизведение файла mp3, а диспетчер звука должен отправить PLAYINGсобытие, в результате чего следующий оператор трассировки будет отправлен на панель «Вывод» с помощью musicPlaying()метода класса документа :

1
Music playing

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

Давайте начнем с добавления кода, чтобы приостановить музыку.

Вернитесь к SoundManagerклассу и добавьте следующие строки в его pause()метод:

Две новые строки кода выше сохраняют текущую точку, которая воспроизводится в файле mp3 перед остановкой воспроизведения.

Класс API AS3 SoundChannelпредоставляет positionсвойство, которое возвращает текущую точку, которая воспроизводится в звуковом файле. Мы использовали это свойство для получения из sndChanпеременной-члена количества миллисекунд в mp3-файле, которым мы являемся, и сохранили его в переменной-члене pos для последующего использования методом менеджера звука play().

Как только позиция известна и сохранена, делается вызов, чтобы остановить воспроизведение mp3-файла. Это делается с помощью stop()метода, который предоставляется SoundChannelклассом.


Теперь давайте разберемся с ситуацией, когда mp3-файл воспроизводится до конца.

На шаге 28 мы добавили soundFinishedPlaying()прослушиватель событий, который вызывается после завершения воспроизведения mp3-файла.

Завершите метод, добавив к нему следующее:

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

Помните, что в шаге 27 из нашего класса документов мы добавили слушателя в менеджер звука именно для этого самого события. Вот код снова в качестве напоминания:

По сути, всякий раз, когда mp3-файл воспроизводится до конца или делается вызов, чтобы остановить менеджер звука, воспроизводящий музыку, метод класса документа musicStopped()будет выполняться в ответ.


Давайте проверим нашу текущую версию SoundManagerкласса, добавив немного взаимодействия.

Мы напишем некоторый код в нашем классе документов, чтобы проверить щелчок мышью на cassetteэкземпляре фрагмента ролика и переключить воспроизведение и приостановку нашего mp3-файла.

Сначала перейдите к addedToStage()методу и удалите следующую строку:

Мы больше не будем сразу же начинать воспроизведение mp3-файла. Вместо этого мы будем ждать, когда пользователь впервые нажмет на аудиокассету.

Мы будем прислушиваться к событию мыши, поэтому добавим следующий оператор импорта в начале класса документа:

Добавьте следующую строку в конце addedToStage()метода, чтобы прослушать, как пользователь нажимает на cassetteфрагмент ролика:

Теперь напишите cassetteClicked()метод, который будет вызываться, когда пользователь нажимает на аудиокассету:

Код в этом методе довольно прост и действует как простой переключатель вкл / выкл для музыки. Если менеджер звука не воспроизводит музыку, вызовите его play()метод. В противном случае вызовите его pause()метод, чтобы остановить текущую музыку.


Опубликуйте и протестируйте свой фильм и попробуйте нажать на аудиокассету, чтобы включить воспроизведение музыки. Следует заметить, что операторы трассировки в классе документа musicPlaying()и musicStopped()обработчиках событий отображаются на панели «Вывод» в ответ на события, отправляемые менеджером событий.

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


Теперь мы напишем некоторый код для запуска и остановки анимации аудиокассеты в ответ на звуковой менеджер PLAYINGи STOPPEDсобытия.

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

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

Сначала создайте новый класс ActionScript 3 и назовите его AudioCassette.as.

Добавьте следующий код в класс:

Код в этом классе должен выглядеть очень знакомым. Этот stopTape()метод содержит код ActionScript, который мы первоначально добавили в класс документа на шаге 23, чтобы остановить воспроизведение анимации аудиокассеты. Этот playTape()метод аналогичен и обеспечивает механизм запуска анимации аудиокассеты.

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

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

Так как cassetteClicked()метод требует ссылку на менеджер звука, объявлена sndManзакрытая переменная-член для хранения ссылки, и setup()был написан метод, позволяющий передать ссылку в AudioCassetteкласс.

Обратите внимание, что AudioCassetteкласс расширяется MovieClip. По сути, AudioCassetteкласс собирается предоставить дополнительную функциональность и публичные вызовы API всем экземплярам сцены аудиокассеты, которые находятся в вашей библиотеке.

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

Для этого найдите клип Audio Cassette в своей библиотеке. Щелкните правой кнопкой мыши на нем и выберите пункт меню «Свойства …».


Появится панель свойств символа. Установите флажок «Экспорт для ActionScript». Поле Class под ним должно заполниться названием вашего класса — AudioCassette. Нажмите кнопку ОК.


Теперь вернитесь к своему классу документа и удалите код, который был перемещен в AudioCassetteкласс. Код для удаления выделен ниже:


Теперь давайте внесем соответствующие дополнения в класс документа для настройки и использования AudioCassetteкласса. Обратите внимание, что нет необходимости создавать экземпляр AudioCassetteкласса. Это автоматически выполняется Flash Player для любых экземпляров аудиокассеты, которые находятся на сцене. В нашем случае у нас есть единственный экземпляр клипа cassette, на который ссылается класс документа через cassetteпеременную-член.

Дополнения, которые будут сделаны к классу документа, показаны ниже жирным шрифтом:

Обратите внимание, что cassetteтип переменной-члена был изменен с MovieClipна, AudioCassetteчтобы отразить тот факт, что у нас есть специализированный класс, который теперь представляет символ клипа аудиокассеты.

Остальные изменения не так сложны для отслеживания.

Внутри addedToStage()метода мы вызываем метод кассеты setup(), передавая ему ссылку на менеджер звука.

И внутри, musicPlaying()и musicStopped(), звонки сделаны, чтобы заставить аудиокассету запускать и останавливать ее анимации соответственно.


Опубликуйте и протестируйте свой фильм.

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

Фактически, единственное, что до сих пор работает не полностью, это анимация намотки ленты. Пусть музыка воспроизводится, и вы должны увидеть, что анимация ленты еще не синхронизирована с текущей позицией воспроизведения и длиной mp3-файла.


В данный момент анимация ленты просто воспроизводится по временной шкале до ее завершения, а затем возвращается к началу.

Что мы на самом деле хотим сделать, это определить, какой процент mp3-файлов был воспроизведен, и перейти на правильную позицию в пределах временной шкалы, чтобы отразить это.

Анимация намотки ленты составляет 480 кадров. Если, например, 50% файла mp3 было воспроизведено, то мы хотим остановить воспроизведение временной шкалы на кадре 240.

Мы можем определить, к какому кадру перейти, используя следующую формулу:

frame = ( position / length ) * total_frames

где

  • frame: это кадр на временной шкале, на который нужно перейти.
  • position: текущая позиция в mp3, измеренная в миллисекундах.
  • length: длина mp3, указанная в миллисекундах.
  • total_frames: это общее количество кадров на временной шкале ленты.

Эта формула демонстрирует некоторые недостатки открытого API нашего менеджера звука. В настоящее время он не предоставляет никакого способа определения длины или текущей позиции mp3-файла.

Давайте рассмотрим это сейчас. Перейдите в SoundManagerкласс и добавьте следующие два общедоступных метода получения:


Теперь мы можем написать код ActionScript, чтобы обновить положение ленты, чтобы отразить текущую точку в воспроизводимом mp3-файле.

Мы создадим два новых класса, чтобы справиться с этим. Оба класса будут расширяться MovieClip. Мы свяжем один класс с символом фрагмента ролика Tape Left в нашей библиотеке, а другой класс — с символом фрагмента ролика Tape Right. Каждый класс будет иметь закрытую переменную-член, которая ссылается на менеджер звука.

Мы начнем с написания класса для клипа Tape Left. Создайте файл ActionScript 3 и назовите его TapeLeft.as. Добавьте следующий код структуры:

Класс имеет закрытую переменную-член с именем sndMan, которая получает наборы для ссылки на менеджер звука из setup()метода.

В настоящее время в AudioCassetteклассе stopTape()и playTape()методах существует код для остановки и воспроизведения анимации временной шкалы левой ленты. Однако вскоре мы удалим этот код, поскольку теперь он будет обрабатываться непосредственно в нашем TapeLeftклассе.

Вы можете увидеть это частично в действии в addedToStage()методе, который мы добавили к классу выше. Метод останавливает точку воспроизведения временной шкалы в кадре 1. enterFrame()Метод, который мы еще не завершили, будет отвечать за мониторинг текущей позиции в файле mp3 и соответственно обновлять точку воспроизведения временной шкалы.

Давайте продолжим и закончим enterFrame()метод, используя формулу, которую мы обсуждали:

Найдите клип Tape Left в своей библиотеке. Щелкните правой кнопкой мыши на нем и выберите пункт меню «Свойства …». На панели «Свойства символа» установите флажок «Экспорт для ActionScript» и убедитесь, что поле «Класс» заполнено именем вашего класса — TapeLeft. Нажмите кнопку ОК.


Код, необходимый для клипа Tape Right, идентичен, поэтому мы можем просто повторно использовать TapeLeftкласс.

Найдите в вашей библиотеке символ клипа «Лента справа». Щелкните правой кнопкой мыши на нем и выберите пункт меню «Свойства …». Установите флажок «Экспорт для ActionScript» — поле класса будет автоматически установлено на TapeRight. Тем не менее, мы на самом деле не создали TapeRightкласс. Вместо этого сообщите Flash IDE, что вы хотите использовать TapeLeftкласс, поместив его имя в поле Base Class.


При нажатии кнопки «ОК» в Flash IDE отобразится панель со следующим предупреждением:


Это то, что мы хотим, поэтому нажмите ОК.


Теперь осталось только внести некоторые изменения в AudioCassetteкласс.

Удалите строки кода, отвечающие за запуск и остановку анимации ленты. Они показаны ниже жирным шрифтом , в пределах playTape()и stopTape()методов:

Теперь добавьте следующие строки кода в setup()метод:

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


Вот и весь код, необходимый для этого проекта.

Идите вперед, опубликуйте и протестируйте свой фильм.

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


Мы многое изучили и воспользовались как инструментами дизайна Flash, так и ActionScript 3, чтобы воплотить в жизнь практически фотореалистичный ретро-аудиокассетный музыкальный проигрыватель.

Надеемся, что это руководство научило вас использовать инструменты рисования Flash и язык программирования ActionScript 3. Совместное использование обоих может помочь сократить время разработки и дать невероятные результаты

В то время как визуальные и аудио результаты поразительны, вас может поразить окончательный размер файла SWF. Формат файла SWF невероятно компактен. Если Flash IDE и его инструменты используются правильно, это может привести к публикации невероятно маленьких файлов.

Возьмите наш последний SWF в качестве примера. Это всего лишь 18 КБ. Чтобы дать вам некоторую перспективу, которая значительно меньше, чем размер файла 97 КБ исходного эталонного растрового изображения, которое вы использовали при прохождении этого учебного руководства.

Другими словами, наш полностью интерактивный SWF-поток с анимацией составляет примерно одну пятую размера нашего статического изображения в формате PNG!

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

Спасибо за прочтение!