Мультфильмы ~ Матричные преобразования
Здравствуйте друзья!
Выкладываю обещанный 2 урок. Он предназначен для пользователей 8 версии. Необходимо владение языком АС 2.0.
Примерно так выглядит готовый вариант.

 

Это похоже на титры из какого-то фильма ("Звездные войны" кажись? :-)).
Как видите, я "перспективно" исказил символы в строке. Кроме того, строки масштабируются и перемещаются. Все эти преобразования мы сделаем с помощью матрицы, ни разу не обратившись, при этом, к стандартным свойствам клипов.
Для упрощения восприятия материала, я разбил код на 3, логически зависимые, части и буду комментировать их в порядке написания.
Теперь подготовка. Создайте в папке текстовый файл с текстом в несколько коротких строк (у меня кусочек песни И. Талькова) и сохраните его в кодировке UTF8 под именем "titles.txt".
Во флэше создайте новый однокадровый документ с двумя слоями и сохраните его в ту-же папку. На одном из слоев нарисуйте или импортируйте клип в виде кнопки повтора и дайте ему инстанс имя - "r_mc".
Второй слой мы бум использовать под код. Выделите его нажмите [F9] и вперед...

Часть 1. 
Инициализация пременных. Загрузка и парсинг текста. Стартовая подготовка.

// Пути к необходимым здесь классам&amp;nbsp;&lt;br /><br />

            import flash.geom.*;&lt;br /><br />

            import flash.display.*;&lt;br /><br />

            // Глобальные переменные&lt;br /><br />

            var titles:XML = new XML();&lt;br /><br />

            //Объект загрузчик текста&lt;br /><br />

            var lines:Array = [];&lt;br /><br />

            //Массив для хранения строк текста&lt;br /><br />

            var lineCount:Number;&lt;br /><br />

            //Счетчик строк. Нужен для отслеживания полного окончания анимации&lt;br /><br />

            //Формат символов&lt;br /><br />

            var tf:TextFormat = new TextFormat('Arial', 42, 0, true);&lt;br /><br />

            //var tf:TextFormat = new TextFormat('Arbat', 42, 0, true);&lt;br /><br />

            //Кнопку повтора спрячем&lt;br /><br />

            r_mc._visible = false;&lt;br /><br />

            /********************************************************/&lt;br /><br />

            //При успешной загрузе текста, вызовем процедуру его парсинга&lt;br /><br />

            /**/&lt;br /><br />

            titles.ignoreWhite = true;&lt;br /><br />

            titles.onload = function(succes) {&lt;br /><br />

            if (!this.loaded || this.status) {&lt;br /><br />

            &amp;nbsp;throw new Error('An error occured while loading XML');&lt;br /><br />

            &amp;nbsp;return;&lt;br /><br />

            }&lt;br /><br />

            var txt = this.firstChild.toString();&lt;br /><br />

            parse(txt);&lt;br /><br />

            };&lt;br /><br />

            /*Парсер весьма прост. Определим символ окончания строки. Дело в том, что он бывает разный. И забьем текст в массив&lt;br /><br />

            построчно, используя этот символ, в качестве разделителя.&lt;br /><br />

            Теперь можно запускать основную процедуру*/&lt;br /><br />

            function parse(arg:String) {&lt;br /><br />

            var ent:String = (arg.split('rn')).length>1 ? 'rn' : 'n';&lt;br /><br />

            lines = arg.split(ent);&lt;br /><br />

            generate();&lt;br /><br />

            }

 

Часть 2. 
Сейчас у нас есть массив "lines" содержащий текст из файла - построчно.
Мы сделаем для каждой строчки клип контейнер. В нем, создадим контейнеры для каждого символа этой строки. Туда "положим" растровые изображения символов и исказим матрицу каждого символьного контейнера. Теперь переведем всю строку в растр и уничтожим контейнеры символов, за ненадобностью. Такое решение позволило прилично снизить нагрузку на процессор. После выстроим клипы-строки внизу фильма, одну за другой, вне зоны видимости и запустим анимацию построчно.

function generate() {&lt;br /><br />

            r_mc._visible = false;&lt;br /><br />

            //Уберем кнопку повтора&lt;br /><br />

            var LL:Number = lines.length;&lt;br /><br />

            // Кол-во строк нашего текста&lt;br /><br />

            lineCount = 0;&lt;br /><br />

            //Сбросим счетчик строк. Он пригодится в процедуре анимации&lt;br /><br />

            for (var i:Number = 0; i&amp;lt;LL; i++) {&lt;br /><br />

            &amp;nbsp;//Теперь построчно:...&lt;br /><br />

            &amp;nbsp;var sl:Number = lines[i].length;&lt;br /><br />

            &amp;nbsp;// Кол-во символов в текущей строчке&lt;br /><br />

            &amp;nbsp;var l:Number = 20;&lt;br /><br />

            &amp;nbsp;// Левый отступ для 1-ого символа. Без него, при искажении, часть символа может "выпасть".&lt;br /><br />

            &amp;nbsp;var l_mc:MovieClip = this.createEmptyMovieClip('s'+i, this.getNextHighestDepth());&lt;br /><br />

            &amp;nbsp;// Сделаем клип, в который и будем собирать текущую строку. И после его проанимируем.&lt;br /><br />

            &amp;nbsp;for (var j:Number = 0; j&amp;lt;sl; j++) {&lt;br /><br />

            &amp;nbsp; // Для каждого символа в строке...&lt;br /><br />

            &amp;nbsp; var tmc:MovieClip = l_mc.createEmptyMovieClip('s'+j, l_mc.getNextHighestDepth());&lt;br /><br />

            &amp;nbsp; //Создаем клип-контейнер&lt;br /><br />

            &amp;nbsp; tmc.createTextField("txt", 0, 0, 0, 1, 1);&lt;br /><br />

            &amp;nbsp; //А в нем - текстовое поле&lt;br /><br />

            &amp;nbsp; tmc.txt.autoSize = true;&lt;br /><br />

            &amp;nbsp; tmc.txt.setNewTextFormat(tf);&lt;br /><br />

            &amp;nbsp; // Отформатируем поле&lt;br /><br />

            &amp;nbsp; tmc.txt.text = lines[i].charAt(j);&lt;br /><br />

            &amp;nbsp; //И нарисуем в нем текущий символ из текущей строчки&lt;br /><br />

            &amp;nbsp; tmc._x = l;&lt;br /><br />

            &amp;nbsp; l += (tmc._width-4);&lt;br /><br />

            &amp;nbsp; // Поставим клип на необходимое место в строке и подготовим указатель для следующего клипа.&lt;br /><br />

            &amp;nbsp; var bmp:BitmapData = new BitmapData(tmc._width, tmc._height, true, 0);&lt;br /><br />

            &amp;nbsp; bmp.draw(tmc);&lt;br /><br />

            &amp;nbsp; tmc.attachBitmap(bmp, 0);&lt;br /><br />

            &amp;nbsp; //Сделаем временную битмап дату, забьем в нее наш символ и визуализируем ее в том-же клипе&lt;br /><br />

            &amp;nbsp; //А теперь-то поиздеваемся над клипом!&lt;br /><br />

            &amp;nbsp; var m:Matrix = tmc.transform.matrix;&lt;br /><br />

            &amp;nbsp; //Снимем слепок текущей матрицы клипа&lt;br /><br />

            &amp;nbsp; m.c = Math.sin((j-sl/2)*Math.PI/60);&lt;br /><br />

            &amp;nbsp; //Зададим уровень искажения клипа, исходя из его места в пол-строке и направление искажения, в зависимости&lt;br /><br />

            &amp;nbsp;   //от того, в какой половине строки находится этот символ&lt;br /><br />

            &amp;nbsp; tmc.transform.matrix = m;&lt;br /><br />

            &amp;nbsp; //Исказим клип&lt;br /><br />

            &amp;nbsp;}&lt;br /><br />

            &amp;nbsp;/*Строка готова. Она содержит кучу клипов с растром, что тормозит не по детски.&lt;br /><br />

            &amp;nbsp;Ликвидируем проблему следующим образом:*/&lt;br /><br />

            &amp;nbsp;var bmp:BitmapData = new BitmapData(l_mc._width, l_mc._height, true, 0);&lt;br /><br />

            &amp;nbsp;//Создадим битмап дату для всей строки&lt;br /><br />

            &amp;nbsp;bmp.draw(l_mc);&lt;br /><br />

            &amp;nbsp;l_mc.attachBitmap(bmp, 0);&lt;br /><br />

            &amp;nbsp;// Переведем строку в растр и в ее-же клипе визуализируем&lt;br /><br />

            &amp;nbsp;for (var n in l_mc) {&lt;br /><br />

            &amp;nbsp; if (l_mc[n].removeMovieClip()) {&lt;br /><br />

            &amp;nbsp;  l_mc[n].removeMovieClip();&lt;br /><br />

            &amp;nbsp; }&lt;br /><br />

            &amp;nbsp;}// В цикле уберем клипы с символами и с ненужными, теперь, их растрами.&lt;br /><br />

            &amp;nbsp;l_mc._x = (Stage.width-l_mc._width)/2;&lt;br /><br />

            &amp;nbsp;l_mc._y = Stage.height+i*l_mc._height;&lt;br /><br />

            &amp;nbsp;//Поставим клип-строчку посреди фильма по горизонтали и спрячем ее за пределы видимости внизу&lt;br /><br />

            &amp;nbsp;l_mc.id = setInterval(animate, 800, l_mc);&lt;br /><br />

            &amp;nbsp;//Запуск анимации строки&lt;br /><br />

            }&lt;br /><br />

            }

 

Часть 3.
Собственно анимация и кой какие мелочи.
Здесь меняются лишь размеры и координаты контейнеров-строк и вполне можно было обойтись модификацией стандартных свойств клипов
т.е. "_x", "_y", "_xscale", "_yscale". Но, для пущего обучения, мы и здесь продолжим мучать матрицу трансформации.
Обратите внимание на формулы модификаторов ширины и высоты клипа. Имея небольшую разницу в написании, они абсолютно неодинаково модифицируют параметры матрицы. Попытайтесь самостоятельно в них разобраться.
В этой-же процедуре следим, если клип вышел за пределы документа, сразу подметаемся. Когда контейнеров не останется - выходим из функции и показываем кнопку повтора.

&amp;nbsp;function animate(mc) {&lt;br /><br />

            clearInterval(mc.id);&lt;br /><br />

            //Грохнем таймер&lt;br /><br />

            var m:Matrix = mc.transform.matrix;&lt;br /><br />

            //Возьмем текущую матрицу для дальнейшей ее модификации&lt;br /><br />

            m.a = Math.abs(2*(mc._y/Stage.height)-1)+.2;&lt;br /><br />

            //Масштаб по х оси&lt;br /><br />

            m.d = 2*(mc._y/Stage.height)-1;&lt;br /><br />

            //Масштаб по у оси&lt;br /><br />

            m.tx = (Stage.width-mc._width)/2;&lt;br /><br />

            //Держимся центра по горизонтали (х координата)&lt;br /><br />

            m.ty -= 1;&lt;br /><br />

            //Ползем вверх потихоньку (у координата)&lt;br /><br />

            mc.transform.matrix = m;&lt;br /><br />

            updateAfterEvent();&lt;br /><br />

            //Применяем матрицу к клипу и обновляемся&lt;br /><br />

            if (mc._y&amp;lt;0) {&lt;br /><br />

            //Клип вылез за пределы границ документа&lt;br /><br />

            &amp;nbsp;mc.removeMovieClip();&lt;br /><br />

            &amp;nbsp;//Убиваем его&lt;br /><br />

            &amp;nbsp;lineCount++;&lt;br /><br />

            &amp;nbsp;//Инкременируем счетчик (:-) засечка на прикладе винтовки)&lt;br /><br />

            &amp;nbsp;lineCount == lines.length ? endAnimate() : null;&lt;br /><br />

            &amp;nbsp;//Если число убитых контейнеров сравнялось с общим числом строк, выходим из анимации&lt;br /><br />

            } else {&lt;br /><br />

            // Клип в пределах документа&lt;br /><br />

            &amp;nbsp;mc.id = setInterval(animate, 20, mc);&lt;br /><br />

            &amp;nbsp;//по таймеру анимируем его дальше.&lt;br /><br />

            }&lt;br /><br />

            }&lt;br /><br />

            //Процедура, вызываемая по завершении анимации&lt;br /><br />

            function endAnimate() {&lt;br /><br />

            //Покажем кнопку повтора&lt;br /><br />

            r_mc._visible = true;&lt;br /><br />

            }&lt;br /><br />

            // Обработчик нажатия на кнопку&lt;br /><br />

            r_mc.onRelease = function() {&lt;br /><br />

            generate();&lt;br /><br />

            };&lt;br /><br />

            //Загрузка текста&lt;br /><br />

            titles.load('titles.txt');

 

Вот и все! Всем спасибо за внимание и творческих успехов!

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

 (голосов: 0)
Комментарии [0]   Просмотров: [+156]   Автор, admin 18 июня 2008 Напечатать


Добавление комментария
Ваше Имя:
Ваш E-Mail:

Введите цифры, которые вы видите на картинке.
Включите эту картинку для отображения кода безопасности
обновить если не виден код
Введите код:


Рубрики нашего сайта
Тут вы найдете много интересного...


Опросы на сайте


Архивы проекта


Самое интересное

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

"Движение свободных сайтов Рунета" 2007—2008. Администрация не несет ответственности за файлы размещенные пользователями.