Опубликован: 04.11.2006 | Доступ: свободный | Студентов: 4460 / 498 | Оценка: 4.46 / 3.96 | Длительность: 39:17:00
Урок 10:

Автоматизация скриптов с помощью циклов

< Урок 9 || Урок 10: 1234 || Урок 11 >

Вложенные циклы

Как вы только что убедились, применение циклов позволяет автоматизировать выполнение повторяющихся задач. Однако это еще не все. Представьте себе, что можно сделать при помощи вложенного цикла – то есть цикла, помещенного в другой цикл. Набор действий выполняется несколько раз, затем эта последовательность повторяется, но уже с небольшими изменениями, затем еще раз… Вот пример вложенного цикла:

var i = 0;
while (++i <= 10) {
  var j = 0;
  while (++j <= 10) {
    // выполняемые действия
  }
}

Набор действий в этом скрипте будет выполнен 100 раз. Смысл тут таков: внешний цикл (использующий в условии переменную i) выполняется 10 раз. При этом на каждой итерации переменная j (используемая в условии внутреннего цикла) сбрасывается на 0, и внутренний цикл выполняется 10 раз. Иными словами, на первой итерации внешнего цикла внутренний цикл выполняется 10 раз, на второй итерации – еще 10 раз, и так далее.

Вот вам пример вложенных циклов из жизни. Представьте себе, что вы набираете в текстовом редакторе какой-то текст. Этот процесс представляет собой не что иное, как вложенный цикл: вы начинаете с первой строки, вводите 100 символов, переходите на вторую строку, вводите еще 100 символов, и так далее. Если текст состоит, к примеру, из 25 строк, то эту работу можно представить в виде такого скрипта:

var i = 0;
while (++i <= 25) {
  var j = 0;
  while (++j <= 100) {
    // ввод одного символа
  }
  // переход на следующую строку
}

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

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

  1. Откройте файл pictureShow2.fla из папки Lesson10/Assets.

Над сценой расположены три экземпляра фильмов-символов: picture1, picture2 и picture3. В этом упражнении мы создадим скрипт, дублирующий один из этих экземпляров (какой именно – будет зависеть от выбранного пользователем элемента нашего меню).

  1. Откройте панель Действия, выделите экземпляр клипа dropDownList и добавьте в обработчик события load следующую функцию:
function itemClicked(pictureID) {
  picToDuplicate = "pictures" + pictureID;
  xSpacing = 160;
  ySpacing = 120;
  xStart = 190;
  yStart = 30;
}

Вскоре мы запрограммируем кнопки в нашем списке (который мы создали в предыдущем упражнении), чтобы при нажатии они вызывали эту функцию и передавали ей значение параметра – pictureID. Функция будет создавать четыре копии одного из трех клипов, расположенных над сценой, формируя на сцене "сетку" две на две картинки. При этом каждый экземпляр будет показывать свою картинку (один из кадров своего монтажного стола).


Итак, первая строка в нашей новой функции создает переменную с именем picToDuplicate. Эта переменная будет, в зависимости от значения переданного функции параметра pictureID (1, 2 или 3), получать значение picture1, picture2 или picture3 – что соответствует именам экземпляров с картинками.

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

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

  1. Добавьте в описание функции itemClicked() следующие строки:
v = 0;
i = -1;
while (++i < 2) {
  j = -1;
  while (++j < 2) {
    ++v;
    name = "picture" + v;
    _root[picToDuplicate].duplicateMovieClip(name, v);
    _root[name]._x = xStart + i * xSpacing;
    _root[name]._y = yStart + j * ySpacing;
    _root[name].gotoAndStop(v);
  }
}

Как видите, здесь мы имеем вложенный цикл. Эта часть функции как раз создает дубликаты и располагает их по строкам и столбцам. Если бы мы использовали одиночный цикл, то получился бы всего один столбец из картинок. А вложенный цикл создает столбец из двух экземпляров, "смещает" координаты столбца и создает второй столбец из двух экземпляров. Поясним, как это получается.

Внешний цикл (начинающийся с третьей строки) увеличивает на значение i единицу ( ++i ) – получается 0. Условие внешнего цикла гласит, что пока i меньше 2, действия в теле цикла должны выполняться. Так как 0 меньше 2, начинается выполнение. Первое действие присваивает переменной j значение -1. Сразу после этого начинается внутренний цикл, в условии которого используется переменная j. После инкремента ( ++j ) и проверки условия ( j должно быть меньше 2) начинается выполнение тела этого цикла. Первая итерация: значение v увеличивается на единицу ( ++v ) – получается 1. Значение этой переменной несколько раз используется в следующих строках. По уже знакомой вам "технологии" нужный экземпляр клипа с картинками дублируется и размещается на сцене. Начинается вторая итерация внутреннего цикла. Значение j увеличивается еще на единицу, получается 1 – это попрежнему меньше 2, поэтому тело цикла выполняется вновь. Третьей итерации не будет, поскольку после инкремента j станет равно 2, и условие даст результат false. Управление опять переходит к внешнему циклу. В результате инкремента i получает значение 1; это меньше, чем 2, и внешний цикл выполняется опять. Значение j вновь сбрасывается на -1, в результате снова выполняются две итерации внутреннего цикла. Если вам что-то осталось непонятным, рассмотрите внимательно эту схему.


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

_root[name]._x = xStart + i * xSpacing;
_root[name]._y = yStart + j * ySpacing;

В первой строке используется значение i для вычисления отступа по горизонтали, во второй строке – значение j, для вычисления отступа по вертикали. Как вы уже знаете, на каждой итерации внешнего цикла внутренний цикл выполняет две итерации. Таким образом, когда i имеет значение 0, j последовательно принимает значения 0 и 1; затем i увеличивается до 1, и j вновь получает значения 0 и 1. Зная значения xStart, xSpacing, yStart и ySpacing, а также значения i и j, мы можем определить, как устанавливаются отступы для каждого клипа:

Первое дублирование экземпляра

_x = 190 + 0 * 160; // x равен 190
_y = 30 + 0 * 120;  // y равен 30

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

Второе дублирование экземпляра

_x = 190 + 0 * 160; // x равен 190
_y = 30 + 1 * 120;  // y равен 150

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

_x = 190 + 1 * 160; // x равен 350
_y = 30 + 0 * 120;  // y равен 30

Четвертое дублирование экземпляра

_x = 190 + 1 * 160; // x равен 350
_y = 30 + 1 * 120; // y равен 150

  1. Добавьте в описание функции itemClicked() последнее действие:

removeButtons();

Это действие будет вызывать функцию removeButtons() (мы как раз собираемся ее создать). Эта функция будет убирать с экрана элементы раскрывающегося списка после того, как пользователь щелкнет на одном из них (и будет показан соответствующий набор картинок).

  1. В конец обработчика события load поместите описание функции removeButtons():
function RemoveButtons() {
  var i = -1;
  while (++i < numberOfButtons) {
    name = "item" + i;
    this[name].removeMovieClip();
  }
}

В этой функции использован простой цикл while, перебирающий все элементы списка под кнопкой Menu ( item0, item1 и item2 ). Цикл с виду похож на тот, который создает дубликаты, составляющие список. Проанализируем синтаксис.

Переменная numberOfButtons (использованная в третьей строке этого скрипта) была создана, как вы помните, функцией populateList(). Ее значение равно длине (свойству length ) массива info. Поскольку в этом массиве у нас три элемента, данный цикл будет выполнен трижды. На каждой итерации переменная name получает значение, зависящее от значения i. Метод removeMovieClip(), используя в качестве адреса текущее значение name, удаляет список под кнопкой Menu.

  1. Двойным щелчком на экземпляре фильма-символа dropDownList откройте его для редактирования на месте. Также двойным щелчком откройте для редактирования на месте экземпляр клипа item. Выделите белую кнопку и введите в панели Действия следующий скрипт:
on (release) {
  _parent.itemClicked(pictureID);
}

Итак, при нажатии кнопки Menu раскрывается список – путем дублирования экземпляра фильма-символа item. Этот скрипт мы присоединили к кнопке, находящейся внутри экземпляра клипа item, и значит, этот скрипт – один и тот же – будет включен во все дубликаты. Однако в процессе дублирования (выполняемого функцией populateList(), созданной нами в предыдущем упражнении) внутри каждого дубликата создается своя переменная с именем pictureID – и в каждом дубликате она имеет свое значение: 1, 2 или 3, в зависимости от значения переменной цикла i в функции populateList(). Таким образом, при нажатии кнопки любого из дубликатов, вызывается функция itemClicked() (описанная в экземпляре клипа dropDownList ) и ей передается значение переменной pictureID этого дубликата. В результате на сцене отображаются четыре картинки (см. иллюстрацию к шагу 2 этого упражнения).

  1. Командой Управление > Проверить фильм (Control > Test Movie) запустите тест проекта.

Нажав кнопку Menu, раскройте список. Если вы щелкнете на одном из элементов списка, на сцене появятся четыре картинки – тот или иной набор, в зависимости от значения pictureID, переданного функции itemClicked(). Сразу после этого список исчезнет с экрана, будучи удален функцией removeButtons().

  1. Закройте тестовый фильм и сохраните свою работу как pictureShow3.fla.

В этом упражнении мы, с помощью вложенного цикла, отобразили на экране картинки в виде "таблицы". Таким образом, вместо того, чтобы вручную перетаскивать на сцену экземпляры и размещать их, мы автоматизировали процесс. К тому же в нашем проекте можно отобразить "таблицу картинок хоть 100 на 100 – для этого понадобится внести в скрипт лишь пару мелких изменений. Вы убедились, что применение циклов помогает сильно упростить работу над многими проектами, притом дает возможность динамически обновлять выводимую информацию и расширять ее объем прямо в ходе воспроизведения проекта.

< Урок 9 || Урок 10: 1234 || Урок 11 >
Евгений Стародубцев
Евгений Стародубцев

Вот задание:

7. Открыв панель Действия (Actions) и установив ее в Экспертный режим(Expert Mode), выделите кадр 1 слоя Actions и введите следующий скрипт:

Галина Кузнецова
Галина Кузнецова

Добрый день.

Можно ли получить среду Flash для обучения бесплатно?

Болат Байгалиев
Болат Байгалиев
Казахстан, КазНИТУ, 2016