В этом уроке вы узнаете, как разделить три цветовых канала изображения для создания эффекта смещения RGB. Я также покажу вам некоторые графические приемы, чтобы имитировать старый ЭЛТ-дисплей.
Окончательный результат предварительного просмотра
Вот пример эффекта, который мы будем создавать:
Основным выводом в этом уроке будет эффект смещения RGB, но я также покажу, как создавать линии сканирования на ЭЛТ, шум и графику с полосой прокрутки.
Шаг 1: Об изображениях RGB
Каждое изображение на экране вашего компьютера отображается с использованием красного, синего и зеленого цветов. Смешивая эти три цвета в разных количествах, ваш компьютер может создавать другие цвета в спектре.
Если три цветовых канала не выровнены должным образом, изображение не будет правильно скомпоновано, и вы начнете видеть, как края отдельных каналов «кровоточат» по сторонам изображения.
Это именно то, что мы собираемся делать в этом уроке; разделение изображения на три цветовых канала, а затем преобразование каждого по отдельности для создания эффекта искажения. Давайте доберемся до этого!
(Вы можете узнать больше о том, как работает цвет RGB в Википедии .)
Шаг 2: создайте титульный экран
Вам нужно будет создать графику, чтобы применить эффект. Я решил создать титульный экран видеоигры, но вы можете сделать любой вид графики, какой захотите.
Создайте новый мувиклип с названием «titleScreen» и поместите в него экран заголовка (или другую графику).
Я думаю, что-то с ретро-тематикой лучше всего работает с этим эффектом, поскольку напоминает мне старый неработающий аркадный экран. Я создал свой титульный экран со шрифтом Commodore 64 Pixeled . Я добавил фильтр Glow к тексту, чтобы придать ему размытый, размытый ЭЛТ-вид.
Как только вы довольны своим дизайном, добавьте к сцене MovieClip titleScreen и присвойте ему имя экземпляра titleScreen.
Шаг 3: Создайте класс RGBShift
Создайте новый файл Actionscript с именем ‘RGBShift.as’. Сохраните этот файл в том же каталоге, что и ваш основной файл Flash. Добавьте этот код для создания оболочки для класса:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package {
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.BitmapDataChannel;
import flash.display.BlendMode;
import flash.events.Event;
import flash.geom.Point;
public class RGBShift extends Sprite {
private var _centerX:Number;
private var _centerY:Number;
// CONSTRUCTOR
public function RGBShift(dObj:DisplayObject) {
}
}
}
|
Примечание редактора: пока не устраивает кодирование на основе классов? Посмотрите этот Быстрый совет, чтобы помочь вам начать.
Этот код пока ничего не делает. Первые 10 строк или около того импортируют все дополнительные классы, которые нам понадобятся. У меня есть две приватные переменные с именами _centerX и _centerY (я использую подчеркивание для обозначения приватных переменных). Эти две переменные будут содержать координаты x и y центра нашего графика.
Обратите внимание, что функция конструктора (пока пустая) принимает объект DisplayObject. Это позволит нам использовать любой тип DisplayObject с этим эффектом (MovieClip, Sprite, Bitmap и т. Д.) Мы будем использовать titleScreen MovieClip со сцены, но наличие класса, принимающего любой DisplayObject, делает его гибким для последующего использования. ,
Шаг 4: Добавьте функцию createBMD
Мы сделали наш класс гибким, позволив ему принимать любой DisplayObject, но на самом деле нам понадобится объект BitmapData для выполнения эффекта смещения RGB. Давайте создадим функцию, которая может создавать BitmapData из DisplayObject.
Добавьте эту функцию в ваш класс RGBShift чуть ниже конструктора:
приватная функция createBMD (dObj: DisplayObject): BitmapData { // создаем новый объект BitmapData размером с наш DisplayObject var bmd: BitmapData = new BitmapData (dObj.width, dObj.height, правда, 0xFF000000); // рисуем экранный объект в растровых данных bmd.draw (dObj); вернуть bmd; }
Посмотрите, что делает эта функция. Первая строка использует ширину и высоту объекта DisplayObject для создания нового прозрачного объекта BitmapData того же размера, что и объект DisplayObject. Затем он рисует объект DisplayObject в BitmapData. Наконец, он возвращает BitmapData вызывающей стороне.
Шаг 5: Добавьте функцию createRGB
Вот где происходит фактическое разделение цветов. Добавьте эту функцию в ваш класс:
приватная функция createRGB (dObj: DisplayObject): Array { var bmd: BitmapData = createBMD (dObj); // создаем bitmapData из экранного объекта // создаем новый объект растровых данных для каждого цветового канала var r: BitmapData = new BitmapData (bmd.width, bmd.height, true, 0xFF000000); var g: BitmapData = new BitmapData (bmd.width, bmd.height, true, 0xFF000000); var b: BitmapData = new BitmapData (bmd.width, bmd.height, true, 0xFF000000); // копируем данные из каждого канала в соответствующие растровые данные r.copyChannel (bmd, bmd.rect, new Point (), BitmapDataChannel.RED, BitmapDataChannel.RED); g.copyChannel (bmd, bmd.rect, new Point (), BitmapDataChannel.GREEN, BitmapDataChannel.GREEN); b.copyChannel (bmd, bmd.rect, new Point (), BitmapDataChannel.BLUE, BitmapDataChannel.BLUE); // возвращаем массив с растровыми данными для 3 цветовых каналов возврат [r, g, b]; }
Эта функция также принимает DisplayObject. Затем он передает это в функцию createBMD (), которую мы написали на предыдущем шаге, которая преобразует ее в BitmapData. Затем мы создаем три новых прозрачных объекта BitmapData; по одному на каждый цвет. Мы создаем их точно в том же размере, что и наш исходный BitmapData (из DisplayObject).
Затем мы используем метод CopyChannel () BitmapData для копирования одного цветового канала из исходного BitmapData в каждый из трех новых объектов BitmapData.
Последняя строка просто возвращает три новых объекта BitmapData, заключенных в массив.
Шаг 6: Используйте функцию createRGB в конструкторе
Теперь, когда наши классы createBMD и createRGB работают вместе, давайте их использовать. Добавьте это в качестве первой строки кода в функцию конструктора для класса RGBShift:
var rgbBMD: Array = createRGB (dObj);
Эта строка просто передает DisplayObject в функцию createRGB () . createRGB () использует функцию createBMD () для преобразования ее в BitmapData, а затем разделяет ее на три отдельных объекта BitmapData (по одному для каждого канала). Наконец, он возвращает массив этих трех объектов в наш локальный массив rgbBMD . Есть смысл? Хорошо.
Шаг 7. Создание растровых изображений из каналов RGB.
Теперь у нас есть массив из трех объектов BitmapData. Нам нужно создать растровое изображение из каждого, чтобы отобразить их на экране. Добавьте этот цикл for в функцию конструктора RGBShift чуть ниже последней добавленной нами строки:
Примечание редактора: Приносим извинения за неудобства, отображение этого конкретного фрагмента ActionScript отключает FireFox. Не стесняйтесь скачать его здесь .
Большая часть этого довольно проста. Давайте взглянем.
- С каждым объектом BitmapData в нашем массиве rgbBMD мы создаем новое растровое изображение.
- Мы устанавливаем сглаживание в true, чтобы мы могли масштабировать и вращать его без пикселизации. (строка 23)
- Затем мы создаем контейнер Sprite и добавляем новое растровое изображение в список отображения контейнера. (строки 25 и 26)
- Теперь мы наконец-то начали использовать переменные _centerX и _centerY. Мы устанавливаем каждый в центр растрового изображения путем деления ширины и высоты пополам.
- Мы используем эту центральную точку, чтобы сместить растровое изображение внутри контейнера Sprite, а затем сместить контейнер Sprite на сцене. Я объясню почему на следующем шаге.
- Наконец, мы добавляем контейнер Sprite на сцену (помните, что есть контейнер для каждого из наших трех цветовых каналов).
Шаг 8: Зачем использовать контейнер спрайт?
Вы можете создать этот эффект без контейнера Sprite, просто добавив растровые изображения прямо на сцену. Мне нравится заключать их в контейнер, потому что это облегчает контроль точки трансформации, когда вы выполняете такие вещи, как масштабирование и вращение.
Обычно, когда вы выполняете масштабирование или вращение объекта, оно трансформируется из начальной точки (0,0) этого объекта. Это редко то, что я хочу случиться. Обычно я хочу, чтобы преобразования применялись из центра объекта.
Обратите внимание, что в последнем разделе мы устанавливаем x и y растровых изображений равными отрицательной половине ширины и высоты. Это размещает растровое изображение таким образом, чтобы его центральная точка находилась на 0,0 в контейнере Sprite. Если мы выполним какие-либо преобразования в контейнере Sprite, он будет преобразован из 0,0 контейнера, который теперь является центром нашего растрового изображения.
Единственная проблема в том, что теперь виден только нижний угол нашего растрового изображения, поэтому я установил для контейнера Sprite x и y половину высоты и ширины растрового изображения, чтобы все вернулось в правильное положение.
Шаг 9: Класс смены RGBS
Вот класс RGBShift до этого момента, если вы заблудились на этом пути:
Примечание редактора: Я снова, еще раз вам придется скачать AS здесь . Приносим извинения за неудобства.
Шаг 10: Создайте основной класс документов
Итак, у нас есть класс RGBShift, но как мы его используем? Начните с создания нового файла Actionscript с именем Main.as, затем добавьте этот код:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
package {
import flash.display.MovieClip;
public class Main extends MovieClip {
public function Main() {
var rgb = new RGBShift(titleScreen);
removeChild(titleScreen);
// add it to the stage
addChild(rgb);
}
}
}
|
Здесь мы создаем новый экземпляр класса RGBShift и передаем ему titleScreen MovieClip со сцены. Нам больше не нужен этот MovieClip, поэтому мы удаляем его со сцены и вместо этого добавляем новый экземпляр RGBShift.
Теперь нам просто нужно связать этот класс с нашим документом Flash. Вернитесь во Flash и установите для класса документа значение «Основной».
Шаг 11: Тест
Теперь вы должны иметь возможность протестировать ваш Flash-файл («Управление» -> «Тестировать ролик») без каких-либо ошибок или предупреждений.
Хм, это выглядит не совсем правильно, не так ли?
Здесь происходит то, что мы наложили три цветовых канала друг на друга, но они не объединяют и не смешивают цвета, поэтому мы видим только верхний слой (синий). Давайте исправим это сейчас.
Шаг 12: измени режим смешивания
Для правильного смешивания цветовых каналов нам нужно изменить их BlendMode на SCREEN. Мы только хотим изменить режим смешивания второго и третьего слоев. Мы оставим первый (нижний) слой нормальным и смешаем в нем два других слоя.
Добавьте этот код в цикл for в функции конструктора класса RGBShift:
if (i> 0) { // устанавливаем режим наложения ЭКРАН для 2-го и 3-го изображений bmp.blendMode = BlendMode.SCREEN; }
Это проверяет, чтобы убедиться, что текущее изображение не является первым изображением (0), а затем устанавливает для свойства blendMode значение SCREEN.
Шаг 13: Тестируй снова
Протестируйте свой фильм еще раз, и вы должны увидеть что-то, похожее на ваш титульный экран.
Я знаю, что ты думаешь; «Это была большая работа по воссозданию того же графика, который уже был там».
Но теперь графика состоит из трех объектов, которые мы можем трансформировать по отдельности, чтобы создать искажение. Так что прекрати ныть и давай продолжим …
Шаг 14: Загрузите библиотеку Tweener
Мы собираемся использовать библиотеку Tweener для анимации. Загрузите его здесь, если у вас его еще нет.
Чтобы использовать Tweener, поместите главную папку ‘caurina’ в тот же каталог, что и ваш файл Flash, и добавьте этот оператор импорта в начало класса RGBShift:
импорт caurina.transitions.Tweener;
Шаг 15: Добавьте файл randRange
Я использую эту функцию randRange как простой способ генерировать случайные целые числа в заданном диапазоне. Вы можете просто добавить эту функцию в класс RGBShift, но я использую эту функцию так часто, что мне нравится хранить ее в отдельном файле, чтобы ее было легче распространять среди разных проектов.
Создайте новый файл Actionscript с именем ‘randRange.as’ в той же папке, что и ваш основной файл Flash. Добавьте этот код:
1
2
3
4
5
6
7
|
package {
// returns a random number between specified range (inclusive)
public function randRange(min:int, max:int):int {
var randomNum:int = Math.floor(Math.random() * (max — min + 1)) + min;
return randomNum;
}
}
|
Как видите, это всего лишь одна функция, заключенная в объявление пакета. Теперь мы можем использовать эту функцию, как если бы она была частью нашего класса.
(Для получения дополнительной информации о том, как работает эта функция, ознакомьтесь с Quick Tip от Carlos .)
Шаг 16: Добавьте функцию distort ()
Вот где происходит волшебство. Добавьте эту функцию в класс RGBShift:
частное искажение функции (img: Sprite): void { Tweener.addTween (img, { y: randRange (_centerY-3, _centerY + 3), // рандомизировать сдвиг y time: randRange (1,2) / 10, // рандомизировать время alpha: randRange (8,10) / 10, // рандомизировать альфа Переход: "easeInOutSine", onComplete: distort, // когда закончите, снова начните искажение onCompleteParams: [IMG] } ); }
Мы собираемся запустить эту функцию distort () для каждого из наших цветовых каналов отдельно, чтобы создать эффект искажения.
Функция принимает Sprite (один из наших контейнеров цветовых каналов). Затем он запускает анимацию Tweener на канале с использованием случайного значения Y (от -3 до 3) и случайной продолжительности времени (от 1 до 2 секунд). Это заставит каждый канал сдвигаться вверх и вниз на разную величину с разной скоростью.
Обратите внимание, что я снова использую переменную _centerY для смещения значения Y. Мы также переключаемся на случайное альфа-значение (от 0,8 до 1), чтобы каждый канал немного мерцал. Когда анимация заканчивается, мы используем свойство onComplete для повторного вызова той же функции distort () . Используя onCompleteParams мы отправляем ему тот же цвет канала Sprite. Это заставляет функцию искажения повторяться снова и снова на каждом из наших цветовых каналов.
Видишь, что я тебе сказал ..? Магия!
Чтобы запустить этот цикл искажения, нам нужно вызвать его один раз для каждого из наших цветовых каналов Sprites. Добавьте эту строку в конец цикла for в функции конструктора RGBShift:
искажать (контейнер); // начинаем растровое искажение
Шаг 17: Эксперимент
Теперь вы сможете проверить свой фильм и увидеть эффект искажения в действии.
Лично мне нравится тонкий сдвиг Y, который у нас здесь происходит, но вы можете сделать много безумных вещей с искажением теперь, когда у нас есть каналы, анимирующие отдельно.
Чтобы поэкспериментировать с искажением, вы можете просто изменить свойства и значения в вызове Tweener в функции искажения . Проверьте документацию Tweener для полного списка свойств tweenable.
Вот пример некоторых серьезных искажений, которые я создал, просто добавив еще несколько свойств к вызову Tweener:
Проверьте функцию distort (), которая создала эффект:
частное искажение функции (img: Sprite): void { Tweener.addTween (img, { y: randRange (_centerY-3, _centerY + 3), // ranomize y shift x: randRange (_centerX-10, _centerX + 10), time: randRange (1,2) / 10, // рандомизировать время scaleX: randRange (9,11) / 10, // randimize x scale alpha: randRange (5,10) / 10, // рандомизировать альфа Переход: "easeInOutSine", onComplete: distort, // когда закончите, снова начните искажение onCompleteParams: [IMG] } ); }
Шаг 18: улучшите вид ЭЛТ
Вы можете остановиться здесь, если хотите. Разделение и искажение RGB должны работать на этом этапе.
Для усиления эффекта ЭЛТ, я думаю, нам нужно добавить еще несколько графических элементов. В следующие несколько шагов мы добавим линии сканирования, вращающуюся черную полосу, немного статики и блестящее отражение.
Шаг 19: добавь строки сканирования
Создайте новый MovieClip на сцене под названием «линии». Внутри мувиклипа нарисуйте горизонтальную линию размером 1 пиксель, которая охватывает всю ширину вашего фильма. Установите цвет обводки на черный с 40% альфа.
Теперь скопируйте и вставьте эту строку снова и снова, перемещая ее на 2 пикселя каждый раз, пока у вас не появятся линии, покрывающие всю высоту вашего фильма. Эффект, который вы хотите, это 1 пиксельная строка, затем 1 пиксельный интервал перед следующей строкой.
Шаг 20: добавь Rolling Bar
Теперь мы добавим черную полосу. Создайте новый мувиклип под названием «бар». Внутри нарисуйте сплошной черный прямоугольник, который охватывает всю ширину вашего фильма. Сделайте это около 40 пикселей в высоту. Установите Цветовой стиль MovieClip на Альфа на 30%.
Шаг 21: Анимируй Rolling Bar
Создайте новый мувиклип под названием «animatingBar» и поместите клип внутри. Создайте анимацию короткой анимации движения полосы, движущейся от верхней части фильма к нижней части. Эта анимация зациклится, чтобы дать нам эффект скользящей полосы.
Поместите клип animatingBar на сцену. Выберите его и добавьте фильтр размытия. Отключите настройки размытия X и Y и установите Blur Y на 20, а Blur X на 0.
Установите режим наложения на Overlay. Это похоже на режим смешивания экрана, который мы использовали ранее, но не совсем то же самое.
Шаг 22: создайте статическое изображение
Создайте новый файл Photoshop того же размера, что и ваш фильм. Заполните фоновый слой нейтральным серым (# 808080). Выберите «Фильтр»> «Шум»> «Добавить шум» …
Установите фильтр на 100%, гауссовский, монохромный.
Сохраните изображение как «noise.jpg». Если у вас нет Photoshop, вы можете получить мой файл noise.jpg из исходного архива.
Шаг 23: Анимация статики
Импортируйте изображение noise.jpg в ваш flash-файл. Создайте новый мувиклип под названием «шум» и добавьте к нему изображение. Создайте новый ключевой кадр в кадре 2 (F6) и поверните изображение на 180 градусов. Создайте еще один ключевой кадр в кадре 3 и отразите изображение по горизонтали («Модификация»> «Трансформировать»> «Отразить по горизонтали»). Создайте четвертый ключевой кадр в кадре 4 и снова поверните изображение на 180 градусов. Теперь у нас есть 4-кадровая анимация мерцающей статики.
Вы также можете создать этот шумовой эффект с помощью ActionScript, но это выходит за рамки данного руководства.
Шаг 24: добавь отражение
Создайте новый MovieClip на сцене под названием «сияние». Внутри нарисуйте большой овал, который проходит на полпути над верхней частью вашего фильма. Выберите верхнюю часть овала и удалите его.
Измените заливку на линейный градиент и установите его так, чтобы он смешивался от белого 20% альфа вверху до белого 5% альфа внизу. Возьмите верхнюю часть фигуры и слегка потяните ее вверх, чтобы придать ей небольшой изгиб.
Шаг 25: исправь наложение элементов
Если вы протестируете свой фильм сейчас, вы не увидите никакой новой графики, которую мы только что добавили, потому что слои RGB добавляются поверх всего. Чтобы это исправить, перейдите в класс Main и измените эту строку:
AddChild (RGB);
К этому:
addChildAt (rgb, 0);
Это добавляет объект RGBShift на самый нижний уровень списка отображения , ниже всех других графиков.
Вывод
Этот урок должен быть отправной точкой, а не окончательным решением. Теперь, когда у вас есть отдельные каналы RGB и анимация, есть много разных вещей, которые вы можете сделать с помощью этой техники. Эффект выглядел бы очень хорошо, если бы он сочетался с техникой статического искажения из моего предыдущего урока .
Как всегда, оставьте комментарий и дайте мне знать, что вы думаете. Удачи!