Вернемся к настоящему
В чем сложность создания приложения? Сложность возникает, если не разделять ее на отдельные части. Мы инкапсулируем сложность в отдельных классах используя ООП. Мы легко боремся со сложностью в статической системе. Но система практически никогда не находится в статическом состоянии. Для динамических систем мы используем паттерны проектирования, для того чтобы эту сложность обуздать.
Конвейер, по сути, есть паттерн проектирования – Flash-паттерн. Он помогает бороться со сложностью, упрощая понимание поведения приложения.
Однако этот механизм настолько универсален, что напрашивается другое, более широкое определение.
Конвейер – есть некий язык описания. Он реализует стратегию описания действий во времени. Мы как бы получаем возможность писать некий листинг кода во времени. Сначала это, далее это, а вот сейчас вот это.
Конкретный пример
Представим себе, что мы делаем реальное Flash приложение – рулетку.
Как статическая система приложение уже готово. Каждое конкретное действие реализовано в отдельных компонентах. Игрок должен нажать на кнопку «начать игру» и мы должны вывести игровой результат.
Как выводить игровой результат? Игровой результат не может возникнуть в один момент. Нам нужно показывать игровой процесс шаг за шагом.
Опишем эти шаги:
- Заблокировать интерфейс игрового приложения.
- Создать случайный результат. Произвести расчет результатов для ставок. Создать таблицу выигравших и проигравших ставок. Вычислить величину выигрыша–проигрыша для каждой ставки.
- Запустить анимацию колеса.
- После остановки колеса: вывести выпавшее число на дисплей и в виде гирьки на столе рулетки.
- Озвучить игровой результат: объявить голосом дилера номера, цвет и четность выпавшей цифры.
- Убрать все проигравшие ставки: создать анимацию движения стопок проигравших фишек в сторону дилера.
- С каждой выигравшей ставкой произвести анимационные действия:
- увеличение ставки,
- движения в сторону игрока,
- увеличения баланса игрока (на значение ставки плюс выигрыш)
- Разблокировать интерфейс игры.
Как мы видим, все действия выполняются последовательно. И обязательно должны выполнятся последовательно! Когда заканчивается предыдущее действие, должно выполнятся следующее. Только так, ничего не должно пресекаться и начинаться раньше, чем предыдущее действие будет выполнено.
Вот тут и начинается самое сложное. Как показывает практика, большая часть ошибок, сбоев, «глюков» приложения возникает при реализации последовательного вывода во времени.
Вот здесь и приходит на помощь конвейер.
Пишем код метода начала игры:
private function spin()
{
// заблокировать
// пользовательский интерфейс
this.lock();
// вычислить игровой результат
this.createGameResult();
// начать движение колеса
// (время 100 кадров)
Conv.put(this, "startWeel", "100");
// остановить колесо
Conv.put(this, "stopWeel", 0);
// озвучить игровой результат
// (время - две секунды)
Conv.put(this, "gameSounds", 2000);
// анимационно убрать проигравшие
// ставки (на каждую ставку по 50 кадров)
Conv.put(this, "looses",
String(this.looses_array.length*50));
// анимационно показать
// выигрыш всех выигравших
//(если такие имеются)
// на каждую ставку по 100 кадров
Conv.put(this, "wins",
String(this.wins_array.length*100));
// разблокировать интерфейс
//игрового приложения
Conv.put(this, "unlock", 0)
} |
Метод lock блокирует пользовательский интерфейс. Метод createGameResult вычисляет игровой результат. Происходит вычисление суммы выигрыша, и создаются массивы проигравших и выигравших ставок. Анимируется выигрыш пошагово и в финале разблокируется интерфейс.
Здесь мы впервые встречаем имя Conv и метод put . Conv – имя класса реализующего механизм конвейера (сокращенно от Conveyor). Метод put помещает команду в конвейер.
Conv.put
Как же описать действия?
Чтобы выполнить действие нам нужно вызывать функцию. Если функция является методом объектом, то нужно указать объект и имя метода.
Нам нужно указать задержку. Или в миллисекундах или во фреймах.
Если функция должна получить аргументы, в описание действия нужно добавить значения аргументов.
Примерно так:
Conv.put(trace, 1000, "Hello!");
Conv.put(trace, 0, "World!"); |
В output последовательно выведется сначала слово “Hello !”, а через одну секунду будет выведено слово “World !”.
В данном примере мы задаем задержку в миллисекундах, а что если мы захотим задать задержку во фреймах timeline ?
Тогда будем вводить задержку в виде строки. Если нужна задержка 10 кадров – то пишем «10», если в один фрейм - то «1».
Например, мы хотим перемещать некий мувиклип по одному пикселю вверх-влево в каждый кадр и так десять раз?
for (var i=1;i<=10;i++)
{
Conv.put(any_mc, "moveBy", "1", -1, -1);
} |
Как видно из примера, все компактно и просто. Но нам не нужно каждый раз писать метод для таких простых действий, как перемещения.
А что если нам реализовать и работу с полями (properties)?
for (var i=1;i<=10;i++)
{
Conv.put(any_mc, "_x", 0, any_mc._x+i);
Conv.put(any_mc, "_y", any_mc._y+i);
} |
Опишем метод put конвейера в виде краткой спецификации:
| Conv.put |
Conv.put( function, timeout[, argument1, … argumentN] )
Conv.put( function, scope, timeout[, argument1, … argumentN] )
Conv.put( object, methodName, timeout[, argument1, … argumentN] )
Conv.put( object, paramName, timeout, value )
function – ссылка на функцию, которую необходимо выполнить.
object – путь к объекту. Он может задаваться в виде ссылки и (если объект еще не существует в момент добавления действия) – в виде строки, например, “_root.any_object”.
methodName – строка, имя вызываемого метода объекта
timeout – строка или номер, задержка после выполнения. Строка – задержка во фреймах. Номер – в миллисекундах.
scope – ссылка на объект, то что при выполнении функции будет текущим пространством имен (this).
arguments – аргументы метода или функции
paramName – имя параметра объекта
value – значение параметра
Ничего
Метод добавляет в конвейер действие. Действие состоит из объекта, действия над ним, параметров и задержки. Есть три варианта добавления действия:
В виде функции:
Conv.put(function, timeout[, argument1, … argumentN ])
Conv.put(function, scope, timeout[, argument1, … argumentN])
В виде метода объекта:
Conv.put(object, methodName, timeout[, argument1, … argumentN])
В виде изменения параметра объекта:
Conv.put (object, paramName, timeout, value)
Если действие это – выполнение функции, то указывается ссылка на функцию. В данном варианте можно указать дополнительный параметр – пространство имен ( scope ), чтобы функция выполнялась как «временный метод» объекта. И this в коде этой функции – будет относиться к этому объекту.
Если действие – это выполнение метода объекта, то указывается ссылка на объект и имя его метода в виде строки. Если объект еще не создан, и ссылку на него указать нельзя, то ссылку можно указать в виде строки.
Если действие – это изменение параметра объекта – то указывается ссылка на объект, имя его параметра в виде строки и значение которое нужно присвоить параметру. Если объект еще не создан, то ссылку на объект можно указать в виде строки.
Функция и параметры:
Conv.put(function(str) { trace(str); }, 1000, "Hello, World!"); |
Функция с указанием пространства имен (scope):
Conv.put(function(str) { trace(this._name); }, any_mc, 1000); |
Объект, метод и параметры:
_root.any_object = {};
_root.any_object.method = function(str)
{
trace(str);
}
Conv.put(_root.any_object, "method",
"12", "Hello, World!");
|
Путь к объекту в виде строки и его метод:
Conv.put("_root.any_object", "method",
"12", "Hello, World!");
_root.any_object = {};
_root.any_object.method = function(str)
{
trace(str);
} |
Изменение параметра объекта
Conv.put("_root.textField_txt", "text",
"12", "Hello, World!"); |
|
Предыдущая часть | Следующая часть
[1] [2] [3] [4] [5] [6] [7]
|