Рубрика | AS3, Видео

Программная анимация на основе EnterFrame (+видео)

Опубликовано: 08 Февраль 2010. Автор: kFrame

Доброго времени суток. У нас новый урок по AS3, и этот урок освящен снова программной анимации. Недавно мы немного зацепили тематику событий, слушателей и обработчиков этих самых событий. Сегодняшняя цель - разобраться с понятием события EnterFrame и как с его помощью создавать анимацию. В полной версии поста текстовый урок и видеоурок (продолжаю учиться и экспериментировать с созданием видеоуроков). Для напоминания себе что же такое событие можно открыть урок Понимание классов AS3. В видео это приблизительно срединка. Ниже у нас видео урок а потом приблизительно то же самое в тексте, но более лаконично и местами дополнительные комментарии. К сожалению с некоторых пор на YouTube загружать видео длиннее 10 мин запрещено и в связи с этим данный урок был загружен на Vimeo. В связи с чем в шапке сайта появилась ссылочка моего видео на Vimeo.

This movie requires Flash Player 9

Приступим к практике - создаем в одной папке два файла - я оба назвал enterFrameAnimation - один .fla а другой .as и в файле enterFrameAnimation.fla на панели PROPERTIES записываем enterFrameAnimation. Что это значит как это делается мы по умолчанию знаем, а если не знаем или не помним - открываем AS3 во Flash IDE (CS4) – начало. Относительно графики, которую мы станем анимировать - тут оставляю все на ваш выбор: рисуйте, отрисовывайте или импортируйте внешний файл. Поскольку основная цель урока создать анимацию а не графику, то я импортировал внешний файл (File->Import->Import to Stage или же клавишами Ctrl+R). Выделяем рисунок мышкой и нажимаем клавишу F8 для преобразования  его в символ. Привязку оставляем по умолчанию, тип - MovieClip , а название logo. Отмечаем галочку Export for ActionScript и в поле Base class меняем MovieClip на Sprite. Зачем это делается? - Это делается для уменьшения размера конечного .swf файла. Для данного случая экономия не существенна, у меня она составила всего 27 байт, но и приложение не самое громадное. Причина разницы размеров вытекает из разницы типов MovieClip и Sprite (Sprite это однокадровый урезанный MovieClip - мы об этом говорили). Все с файлом enterFrameAnimation.fla мы закончили - осталось почистить за собой: удаляем графику с рабочей зоны и жмем Ctrl+S для сохранения. Переходим в .as файл и записываем код:

package
{
    import flash.display.Sprite;
    import flash.events.Event;//класс для возможности использовать события
 
    public class enterFrameAnimation extends Sprite
    {
        var _logo:logo;// объявляем переменную типа logo
 
        public function enterFrameAnimation()
        {
            _logo =  new logo();
            addChild(_logo);// добавляем в список отображения
            this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            // добавляем слушатель события EnterFrame
        }
 
        public function enterFrameHandler(e:Event):void// обработчик события
        {
             _logo.x=_logo.x+1;
             // запись равнозначна вот такой _logo.x+=1;
             // и вот такой _logo.x++;
        }
    }
}

с конструкцией addEventListener мы уже встречались - данная функция создает слушатель события и она имеет 2 аргумента (кто такие аргументы - мы уже тоже знаем). Первый аргумент это событие, которое слушается, т.е. событие на которое будет реакция - запуск функции-обработчика события. Название этой функции и есть второй аргумент.
обратим внимание на сам обработчик:

function enterFrameHandler(e:Event):void

функция ничего не возвращает, поэтому ее тип void, сама же функция имеет аргумент e типа Event, т.е. событие. В нашей функции мы аргумент не используем, но бывает и по другому!
Внутри функции записана единственная исполнимая строка

_logo.x=_logo.x+1;

Вроде ничего сверх сложного: значение координаты x символа _logo будет прибавляться каждый раз когда запускается функция, т.е. 24 раза в секунду, а это значит что символ _logo будет перемещаться вправо со скоростью 24 пикселя в секунду. Обратите внимание на закомментированые строки!
Давайте немного усложним анимацию, изменив обработчик событий. Для этого подключаем немного знаний из области математики и собственно математические функции, принадлежащие к классу Math:

package
{
    import flash.display.Sprite;
    import flash.events.Event;
 
    public class enterFrameAnimation extends Sprite
    {
        var _logo:logo;
        var counter:int;// переменная для математических функций
        // int - целочисленный тип
        public function enterFrameAnimation()
        {
            _logo =  new logo();
            counter =0;// начальное значение переменной counter
            addChild(_logo);
            this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
 
        public function enterFrameHandler(e:Event):void
        {
            _logo.x=100 + Math.sin(counter);
            counter++;
        }
    }
}

Посмотрим что у нас изменилось. Мы объявили целочисленную переменную counter перед конструктором. Внутри конструктора задали ей начальное значение 0, хотя конкретно для нашего случая это не имеет никакого значения. Отдельно рассмотрим что происходит внутри обработчика событий. значение координаты x формируется из двух частей: постоянной -число 100, и переменной - Math.sin(counter). Вспоминая свойства функции sin знаем что она принимает значения в диапазоне от -1 до +1, а число 100 это постоянное смещение по оси x. Таким образом если скомпилировать наш скрипт в нынешнем виде, то мы увидим едва заметное подрагивание влево-вправо на 1 пиксель вокруг точки с координатой 100! Давайте увеличим амплитуду этих колебаний домножив значение синуса на 15 и уменьшим частоту (скорость анимации) разделив аргумент синуса на 4:

_logo.x=100 + Math.sin(counter);

Сохраняем и компилируем - любуемся результатом и сразу переходим к усложнению примера. Убедимся в том что таким образом можно анимировать не один объект. Добавляем новый символ _logo2 и в обработчике событий изменяем его координату y:

package
{
    import flash.display.Sprite;
    import flash.events.Event;
 
    public class enterFrameAnimation extends Sprite
    {
        var _logo:logo;
        var _logo2:logo;
        var counter:int;
        public function enterFrameAnimation()
        {
            _logo =  new logo();
            _logo2 =  new logo();
            counter =0;
            addChild(_logo);
            addChild(_logo2);
            this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
 
        public function enterFrameHandler(e:Event):void
        {
            counter++;
            _logo.x=100 + 15*Math.sin(counter/4);
            _logo2.y=100 + 15*Math.sin(counter/4);
        }
    }
}

Сохраняем и тестируем что вышло. Уррра - оно шевелится :-) ! убеждаемся что анимация может проходить с разной скоростью:

_logo2.y=100 + 15*Math.sin(counter/4);

В этой строке меняем частоту: вместо 4 ставим 3, сохраняем и компилируем - и снова шевелится! Ниже добавляем строку

_logo2.x=100 + 15*Math.sin(counter/3);

И видим как второй спрайт двигается вдоль диагонали. Почему? - Потому что координаты x и y получают одинаковые значения.
Фух-х-х, надеюсь не устали от таких экспериментов)) у нас остался еще один пример. Постоянную составляющую в формулах вычисления координат для _logo2 меняем с 100 на 150 - это для того что бы не мешать первому символу. Далее в одной из формул, не важно в которой, меняем sin на cos сохраняем и тестим. О чудо - второй символ начал двигаться по окружности)) ! Полный текст кода ниже:

package
{
    import flash.display.Sprite;
    import flash.events.Event;
 
    public class enterFrameAnimation extends Sprite
    {
        var _logo:logo;
        var _logo2:logo;
        var counter:int;
        public function enterFrameAnimation()
        {
            _logo =  new logo();
            _logo2 =  new logo();
            counter =0;
            addChild(_logo);
            addChild(_logo2);
            this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
 
        public function enterFrameHandler(e:Event):void
        {
            counter++;
            _logo.x=100 + 15*Math.sin(counter/4);
 
            _logo2.x=150 + 15*Math.sin(counter/3);
            _logo2.y=150 + 15*Math.cos(counter/3);
        }
    }
}

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

_logo.alpha=Math.abs(Math.sin(counter/16));
// разберите этот код

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

Bookmark and Share

1 Комментарии к этой статье

  1. Mauri пишет:

    По поводу видео, погляди сюда http://uppod.ru/ :) и проблем с фидео не будет и не будеш зависить ни от каких видеохостингов.

Ваш отзыв

Advertise Here
Advertise Here