Взаимодействие машин: «Лампочка» и «Светофор»

Материал из wiki.appsalutecreator.com
Версия от 07:50, 12 января 2013; Steps (обсуждение | вклад) (Промежуточные состояния)
Перейти к: навигация, поиск
Урок 3 << Оглавление >> Урок 5

Цель: изучить взаимодействие машин состояний.

Задачи:

  • создать тумблер, включающий лампочку
  • создать уличный светофор
  • включать и выключать светофор при помощи кнопки.


Лампочка и выключатель

Создание машин

Создайте в учебном проекте новый экран lesson_4 и сцену stg_mian. Перетащите на сцену из редактора ресурсов переключатель и лампочку:

Lesson4 switch lamp.png


Поменяйте обоим объектам тип, сделав их машинами состояний. Переименуйте (поле свойств "имя") выключатель в switch, а лампочку в lamp.

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

Lesson 4 state1.png


Верхние красные кружочки относятся к переключателю. Он может находиться в двух состояниях on и off. Лампочка (синие кружочки), также имеет два состояния, которые мы назовем dark и light.

Cоздайте эти состояния в машинах так, как это было описано в предыдущем уроке. Добавьте в каждое состояние команду draw с параметром res, в которые перетащите картинки из редактора ресурсов. Затем в переключателе добавьте команду click с параметром go. Сделайте из него "чекбокс":

Lesson 4 switch state1 new.png

В лампочке создайте пока только по команде рисования draw:

Lesson 4 lamp state1.png

Протестируйте получившийся результат. Переключатель должен переключаться, тогда как лампочка ни как на это не реагирует.

Подключаем провода

Теперь самое время подключить к лампочке и выключателю провода. Этими проводами будет служить команда set. Вспомним теорию. При входе в состояние происходит выполнение команд инициализации, которые сразу выполняются, как только машина поменяла своё состояние. К таким командам и относится команда set. С её помощью происходит изменение состояния других машин. Добавим в каждое из состояний переключателя по команде set с параметрами obj и st. Для параметра obj из выпадалки выберем объект lamp. В параметре st зададим руками требуемые состояния лампочки. В результате должно получиться:

Lesson 4 switch state2.png


Снова протестируйте работу машин. Стоит во вьювере нажать S, чтобы понаблюдать за происходящими изменениями состояний объектов.

Активная лампочка

Давайте усложним поведение лампочки. Пусть она, независимо от переключателя, может включаться, если на неё кликнули в состоянии dark. Перейдя в горящее состояние light она горит 2 секунды, а затем сама выключается, возвращаясь в dark:

Lesson 4 states2.png

Не подглядывая на следующую картинку, запрограммируйте такое поведение лампочки. У Вас, конечно, должен был получиться следующий результат:

Lesson 4 lamp2.png

Условия переходов

Потребуем теперь, чтобы лампочка, при клике на неё, могла включаться только, если в этот момент включен переключатель. Таким образом, необходимо заблокировать команду click если переключатель находится в состоянии off. Делается это при помощи команды if, которую необходимо добавить в состояние dark лампочки:

Lesson 4 lamp3.png

Обратим внимание, что кроме команды if, было добавлено одноименное поле в команде click с параметром 0. Разберемся, как работают эти команды. В состоянии может быть несколько команд-условий if. Все они нумеруются начиная с нуля. Т.е. первая сверху в списке команда if имеет номер 0, следующая 1 и т.д. Однако сами по себе условия ещё ничего не делают. Запуск их на проверку выполнимости осуществляют другие команды. В нашем случае это делает команда click. В её поле if стоит ноль. Это означает, что при клике на лампочку переход go произойдет только, если выполняется условие под номером 0. В этом условии происходит проверка того, находится ли объект obj в состоянии st. Если находится, то условие срабатывает и клик приводит к требуемой смене состояния. Все просто :).

Протестируйте получившийся результат. Сначала на выключенном переключателе кликните на лампочку. Она не загорится. Теперь, включите переключатель. Лампа загорится и после 2-х секунд погаснет. Теперь, если кликнуть на лампочку, она снова загорится, так как переключатель находится в состоянии on. Стоит, как обычно, в процессе этих экспериментов понаблюдать за отладочной информацией.

Начальное состояние

Lesson 4 prop.png

Каждая машина в момент начала работы находится в определённом состоянии. По умолчанию, это первое состояние в линейке состояний, в соответствующем окне редактирования. Однако его можно изменить. Сделаем так, чтобы в начальный момент времени переключатель был включен, а не выключен. Для этого необходимо в его свойствах (панель Properties) в поле состояние задать имя начального состояние on.

Запустим вьювер. Обратим внимание, что лампочка сразу загорелась. Так и должно быть, так как машина переключателя начала работать из состояния on, а, следовательно, запустила команаду set, меняющую состояние лампочки.

Подробнее о командах

Подытожим информацию о командах, работающих в состояниях внутри машин. Существует четыре типа команд:

  • инициализаций (draw, set) - выполняется сразу как только машина оказалась в данном состоянии. Это "мгновенные" команды, т.к. их действие не растянуто во времени;
  • воздействий (click) - выполняются, если на машину было оказано внешнее воздействие, например, в неё кликнули мышкой;
  • процессов (wait) - эти команды начинают выполняться, когда произошел переход в данное состояние. В отличии от команд инициализации их действие растянуто во времени. К этому типу команд относится также команда move, которая встречалась в машинах первого урока;
  • условий (if) - описание различных логических условий, которые могут использовать другие команды данного состояния.

К настоящему моменту нам уже известны следующие команды:

  • draw — управление внешним видом машины, определение её графического ресурса. Эта команда, как и set является командой инициализации, т.е. выполняется в момент попадания машины в данное состояние. Если в состоянии машины такой команды нет, то автоматически устанавливается графический ресурс, указанный в свойствах данной машины (поле res);
  • set – установка состояния другого объекта (команда инициализации);
  • click – что делать при клике на объект (команда воздействия). В нашем случае - переход в другое состояние той же машины;
  • wait – временная пауза, после которой происходит переход в другое состояние (время исчисляется в миллисекундах, где 1 сек = 1000 миллисекунд). Это команда процессов, т.е. её выполнение длится во времени;
  • if – логическое условие перехода (команда перехода).

Светофор

Lesson 4 lights1.png

Рассмотрим теперь обычный уличный светофор. Вспомним как он работает:

  • сначала обычно (к сожалению) горит красная лампа, остальные выключены;
  • затем при горящей красной лампе загорается ещё и желтая;
  • затем желтая и красная лампы гаснут и загорается зеленая;
  • в конце горения зеленой лампы она три раза мигает и выключается;
  • затем включается красный, чтобы повторить весь процесс с самого начала.

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

Lessons 4 tree.png

Разместим на сцене подложку для светофора. Она останется статической картинкой. Затем поместим поверх неё три лампы разного цвета и сделаем их подобъектами подложки. Обложку назовем lights, а лампы light_R, light_Y, light_G. Изменяя тип у лам превратим их в машины.

Простой светофор

Сначала проигнорируем одновременное горение и мигание, сделав просто последовательное переключений ламп. Такой "простой светофор" можно попробовать реализовать тремя машинами, имеющих по два состояния в каждой из них:

Lesson 4 R1.png

Lesson 4 Y1.png

Lesson 4 G1.png


Хотя "простой светофор" будет работать вполне корректно, приведенные выше машины не очень хороши. Все лампы находятся в своем стартовом состоянии off. В них есть команда инициализации set, которая устанавливает состояние горения следующей лампы. Что должно произойти в начальный момент запуска проекта? Машины работают также как и рисуются - сверху вниз по дереву проекта. Сначала инициализируется красная лампа. Это её первое попадание в состояние off, поэтому она пытается включить желтую лампу. Однако этого не происходит, так как желтая лампа еще "не существует". Когда до неё доходит очередь, она создается и пытается включить зеленую лампу которой также "ещё нет", поэтому этого тоже не происходит. И только когда доходит дело до создания зеленой лампы, она включает (уже существующую и находящуюся в состоянии off) красную лампу.

С этого момента всё начинает работать вполне логично. При входе в состояние on выключается предыдущая лампа, а при входе в состояние off включается следующая.

Почему же "простой светофор" плох, если он верно работает? Потому, что держать в голове детали последовательного создания машин состояний не стоит, т.к. это усложняет логику понимания их функционирования.

Промежуточные состояния

Исправить ситуацию можно, добавив в каждую лампу промежуточное состояние next, в котором собственно происходит управление переключением следующей лампы. Приведем пример такой машины для красной лампы, а остальные сделайте по её образу и подобию:

Lesson 4 R2.png

Как мы видим, в добавленное состояние next переехала команда set, которая раньше была в состоянии off. Зададим в свойствах (Properties) стартовое состояние красной лампы в on, а остальным в off.

В выключенных состояниях ничего не происходит кроме рисования серой картинки для выключенной лампы. Поэтому ни каких попыток изменить состояния других ламп у light_Y и light_G не будет. Красная лампа light_R начнет работать из состояния on. Прогорев 1 сек, она перейдет в состояние next, в котором переустановит состояние следующей лампы. В состоянии next красная лампа и останется (рисуя серую картинку), пока её не включит на очередном цикле зеленая лама.

Управляющая машина

ДАЛЬШЕ НЕ УСПЕЛ, ДОПИСЫВАЙТЕ... Там фигня какая-то, а не светофор


§1. Создание экрана и сцены в игровом проекте

1. Запустить SceneEditor.

2. В меню Проект → Загрузить → Learning.seproj.

3. Кликнув правой кнопкой мыши по ранее созданному экрану Lesson_05.1, создать экран Lesson_06.

06 1.png

4. В экране Lesson_06 создать новую сцену 06, в которую (через ResourcesEditor) добавить графические ресурсы из папки Sources\Lesson_06 (см. подготовка к работе «Создание проекта»).

06 2.png 06 3.png

§2. Создание машин состояний

1. Графические ресурсы перевести в машины. Для этого нужно, прокликивая по всем объектам, в свойстве элемента изменить тип изображения на тип maсhine.

2. Объект (машину) light_D переименовать в название knopka.

3. Объекты light_R, light_Y, light_G подчинить объекту light.

06 4.png

4. Для всех объектов (машин) в сцене прописать такие состояния:

светофор

06 5.png

красный свет

06 6.png

желтый свет

06 7.png

зеленый свет

06 8.png

кнопка

06 9.png

5. В общих свойствах элемента для объектов (красный свет, желтый свет, зеленый свет и кнопка) в параметре состояние установить первоначально состояние off.

06 10.png

6. Проверить выполнение задачи с помощью проигрывателя сцен Viewer.

§3. Задание к уроку

1. Щелкнув правой кнопкой мыши по экрану Lesson_06, создать новый экран Lesson_06.1

2. Создать новую сцену (с названием 06.1).

3. Скопировать все объекты из сцены 06 (экрана Lesson_06).

4. Вставить скопированые объекты в новую сцену 06.1.

5. В новой сцене необходмо прописать состояния и команды в измененную задачу:

a) добавьте дополнительно два графических ресурса для объектов up (взять ресурс light_D, в общих настройках элемента → модификатор → alpha=0,01) и down (взять ресурс light_D, в общих настройках элемента → модификатор → alpha=0,01).

06 11.png 06 12.png

b) в самой сцене расположите: поверх на красный свет объект up, поверх на зеленый свет объект down.

Сделайте так, чтобы:

c) независимо от того, какой горит свет светофора, при нажатии на красный свет загорался красный;

d) независимо от того, какой горит свет светофора, при нажатии на зеленый свет загорался зеленый.

Упражнения

§3. Задание к уроку

1. Щелкнув правой кнопкой мыши по экрану Lesson_04, создать новый экран Lesson_04.1.

2. Создать новую сцену (с названием 04.1).

3. Скопировать все объекты из сцены 04 (экрана Lesson_04).

4. Вставить скопированые объекты в новую сцену 04.1.

04 15.png

5. В новой сцене постарайтесь сами прописать состояния и команды в измененную задачу. Сделайте так, чтобы:

a) изначально лампочка не горела, а тумблер был в выключенном состоянии;

b) длительность горения лампочки составляла 500 миллисекунд.



Урок 3 << Оглавление >> Урок 5