Machine — различия между версиями

Материал из wiki.appsalutecreator.com
Перейти к: навигация, поиск
м (Условия if)
м (play)
Строка 374: Строка 374:
 
=== play ===
 
=== play ===
  
play - проиграть звук
+
Проиграть звук.
  
*'''snd''' - Короткий звук (перетаскивается из редактора ресурсов)
+
*'''snd''' - короткий звук (перетаскивается из редактора ресурсов)
 
+
*'''voice''' - голос (запускается как звук, но без цикла и с громкостью голоса) (перетаскивается из редактора ресурсов)
*'''voice''' - Голос (запускается как звук, но без цикла и с громкостью голоса) (перетаскивается из редактора ресурсов)
+
*'''mus''' - длинный звук (перетаскивается из редактора ресурсов)
 
+
*'''preload''' - указанный звук будет загружен в память, но не будет проигрываться прямо сейчас. Для ускорения его старта потом
*'''mus''' - Длинный звук (перетаскивается из редактора ресурсов)
+
*'''loop''' - зациклить звук (звуки)
 
+
*'''mus_stop''' - остановить текущую музыку
*'''preload''' - Указанный звук будет загружен в память, но не будет проигрываться прямо сейчас. Для ускорения его старта потом
+
*'''volume''' - установить громкость для всех звуком данной машины - тех что уже играют и тех, что будут запущены впоследствии
 
+
*'''if''' - номер (начиная с нуля) условия перехода (команды if)
*'''loop''' - Зациклить звук (звуки)
 
 
 
*'''mus_stop''' - Остановить текущую музыку
 
 
 
*'''volume''' - Установить громкость для всех звуком данной машины - тех что уже играют и тех, что будут запущены впоследствии
 
 
 
*'''if''' - Номер (начиная с нуля) условия перехода (команды if)
 
  
 
=== var ===
 
=== var ===

Версия 17:31, 23 января 2013

Машина состояний (state machine) позволяет описывать сложное поведение игровых объектов. Для машин с типовым набором состояний и поведений вводятся отдельные типы объектов. Например, кнопка, по своей сути, является машиной состояний.

Введение

Логика поведения машины разбивается на отдельные узлы (состояния). Машина всегда находится строго в одном состоянии. Переход из одного состояния в другое происходит либо в результате внешнего воздействия на машину, либо в результате окончания некоторых процессов протекающих внутри неё

Любая машина состояний может быть изображена в виде графа с кружочками и стрелками. У машины всегда активно строго одно состояние (ниже это изображено на левом рисунке темным кружком):

Def states.png

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

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

Все команды состояния, разбиваются на три группы:

  • Инициализации:
    • draw - установка графического ресурса
    • init - инициализация параметров машины (координаты и т.п.)
    • set - установка состояния другого объекта
    • buy - запуск процедуры in-app покупки
  • Процессов:
    • wait - задержка по времени
    • move - движение
    • alpha - изменение прозрачности
    • scale - изменение размера
    • rot - вращение вокруг точки пивота
    • phys - движение в силовом поле.
  • Воздействия:
    • click - что делать при клике на машине
    • drop - на машине отпущена клавиша мыши
    • drag - машину схватили и тащат
    • throw - машину схватили и кинули
    • apply - сработает при пересечении машины с линией или объектом

Кроме этого, есть команда if, вызываемая другими командами. В ней описываются некоторые логические условия, выполнение которых говорит команде (которая вызвала этот if), что можно завершать работу.

Начальные понятия и методы работы с машинами состояний находятся в уроках, начиная с третьего.

Свойства

Общие для всех объектов свойства описаны в документе Object. Дополнительные свойства:

  • Состояние - Состояние в котором будет находиться машина при инициализации. Если ничего не указано - первое состояние в списке состояний.
  • Хранить нажатость - нужно ли сбрасывать нажатость при изменении состояния.
  • res - графический ресурс машины. Может отсутствовать. Перетягивается из редактора ресурсов(поле должно быть в состоянии редактирования).
  • states - По двойному клику, или по нажатию на кнопку с тремя точками открывается список состояний.
  • прокликиваемая - 0 - машина не пропускает клик, 1 - машина пропускает клик, 2 - машина обрабатывает клик и пропускает его дальше.

Команды инициализации

При первом попадании в состояние, сразу выполняются команды инициализации init, draw и set. Если в этих командах нет параметра break, они все выполняются до запуска процессов.

draw

Команда определяет графический ресурс (картинку, которую надо рисовать в данном состоянии). Её параметры:

  • res - ресурс картинки (перетаскивается из редактора ресурсов)
  • f - начальный кадр
  • ft - длительность кадра в миллисекундах
  • loop - число повторов (зацикливаний анимации); если -1, то бесконечно; отсутствует или 0 - будет проигран одина раз
  • go - перейти в состояние
  • if - условие перехода
  • break - прервать команды

Пустая команда draw (без параметров) "сбрасывает" текущую картинку и в этом состоянии ничего рисоваться не будет. Если в общих параметрах объекта (в базовой панеле свойств) задан ресурс рисования, и он во всех состояниях одинаков, то его можно в состоянии не задавать.

Если параметра loop нет, кадры анимации проиграются один раз. Чтобы зациклить их, необходимо установить loop=-1 или нужное число раз. Аналогично параметру loop других команд, первый раз draw выполняется в любом случае. Дальнейшие её повторы определяются значением loop. Однако, в отличие от других команд, loop повторяет только данную команду draw (даже если она не первая).

Для работы loop необходимо чтобы в редакторе ресурсов в настройках анимации было отключено зацикливание(looped).

init

Инициализация параметров данной машины

  • x,y - координата точки пивота относительно сцены или родительского объекта;
  • sx,sy - масштаб машины по осям (если 1, то это исходный размер; 0.5 - в два раза меньше);
  • ang - угол поворота в градусах; отчитывается вниз от оси x, или вверх, если отрицательный;
  • v - скорость для команды move
  • vr - угловая скорость для команды rot
  • vx,vy - начальная скорость для команды phys
  • ax,ay - ускорение для команды phys
  • z координата - координата машины по z.
  • z приращение - приращение координаты машины по z относительно текущего
  • vis - видимость - видимость машины (1 - видима, 0 - невидима)
  • показать рейтинг - значение 1 означает, что при выполнении этого инита будет показано окно iOS рейтинга
  • закрыть приложение - значение 1 означает, что при выполнении этого инита приложение будет закрыто
  • перезагрузить лэйаут - значение 1 означает, что при выполнении этого инита будет перезагружен лэйаут
  • вернуться назад - начение 1 означает, что при выполнении этого инита произойдет возврат на предыдущий экран
  • реклама AdMob - 1 - показать, 0 - спрятать, -1 - не изменять состояние
  • прокликиваемая - если 1, то картинка прозрачна для клика мышкой (пропускает объектам под ней). Если 2, то клик обрабатывается, но передается дальше
  • курсор - меняет текущий курсор мыши на указанный графический ресурс. Перетягивается из редактора ресурсов, поле должно быть в состоянии редактирования.

Так же, как и при инициализации картинки (draw), вызов команды (init) переопределяет только те параметры, которые в ней указаны. Остальные параметры (заданные в других состояниях или в общих свойствах объекта) остаются без изменений

set

Перевод другого объекта в некоторое состояние или изменение его параметров.

  • obj - изменяемый объект (выбирается из списка объектов);
  • st - состояние в которое переводится объект.
  • scr_obj - у какого экрана надо изменить состояние st либо параметры.
  • par - параметр объекта для установки, используется вместе с val, val_obj, val_txt, val_scr.
  • val - значение параметра объекта для установки
  • round - округлить значение, записываемое в val
  • val_obj - id объекта, будет записано в в par
  • val_txt - id текста, будет записано в в par
  • val_scr - id экрана, будет записано в в par
  • var - имя переменной данной машины, значение которой присваивается в параметр par объекта obj
  • scr - экран на который мы хотим перейти
  • user - 1 - сохранять значения для текущего пользователя. Для всех типов объектов кроме options этот флаг игнорируется
  • if - номер (начиная с нуля) команды if при выполнении которого происходит отработка команды set.
  • break - прервать выполнение команд set на этой команде (запустить их снова можно из команд процессов).

Так как все объекты (не только машины) имеют состояния, то при помощи команды set можно их менять. Стоит обратить внимание на то, что когда в параметрах (любых команд) встречается st, речь идет о состоянии другого объекта, а если go, то данной машины состояний.

buy

При переходе в состояние, данная команда открывает системное окно с предложением совершить in-app покупку. В зависимости от действий игрока, покупка может произойти (успех) или не произойти (провал).

  • id покупки - внутренний id покупки для приложения, указывается в объекте store
  • объект(успех) - объект, которому сообщается об удачной покупке
  • состояние(успех) - состояние в которое переводится выбранный объект в случае успешной покупки
  • объект(провал) - объект, которому сообщается о неудачной покупке
  • состояние(провал) - состояние в которое переводится объект в случае неудачной покупки

Команды процессов

wait

Пауза имеет следующие параметры:

  • t - длительность выполнения команды в ms
  • dt - интервал t+/- dt, внутри которого команда может быть случайно прервана (при t>t+dt прерывается в любом случае)
  • p - вероятность срабатывания перехода в состояние, указываемое параметром go.
  • go - состояние, в которое нужно перейти поле окончания времени и срабатывания условия if, если оно указано.
  • if - номер команды if (начиная с нуля), при выполнении которой происходит переход go.
  • loop - зациклить команды
  • break - Прервать выполнение команд wait на этой команде (запустить их сново можно из команд процессов).

Кроме этих параметров, все команды процессов могут содержать параметры break, loop и параметры совпадающие с именами других процессов move,rot и т.д. Все эти параметры служат для управления циклами и прерываниями.

Простейший набор параметров команды wait выглядит следующим образом:

<wait t="1000" go="next"/>    // ждем 1000ms и покидаем состояние

Для программирования объектов со случайным поведением можно использовать последовательность команд wait с параметром вероятности перехода p (от 0 до 1):

<wait t="100" p="0.5" go="st1"/> // через t с вероятностью 1/2 перейдет в st1
<wait go="st2"/> // иначе,  перейдем в st2

Этот же синтаксис позволяет делать состояния с различным временем жизни:

<wait t="100" p="0.5" go="next"/> // с вероятностью 1/2 живем 100ms
<wait t="100" go="next"/>       // или 200ms

Впрочем, последнюю задачу можно решить при помощи указывания интервала dt, внутри которого произойдет окончание команды. Так, состояние, живущее от 800 до 1200ms, реализуется следующим образом:

<wait t="1000" dt="200" go="next"/>

move

Перемещение по сцене:

  • tx, ty - целевые координаты в пикселях, к которым должен переместиться объект
  • dx, dy - величина смещения от текущей (если есть - tx,ty игнорируются). Можно задавать смесь tx, dy или dx,ty
  • v - скороcть перемещения в пикселях в секунду. Для фреймовой анимации, например, ходьбы скорость рассчитывается исходя из длительности одного кадра и числа кадров на фазу движения. Поэтому, в этом случае, удобнее задавать скорость.
  • t - время перемещения (v игнорируется)
  • go - новое состояние - Состояние в которое нужно перейти после окончания времени.
  • if - номер команды if (начиная с нуля), при выполнении которой происходит переход go.
  • loop - зациклить команды - Начать выполнение команд движения с первой команды.
  • break - прервать команды - Прервать выполнение команд move на этой команде (запустить их сново можно из команд процессов).

В большинстве команд процессов, связанных с движением, величина изменения может быть задана в абсолютных или относительных величинах. Так, могут быть указаны целевые координаты tx, ty в которые надо переместиться, или смещение dx, dy относительно текущего положения объекта.

Аналогично, скорость перемещения регулируется, либо явным заданием времени выполнения команды t, либо скоростью v. Исходя из требуемого расстояния, по этой скорости вычисляется необходимое время. Скорость задается в пикселях за cекунду (а не миллисекунду!)

rot

Вращение объекта вокруг точки пивота с координатами px,py. Эти координаты задаются относительно верхнего левого угла объекта в общей секции описания параметров объекта или командой init в данном состоянии.

  • ta - целевой угол поворота объекта
  • da - на сколько надо повернуться (ta игнорируется)
  • v - угловая скорость поворота в градусах в секунду
  • t - время поворота (v игнорируется)
  • go - новое состояние - Состояние в которое нужно перейти после окончания времени.
  • if - номер команды if (начиная с нуля), при выполнении которой происходит переход go.
  • loop - зациклить команды - Начать выполнение команд движения с первой команды.
  • break - прервать команды - Прервать выполнение команд rot на этой команде (запустить их сново можно из команд процессов).

Угол отсчитывается от оси x. Если он положителен, то поворот происходит по часовой стрелке. Если отрицательный - против часовой.

alpha

Изменение прозрачности объекта. Меняется от 0 (полностью прозрачен) до 1 (непрозрачен)

  • ta - целевая прозрачность
  • da - на сколько надо изменить прозрачность от текущей (ta игнорируется)
  • v - скорость изменения прозрачности (в долях единицы в ms)
  • t - время изменения (v игнорируется)
  • go - новое состояние - Состояние в которое нужно перейти после окончания времени.
  • if - номер команды if (начиная с нуля), при выполнении которой происходит переход go.
  • loop - зациклить команды - Начать выполнение команд alpha с первой команды.
  • break - прервать команды - Прервать выполнение команд alpha на этой команде (запустить их сново можно из команд процессов).

scale

Изменение размеров объекта

  • tx, ty - целевой масштаб по каждой оси
  • dx, dy - на сколько изменить масштаб по каждой оси
  • v - скорость изменения масштаба (в долях единицы в сек.)
  • t - длительность выполнения команды (v игнорируется)
  • go - новое состояние - Состояние в которое нужно перейти после окончания времени.
  • if - номер команды if (начиная с нуля), при выполнении которой происходит переход go.
  • loop - зациклить команды - Начать выполнение команд scale с первой команды.
  • break - прервать команды - Прервать выполнение команд scale на этой команде (запустить их сново можно из команд процессов).

phys

Команда phys позволяет имитировать простую физику. В ней задается начальная скорость и действующая на объект сила (ускорение).

  • vx, vy - начальная скорость
  • ax, ay - величина ускорения по каждой оси
  • tvx, tvy - целевая скорость
  • tx, ty - целевая координата
  • go - новое состояние - Состояние в которое нужно перейти после окончания времени.
  • if - номер команды if (начиная с нуля), при выполнении которой происходит переход go.
  • loop - зациклить команды - Начать выполнение команд phys с первой команды.
  • break - прервать команды - Прервать выполнение команд phys на этой команде (запустить их сново можно из команд процессов).

Рассмотрим подпрыгивающий мячик, который при касании с землей деформируется (вертикально сплюскивается). Это можно сделать в 3 состояния (падаем, касаемся и взлетаем). Первоначально мячик находится в координте y=-100, и имеет высоту картинки w=60. Падает он до координаты ty=0. При касании с землёй, мяч сжимается на 20 процентов (sy=0.8). При этом его центр должен опуститься на dy=0.8*w/2 = 24.


<st id="down">                                    // падаем
    <phys vy="0" ay="20" ty="0" go="touch"/>
</st>

<st id="touch">                                   // касаемся земли
    <move dy="24" t="300"/>                       // опускаем центр при сжатии
    <scale ty="0.8" t="300"/>                     // сжимаемся
    <move dy="-24" t="300"/>                      // поднимаем центр при разжатии
    <scale ty="1" t="300" go="up"/>               // разжимаемся
</st>

<st id="up">                                      // взлетаем
    <phys vy="0" ty="-200" go="down"/>
</st>

Напомним, что если объект имеет начальную скорость взлета, равную v=sqrt(2*ay*h), то он подпрыгнет на высоту h. Однако, в данном случае, вместо задания начальной скорости при взлете, мы задаем целевую координату (ty), до которой мяч должен подпрыгнуть.

Команды воздействий

click

Команда вызывается, если на объект кликнули мышкой. Срабатывает на её нажатие.

  • go - состояние в которое при выполнении команды надо перейти (если if нет, то в любом случае);
  • if - номер команды условия (начиная с нуля), при срабатывании которого, происходит переход go.

touch_in

Наведение мыши/пальца на машину, если палец "тащат" по экрану.

  • go - состояние в которое при выполнении команды надо перейти (если if нет, то в любом случае);
  • if - номер команды условия (начиная с нуля), при срабатывании которого, происходит переход go.

touch_out

Выведение мыши/пальца из машины, если палец "тащат" по экрану.

  • go - состояние в которое при клике надо перейти;
  • if - номер команды условия, при котором срабатывает переход go.

mouse_in

Срабатывает при наведение мыши/пальца на машину даже если не нажата кнопка мыши, работает на desktop-ных системах (OSX, Windows)

  • go - состояние в которое при выполнении команды надо перейти (если if нет, то в любом случае);
  • if - номер команды условия (начиная с нуля), при срабатывании которого, происходит переход go.

mouse_out

Срабатывает при выведение мыши/пальца из машины даже если не нажата кнопка мыши, работает на desktop-ных системах (OSX, Windows)

  • go - состояние в которое при выполнении команды надо перейти (если if нет, то в любом случае);
  • if - номер команды условия (начиная с нуля), при срабатывании которого, происходит переход go.

drag

Если на объект наступили мышкой, и не отпуская его, начали перемещать, то при наличии этой команды, объект "прилипнет" к мышке, и будет за ней таскаться. Можно ограничить разрешенную область таскания, за которую объект выпускаться не будет.

  • x1 - разрешено таскать, когда координата объекта правее;
  • x2 - разрешено таскать, когда координата объекта левее;
  • y1 - разрешено таскать, когда координата объекта ниже;
  • y2 - разрешено таскать, когда координата объекта выше;
  • if - номер команды условия (начиная с нуля) разрешения таскания;
  • obj - объект у какоторого надо изменить состояние;
  • st - новое состояние объекта obj;
  • таскать за пивот - 1 - таскать объект за пивот, 0 - за ту точку, за которую схватили

drop

Если нажатая кнопка мышки отпускается, вызвается эта команда. Обычно она используется в связке с командой drop

  • obj - объект, на который надо уронить таскаемый объект;
  • go - состояние в которое переходим при отпускании мышки;
  • if - номер условия разрешения бросания.

Рассмотрим совместное применение команд drag и drop на следующей задаче. Пусть есть ключ и ящик. Ключ можно взять мышкой и перетащить, бросив на ящик. Ящик при этом должен постепенно стать прозрачным, а ключ уменьшиться до нуля. Машина состояний для ключа выглядит следующим образом:


<st id="drag">
    <drag x1="-350" x2="350" y1="-250" y2="250"/>
    <drop obj="box" go="open"/>
</st>

<st id="open">
    <set obj="box" st="open"/>
    <scale tx="0.01" ty="0.01" t="500" go="hide"/>
</st>

<st id="hide">
    <init x="268" y="30"/>
    <scale tx="1" ty="1" t="500" go="drag"/>
</st>


Ящик:


<st id="close">                        // начальное состояние ящика
    <init al="1"/>                     // если его кто-то сюда переведет - он появится.
</st>

<st id="open">              
    <alpha ta="0" t="500"/>            // исчезает по прозрачности за 500 ms
</st>

throw

Если на объект наступили мышкой, не отпуская кнопки, мышку оттащили и затем отпустили, вызывается команда throw со следующими параметрами:

  • go - состояние, в которое, при клике, надо перейти;
  • if - номер команды разрешения бросания;
  • force - получаемая скорость равна разнице пискелей от начала бросания (мышь нажата) до его конца (мышь отжата), умноженная на этот параметр. По умолчанию он равен 1.

Сработав, эта команда задает начальные значения скорости для команды phys, поэтому должна использоваться совместно с ней (см. ниже пример).

apply

Вызывается, если данная машина пересеклась с другой. Обычно используется в совокупности с throw, move, phys, drag.

  • obj - сработает , если пересеклись с этим объектом;
  • x1 - сработает, если центр объекта левее этого x-ка;
  • x2 - сработает, если центр объекта правее этого x-ка;
  • y1 - сработает, если центр объекта выше этого y-ка;
  • y2 - сработает, если центр объекта ниже этого y-ка;
  • rm - радиус этой машины (если rm=0, то она считается прямоугольной)
  • ro - радиус объекта obj (если ro=0, то он считается прямоугольным)
  • st - состояние, в которое надо перевести объект obj
  • go - состояние, в которое надо перейти при срабатывании;
  • if - номер команды условия (начиная с нуля) разрешения применения команды apply.


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


<st id="trow">
    <init x="-350" y="150"/>                      // начальное положение
    <throw go="fly"/>                             // бросаем
</st>

<st id="fly">
    <phys ay="100"/>                              // летим
    <apply y2="300" go="throw"/>                  // с землей
    <apply obj="тыква" rm="8" ro="10" st="bang"/> // с тыквой
</st>

play

Проиграть звук.

  • snd - короткий звук (перетаскивается из редактора ресурсов)
  • voice - голос (запускается как звук, но без цикла и с громкостью голоса) (перетаскивается из редактора ресурсов)
  • mus - длинный звук (перетаскивается из редактора ресурсов)
  • preload - указанный звук будет загружен в память, но не будет проигрываться прямо сейчас. Для ускорения его старта потом
  • loop - зациклить звук (звуки)
  • mus_stop - остановить текущую музыку
  • volume - установить громкость для всех звуком данной машины - тех что уже играют и тех, что будут запущены впоследствии
  • if - номер (начиная с нуля) условия перехода (команды if)

var

Переменная, которой присваивается значение параметра объекта

  • name - имя переменной
  • obj - объект, используемый далее
  • par - Имя параметра, значение которого присваивается переменной
  • val - Значение переменной, если отсутствуют obj и par

Условия if

Параметры:

  • obj - объект
  • st - объект находится в состоянии
  • par - параметр объекта
  • op - операция сравнения с заданным значением. Может быть:
    • < - меньше
    • > - больше
    • != - не равно
    • <> - не равно
    • >= - больше или равно
    • <= - меньше или равно
  • val - значение
  • buy - совершена ли покупка
  • Guest - объект который установил состояние
  • curScr - если текущий экран
  • prScr - если предыдущий экран
  • wasScr - если был экран

Если использовать obj-par-val, то будет происходить проверка на равенство значения параметра объекта и значения записаного в поле val.

Если использовать obj-par-op-val, то будет происходить проверка в соответствии с операцией сравнения значения параметра объекта и значения записаного в поле val.

По отдельноси каждый из if-ов возвращает значение true или false, далее с if-ами можно создавать логические выражения, в том числе со знаками приоритета(скобочками), например в set-aх.

Логические операции:

  • , - и
  • & - и
  • | - или
  • ! - не

Пример записи логического выражения в поле if set-a: (1&2)|(3&(!4))