https://wiki.appsalutecreator.com/api.php?action=feedcontributions&user=Alexeev&feedformat=atomwiki.appsalutecreator.com - Вклад участника [ru]2024-03-28T11:40:42ZВклад участникаMediaWiki 1.31.15https://wiki.appsalutecreator.com/index.php?title=Machine&diff=8995Machine2017-07-31T10:08:10Z<p>Alexeev: /* set */</p>
<hr />
<div>{{TOC right}}<br />
[[Machine]] - [[Object|объект]] '''машина состояний''' (state machine) позволяет описывать сложное поведение игровых объектов. Для машин с типовым набором состояний и поведений вводятся отдельные типы объектов. Например, кнопка, по своей сути, является машиной состояний.<br />
<br />
== Введение ==<br />
<br />
Логика поведения машины разбивается на отдельные узлы (состояния). Машина всегда находится строго в одном состоянии. Переход из одного состояния в другое происходит либо в результате внешнего воздействия на машину, либо в результате окончания некоторых процессов протекающих внутри неё<br />
<br />
Любая машина состояний может быть изображена в виде графа с кружочками и стрелками. У машины всегда активно строго одно состояние (ниже это изображено на левом рисунке темным кружком):<br />
<center><br />
[[Файл:def_states.png]]<br />
</center><br />
Машина состояний не обладает памятью. Это означает, что для анализа того, что произойдет в данном состоянии, неважно как мы в него попали, и какова была предыстория переходов. Важно, только, что мы находимся в этом состоянии. Такое отсутствие памяти упрощает анализ логики машины, так как каждый раз мы концентрируемся на одном конкретном состоянии, а всю логику работы разбиваем на отдельные кирпичики-состояния.<br />
<br />
Выше на правом рисунке изображено некоторое состояние. При входе в него, происходит инициализация состояния. Если на объект оказываются внешние воздействия, то он может покинуть состояние. Наконец, внутри состояния могут работать различные процессы.<br />
<br />
Все команды состояния, разбиваются на три группы:<br />
* '''[[#Инициализация|Инициализация]]''':<br />
** '''[[#draw|draw]]''' - установка графического ресурса;<br />
** '''[[#init|init]]''' - инициализация параметров машины (координаты и т.п.);<br />
** '''[[#set|set]]''' - установка состояния другого объекта;<br />
** '''[[#play|play]]''' - проиграть звук;<br />
** '''[[#var|var]]''' - переменная, которой присваивается значение параметра объекта;<br />
** '''[[#buy|buy]]''' - запуск процедуры in-app покупки;<br />
** '''[[#download|download]]''' - запуск процедуры закачки контента.<br />
* '''[[#Процессы|Процессы]]''':<br />
** '''[[#wait|wait]]''' - задержка по времени;<br />
** '''[[#move|move]]''' - равномерное движение;<br />
** '''[[#rot|rot]]''' - вращение вокруг точки пивота;<br />
** '''[[#alpha|alpha]]''' - изменение прозрачности;<br />
** '''[[#scale|scale]]''' - изменение размера;<br />
** '''[[#phys|phys]]''' - ускоренное движение;<br />
** '''[[#rgb|rgb]]''' - изменить rgb-каналы;<br />
** '''[[#spline|spline]]''' - движение по сплайну (по кривой).<br />
* '''[[#Воздействия|Воздействия]]''':<br />
** '''[[#click|click]]''' - что делать при клике на машине;<br />
** '''[[#drop|drop]]''' - на машине отпущена клавиша мыши;<br />
** '''[[#drag|drag]]''' - машину схватили и тащат;<br />
** '''[[#throw|throw]]''' - машину схватили и кинули;<br />
** '''[[#apply|apply]]''' - сработает при пересечении машины с линией или объектом;<br />
** '''[[#touch_in|touch_in]]''' - наведение мыши/пальца на машину, если палец "тащат" по экрану;<br />
** '''[[#touch_out|touch_out]]''' - выведение мыши из машины, если палец "тащат" по экрану;<br />
** '''[[#touch_up|touch_up]]''' - отжатие мыши от машины;<br />
** '''[[#tap|tap]]''' - умный тач;<br />
** '''[[#mouse_in|mouse_in]]''' - наведение мыши на машину даже если не нажата кнопка мыши;<br />
** '''[[#mouse_out|mouse_out]]''' - выведение мыши из машины даже если не нажата кнопка мыши.<br />
<br />
Кроме этого, есть команда '''[[#if|if]]''', вызываемая другими командами. В ней описываются некоторые логические условия, выполнение которых говорит команде (которая вызвала этот '''if'''), что можно завершать работу. Для разных команд использование этого параметра несколько '''отличается'''!<br />
<br />
Начальные понятия и методы работы с машинами состояний находятся в [[Learning|уроках]],<br />
начиная с [[Checkbox как машина состояний|третьего]].<br />
<br />
== Свойства ==<br />
<br />
Общие для всех объектов свойства описаны в документе [[Object|Object]].<br />
Дополнительные свойства:<br />
<br />
* '''в опции''' - да - машина будет сохранять свое состояние в опции и при следующей инициализации инициал-ся не в первом состоянии, а в состоянии, записанном в опциях.<br />
* '''Состояние''' - Состояние в котором будет находиться машина при инициализации. Если ничего не указано - первое состояние в списке состояний.<br />
* '''Хранить нажатость''' - нужно ли сбрасывать нажатость при изменении состояния.<br />
* '''res''' - графический ресурс машины. Может отсутствовать. Перетягивается из редактора ресурсов(поле должно быть в состоянии редактирования).<br />
* '''states''' - По двойному клику, или по нажатию на кнопку с тремя точками открывается список состояний.<br />
* '''отладка''' - Отображать в окне состояний текущий объект.<br />
* '''курсор''' - Графический ресурс курсора текущего и всех дочерних объектов.<br />
* '''прокликиваемая''' - 0 - машина не пропускает клик, 1 - машина пропускает клик, 2 - машина обрабатывает клик и пропускает его дальше.<br />
<br />
== Инициализация ==<br />
<br />
При попадании в состояние, сразу выполняются команды инициализации init, draw, set, buy, var. Если в этих командах нет параметра break, они все выполняются до запуска процессов. Параметр break (со значением 1) прерывает выполнение команд инициализации данного типа. Их можно перезапустить по окончанию команд процессов.<br />
<br />
'''''Замечание.''''' По возможности, нужно избегать передачи значений другим объектам, в начальном состоянии машины, так как такие команды будут выполнятся даже тогда, когда машина будет выключена на визуальной сцене.<br />
<br />
=== draw ===<br />
<br />
Команда определяет графический ресурс (картинку, которую надо рисовать в данном состоянии). Её параметры:<br />
<br />
* '''res''' - ресурс картинки (перетаскивается из редактора ресурсов);<br />
* '''f''' - начальный кадр;<br />
* '''ft''' - длительность кадра в миллисекундах;<br />
* '''loop''' - число повторов (зацикливаний анимации); если -1, то бесконечно; отсутствует или 0 - будет проигран один раз;<br />
* '''rev''' - играть анимацию в обратном порядке; 0 - прямой порядок проигрывания, 1 - обратный порядок проигрывания;<br />
* '''go''' - перейти в состояние;<br />
* '''if''' - номер (начиная с нуля) команды [[#if|if]] для условия перехода; можно использовать логические операторы (см. [[#if|if]]);<br />
* '''break''' - прервать команды.<br />
<br />
Пустая команда draw (без параметров) "сбрасывает" текущую картинку и в этом состоянии ничего рисоваться не будет. Если в общих параметрах объекта (в базовой панеле свойств) задан ресурс рисования, и он во всех состояниях одинаков, то его можно в состоянии не задавать.<br />
<br />
Если параметра loop нет, кадры анимации проиграются один раз. Чтобы зациклить их, необходимо установить loop=-1 или нужное число раз. Аналогично параметру loop других команд, первый раз draw выполняется в любом случае. Дальнейшие её повторы определяются значением loop. Однако, в отличие от других команд, loop повторяет только '''данную''' команду draw (даже если она не первая).<br />
Для работы loop '''необходимо''' чтобы в редакторе ресурсов в настройках анимации '''было отключено''' зацикливание(looped).<br />
<br>Если есть анимация открывающейся и закрывающейся книги (коробки, двери и т.д.) не обязательно подгружать в проект две анимации, можно использовать одну, но запускать ее в обратном порядке, для этого есть параметр '''rev'''.<br />
<br />
=== init ===<br />
<br />
====Параметры объекта====<br />
<br />
* '''x''','''y''' - координата точки пивота относительно сцены или родительского объекта;<br />
* '''ang''' - угол поворота в градусах; отчитывается вниз от оси x, или вверх, если отрицательный;<br />
* '''al''' - Прозрачность: от 0 (прозрачен) до 1 (не прозрачен);<br />
* '''sx''','''sy''' - масштаб машины по осям (если 1, то это исходный размер; 0.5 - в два раза меньше);<br />
* '''vis''' - видимость - видимость машины (1 - видима, 0 - невидима), если vis = 0, это равноценно отключению объекта в редакторе;<br />
* '''z координата''' - координата машины по z.<br />
* '''z приращение''' - приращение координаты машины по z относительно текущего<br />
* '''прокликиваемая''' - если 1, то картинка прозрачна для клика мышкой (пропускает объектам под ней). Если 2, то клик обрабатывается, но передается дальше;<br />
<br />
====Параметры движения====<br />
<br />
* '''v''' - скорость для команды move<br />
* '''vr''' - угловая скорость для команды rot<br />
* '''vx''','''vy''' - начальная скорость для команды phys<br />
* '''ax''','''ay''' - ускорение для команды phys<br />
<br />
====Системные действия====<br />
<br />
* '''показать рейтинг''' - значение 1 означает, что при выполнении этого инита будет показано окно iOS рейтинга.<br />
Если на девайсе была нажата кнопка "отрейтинговать", то в опции запишется параметр rating значение 1, если нажата кнопка "позже" - rating 2, "никогда" - rating 3.<br />
* '''закрыть приложение''' - значение 1 означает, что при выполнении этого инита приложение будет закрыто.<br />
* '''перезагрузить лэйаут''' - значение 1 означает, что при выполнении этого инита будет перезагружен лэйаут.<br />
* '''вернуться назад''' - начение 1 означает, что при выполнении этого инита произойдет возврат на предыдущий экран.<br />
* '''реклама AdMob''' - 1 - показать, 0 - спрятать, -1 - не изменять состояние.<br />
* '''курсор''' - меняет текущий курсор мыши на указанный графический ресурс. Перетягивается из редактора ресурсов, поле должно быть в состоянии редактирования.<br />
* '''id внешней ссылки в текстовой базе''' - Ссыслка будет взята из текстовой базы в соответствии с текущим маркетом.<br />
* '''[[#Clone|clone]]''' - Значение 1 означает, что в текущем местоположении машины будет создана ее копия<br />
<br />
====Переходы и параметры выполнения====<br />
<br />
* '''if''' - номер (начиная с нуля) команды [[#if|if]] для условия выполнения; можно использовать логические операторы (см. [[#if|if]]);<br />
* '''break''' - прервать команды.<br />
<br />
Так же, как и при инициализации картинки ('''draw'''), вызов команды ('''init''') переопределяет только те параметры, которые в ней указаны. Остальные параметры (заданные в других состояниях или в общих свойствах объекта) остаются без изменений<br />
<br />
=== set ===<br />
<br />
Перевод другого объекта в некоторое состояние или изменение его параметров.<br />
<br />
* '''obj''' - изменяемый объект (выбирается из списка объектов). В значении объекта можно указать this, это значит что машина сама себе пропишет какой то параметр или состояние.<br />
* '''scr_param''' - глобальный либо текущий экран, параметры которого меняем.<br />
* '''scr_state''' - экран, состояние которого меняем.<br />
* '''parent''' - Объект, который будет установлен в качестве родителя объекту из obj. Объект obj будет оторван от текущего своего родителя и добавлен в детей объекта parent. При этом у obj сбивается значение Z. Если оно должно быть отличным от нуля, то нужно установить заново после смены родителя.<br><br />
* '''st''' - состояние в которое переводится объект.<br><br />
* '''par''' - параметр объекта для установки, используется вместе с val, val_obj, val_txt, val_scr,val_vid,val_res,val_node.<br />
* '''mSt''' - Состояние машины в котором будем изменять параметр команды.<br />
* '''mCmd''' - Имя команды, параметр которой меняем.<br />
* '''mCmdN''' - Порядковый номер в перечне одноименных команд состояния.<br />
* '''mPar''' - Установить этот параметр команды в значение val.<br />
* '''val_obj''' - id объекта, будет записано в в par<br />
* '''val_txt''' - id текста, будет записано в в par(параметр для текстов "txtID")<br />
* '''val_vid''' - id video, будет записано в par(параметр для видео "video" - RGB, "videoA" - Alpha)<br />
* '''val_scr''' - id экрана, будет записано в в par<br />
* '''val_res''' - Новое значение графического ресурса (перетаскивается из редактора ресурсов). (пока не работает)<br />
* '''val_node''' - Новое нода графа (выбирается из списка, при заданном объекте)<br />
* '''val''' - значение параметра объекта для установки<br />
* '''var''' - имя переменной данной машины, значение которой присваивается в параметр par объекта obj<br />
* '''round''' - округлить значение, записываемое в val<br><br />
* '''position''' - объект указанный в поле '''obj''' будет отпозиционирован относительно указанного объекта в этом поле ( можно одновременно и задавать состояние '''st''' в которое перевести объект ( поле obj ) ); <br />
* '''pos_dx''' - смещение по оси X от точки пивоты объекта из поля выше ( если это поле не указывать, смещение будет = 0 );<br />
* '''pos_dy''' - смещение по оси Y от точки пивоты объекта из поля выше ( если это поле не указывать, смещение будет = 0 )<br />
* '''scr''' - экран на который мы хотим перейти<br />
* '''user''' - 1 - сохранять значения для текущего пользователя. Для всех типов объектов кроме options этот флаг игнорируется<br><br />
* '''if''' - номер (начиная с нуля) команды [[#if|if]] при выполнении которого происходит отработка команды set. <br />
* '''break''' - прервать выполнение команд set на этой команде (запустить их снова можно из команд процессов).<br />
<br />
Так как все объекты (не только машины) имеют состояния, то при помощи команды set можно их менять. Стоит обратить внимание на то, что когда в параметрах (любых команд) встречается st, речь идет о состоянии другого объекта, а если go, то данной машины состояний.<br />
<br />
=== play ===<br />
<br />
Проиграть звук<br />
<br />
*'''snd''' - Короткий звук (перетаскивается из редактора ресурсов);<br />
*'''voice''' - Голос (перетаскивается из редактора ресурсов);<br />
*'''mus''' - Длинный звук (перетаскивается из редактора ресурсов);<br />
*'''preload''' - Указанный звук будет загружен в память, но не будет проигрываться прямо сейчас. Для ускорения его старта потом;<br />
*'''loop''' - Зациклить указанный звук. Использовать вместе с snd или voice;<br />
*'''mus_loop''' - Зациклить указанную музыку. По умолчанию музыка всегда зацикленна. То есть, фактически этой флаг используется, когда нужно убрать зацикливание.<br />
*'''repeat''' - Число повторов указанного звука при отключенном loop;<br />
*'''mus_stop''' - Остановить музыку. Если используется вместе с mus, то остановится указанная. Если нет - то вся текущая.<br />
*'''stop''' - Остановить указанный звук. Использовать вместе с snd или voice.<br />
*'''mus_fading''' - Время появления/затухания указанной музыки в ms. Использовать вместе с mus.<br />
*'''fading''' - Время появления/затухания указанного звука. Использовать вместе с snd или voice. <br />
*'''volume''' - Установить громкость для всех звуков данной машины - тех что уже играют и тех, что будут запущены впоследствии;<br />
*'''не выгружать''' - Позволяет продолжать проигрывание звука при смене экранов.<br />
*'''go''' - Выбор состояния, в которое нужно перейти после проигрывания музыки/звука/голоса.<br />
*'''if''' - Номер (начиная с нуля) условия перехода [[#if|if]].<br />
<br />
Особенности применения:<br />
<br />
1) Короткий звук (''snd'') нельзя запустить в первом (инитном) состоянии машины. Для того, чтобы запустить звук сразу при загрузке экрана, нужно в первом состоянии машины записать мгновенный переход во второе состояние мамашины (например, команда ''wait'', поле ''go'', в поле выбрать второе состояние), а во втором состоянии уже запустить звук.<br />
<br />
2) Если звук нужно зациклить и проигрывать какое-то количество раз (''loop=1,2,3,..,n'') или бесконечно (''loop=-1''), то нужно проследить чтобы состояние, в котором запускается звук, не вызывалось повторно во время проигрывания звука, иначе возникнет наложение звуков.<br />
<br />
3) Если во время проигрывания звука машина меняет свое состояние, звук продолжает играть.<br />
<br />
4) Если в одной машине почти одновременно воспроизводится несколько звуков, то они прерывают друг друга.<br />
<br />
5) Если каждый звук воспроизводится в отдельной машине, то они звучат параллельно.<br />
<br />
6) Если не указан звук и голос, то команда (''stop'') остановит все звуки, запущенные этой машиной.<br />
<br />
7) Музыка (''mus'') может быть формата .ogg или .mp3. На экране может воспроизводится только одна .mp3 музыка. Любой запуск .mp3 музыки независимо от того, в какой машине он осуществляется, будет прекращать проигрывание предыдущей .mp3 музыки. В тоже время может воспроизводиться несколько .ogg музыки.<br />
<br />
8) Музыка, которая проигрывается на глобальном экране, проигрывается на всех экранах проекта.<br />
<br />
=== var ===<br />
<br />
Переменная, которой присваивается значение параметра объекта<br />
<br />
*'''name''' - имя переменной;<br />
*'''tp''' - тип переменной;<br />
*'''obj''' - объект, используемый далее;<br />
*'''par''' - имя параметра, значение которого присваивается переменной;<br />
*'''val''' - значение переменной, если отсутствуют obj и par;<br />
*'''user''' - если стоит "1", то будет считываться с текущего профиля в опциях<br />
*'''func''' - в выпадающем списке можно выбрать функцию:<br />
**'''random''' - использует arg1 и arg2, возвращает случайное целое число в диапазоне arg1 .. arg2.<br />
**'''conc''' - объединяет 4 строки arg1,arg2,arg3,arg4. Возвращает строку, в которой соединены все строки<br />
**'''exp''' - экспонента от аргумента arg1.<br />
**'''ln''' - натуральный логарифм аргумента arg1.<br />
*'''arg1''' - аргумент функции<br />
*'''arg2''' - аргумент функции<br />
*'''arg3''' - аргумент функции<br />
*'''arg4''' - аргумент функции<br />
<br />
Обозначенная переменная существует (может использоваться) только в текущем состоянии. Переменная может определятся в одном состоянии только один раз. Если созданной переменной нужно изменить значение в рамках состояния, это можно сделать через другую переменную или через параметр опций ([[Options]]). Если ее значение нужно использовать в другом состоянии, то оно присваивается параметру опций, а затем заново считывается в новом состоянии. Переменные можно указывать в поле ''val'' с другими математическими действиями и цифрами, при этом каждое действие заключать в скобки. Если в поле ''val'' указать имя переменной ''А'' без скобок - воспримется строка ''А'', если указать в скобках - воспримется значение переменной.<br />
<br />
=== buy === <br />
<br />
'''(in-app совершить in-app покупку)'''<br />
<br />
При переходе в состояние, данная команда открывает системное окно с предложением совершить in-app покупку. В зависимости от действий игрока, покупка может произойти (успех) или не произойти (провал).<br />
<br />
* '''id покупки''' - внутренний id покупки для приложения, указывается в объекте [[Store]];<br />
* '''объект(успех)''' - объект, которому сообщается об удачной покупке;<br />
* '''состояние(успех)''' - состояние в которое переводится выбранный объект в случае успешной покупки;<br />
* '''объект(провал)''' - объект, которому сообщается о неудачной покупке;<br />
* '''состояние(провал)''' - состояние в которое переводится объект в случае неудачной покупки.<br />
<br />
=== download ===<br />
<br />
'''(скачать загружаемый контент)'''<br />
<br />
При переходе в состояние будет совершена попытку закачать контент.<br />
* '''url''' - ссылка на zip архив с контентом в интернете.<br />
* '''объект успех''' - объект, которому в случае успешной закачки будет задаваться указанное состояние.<br />
* '''состояние (успех)''' - состояние, которое будет устанавливаться выше указанному объекту, в случае успешной закачки.<br />
* '''объект (провал)''' -объект, которому, в случае неудачи закачки, будет устанавливаться указанное состояние.<br />
* '''состояние (провал)''' - состояние, которое, в случае неудачи закачки,будет устанавливаться выше указанному объекту.<br />
* '''счетчик прогресса''' - объект, типа счетчик, который отображает прогресс закачки контента. Крайне желательно, что бы он измерялся в диапазоне от 0 до 100.<br />
<br />
Существует несколько причин при которых вызывается состояние "провал". Для того что бы сообщить пользователю, по какой именно причине возник провал закачки, следует идентифицировать причины провала. Это возможно сделать с помощью параметра <br />
<pre><br />
downloadErrCode<br />
</pre><br />
Ниже приведены значение параметра которые помогут вывести нужное текстовое сообщение :<br />
<pre><br />
GCUSTOM_ERROR_CODE_ERROR_UNKNOWN = 1, //!< ошибка не классифицирована<br />
GCUSTOM_ERROR_CODE_WIFI_DISABLED = 2, //!< отключен WIFI<br />
GCUSTOM_ERROR_CODE_SDCARD_UNAVAILABLE = 3, //!< SD-карта недоступна<br />
GCUSTOM_ERROR_CODE_SDCARD_FULL = 4, //!< SD-карта переполнена перед закачкой<br />
GCUSTOM_ERROR_CODE_UNZIP_FAIL = 5 //!< ошибка при распаковки пака (скорее всего на SD-карте не<br />
хватает места для распаковки <br />
</pre><br />
<br />
== Процессы ==<br />
<br />
Все команды процессов, кроме параметров описанных ниже, могут содержать параметры, совпадающие с именами других команд. В этих параметрах указывается номер (начиная с нуля) команды, которую надо запустить на выполнение, после окончания действия данной команды процесса.<br />
<br />
Если в команде процесса есть условие '''[[#if|if]]''', то после окончания работы команды она ждет пока это условие не выполнится. Только после этого переходит к следующей команде этого же типа<br />
или в другое состояние (если есть параметр go).<br />
Исключением является команда wait, которая '''не''' ждёт срабатывания '''[[#if|if]]'''. Если он по окончанию wait сработал, то происходит переходит в другое состояние, если есть параметр go.<br />
Если параметра go нет, то в любом случае запускается следующий wait (т.е. if относится только к переходу go).<br />
<br />
=== wait ===<br />
<br />
Команда паузы (временной задержки). Если параметра '''t''' нет, то срабатывает сразу.<br />
Может также использоваться для логических ветвлений, случайных переходов в другие состояния и т.д.<br />
<br />
* '''t''' - длительность выполнения команды в ms;<br />
* '''dt''' - интервал от t-dt до t+dt, внутри которого команда может быть случайно прервана (при t>t+dt прерывается в любом случае);<br />
* '''p''' - вероятность срабатывания перехода в состояние, указываемое параметром go;<br />
* '''go''' - состояние, в которое нужно перейти поле окончания времени и срабатывания условия [[#if|if]], если оно указано;<br />
* '''if''' - номер (начиная с нуля) команды [[#if|if]], при выполнении которой происходит переход go;<br />
* '''loop''' - зациклить команды;<br />
* '''break''' - прервать выполнение команд wait на этой команде (запустить их снова можно из команд процессов).<br />
* '''init''', '''set''', '''draw''', '''move''', '''rot''', '''alpha''', '''scale''', '''phys''' - Номер запускаемой команды.<br />
Простейший набор параметров команды wait выглядит следующим образом:<br />
<pre><br />
<wait t="1000" go="next"/> // ждем 1000ms и покидаем состояние<br />
</pre><br />
Для программирования объектов со случайным поведением можно использовать последовательность команд wait с параметром вероятности перехода p (от 0 до 1):<br />
<pre><br />
<wait t="100" p="0.5" go="st1"/> // через t с вероятностью 1/2 перейдет в st1<br />
<wait go="st2"/> // иначе, перейдем в st2<br />
</pre><br />
Этот же синтаксис позволяет делать состояния с различным временем жизни:<br />
<pre><br />
<wait t="100" p="0.5" go="next"/> // с вероятностью 1/2 живем 100ms<br />
<wait t="100" go="next"/> // или 200ms<br />
</pre><br />
Впрочем, последнюю задачу можно решить при помощи указывания интервала dt, внутри которого произойдет окончание команды. Так, состояние, живущее от 800 до 1200ms, реализуется следующим образом:<br />
<pre><br />
<wait t="1000" dt="200" go="next"/><br />
</pre><br />
<br />
=== move ===<br />
<br />
Перемещение по сцене:<br />
* '''tx''', '''ty''' - целевые координаты в пикселях, к которым должен переместиться объект. Можно указывать переменные заданные с помощью [http://ge.absolutist.com/index.php/Machine#var_2 переменной var];<br />
* '''dx''', '''dy''' - величина смещения от текущей (если есть - tx,ty игнорируются); можно задавать смесь tx, dy или dx,ty;<br />
* '''v''' - скорость перемещения в пикселях в секунду; для фреймовой анимации, например, ходьбы скорость рассчитывается исходя из длительности одного кадра и числа кадров на фазу движения. Поэтому, в этом случае, удобнее задавать скорость;<br />
* '''t''' - время перемещения (v игнорируется);<br />
* '''go''' - новое состояние - Состояние в которое нужно перейти после окончания времени;<br />
* '''if''' - номер (начиная с нуля) команды [[#if|if]], при выполнении которой происходит переход go; команда ждет срабатывания условия, и не запускает следующую команду move, пока if не выполнится; <br />
* '''loop''' - зациклить команды - Начать выполнение команд движения с первой команды;<br />
* '''break''' - прервать команды - Прервать выполнение команд move на этой команде (запустить их снова можно из команд процессов).<br />
* '''init''', '''set''', '''draw''', '''move''', '''rot''', '''alpha''', '''scale''', '''phys''' - Номер запускаемой команды.<br />
<br />
В большинстве команд процессов, связанных с движением, величина изменения может быть задана в абсолютных или относительных величинах. Так, могут быть указаны целевые координаты tx, ty в которые надо переместиться, или смещение dx, dy относительно текущего положения объекта.<br />
<br />
Аналогично, скорость перемещения регулируется, либо явным заданием времени выполнения команды t, либо скоростью v. Исходя из требуемого расстояния, по этой скорости вычисляется необходимое время. Скорость задается в пикселях за секунду (а не миллисекунду!)<br />
<br />
=== rot ===<br />
<br />
Вращение объекта вокруг точки пивота с координатами px,py. Эти координаты задаются относительно верхнего левого угла объекта в общей секции описания параметров объекта или командой init в данном состоянии.<br />
* '''ta''' - целевой угол поворота объекта;<br />
* '''da''' - на сколько надо повернуться (ta игнорируется);<br />
* '''v''' - угловая скорость поворота в градусах в секунду;<br />
* '''t''' - время поворота (v игнорируется);<br />
* '''go''' - новое состояние - Состояние в которое нужно перейти после окончания времени.<br />
* '''if''' - номер (начиная с нуля) команды [[#if|if]], при выполнении которой происходит переход go; команда ждет срабатывания условия, и не запускает следующую команду rot, пока if не выполнится; <br />
* '''loop''' - зациклить команды - Начать выполнение команд движения с первой команды;<br />
* '''break''' - прервать команды - Прервать выполнение команд rot на этой команде (запустить их снова можно из команд процессов).<br />
* '''init''', '''set''', '''draw''', '''move''', '''rot''', '''alpha''', '''scale''', '''phys''' - Номер запускаемой команды.<br />
<br />
Угол отсчитывается от оси x. Если он положителен, то поворот происходит по часовой стрелке. Если отрицательный - против часовой.<br />
<br />
=== alpha ===<br />
<br />
Изменение прозрачности объекта. Меняется от 0 (полностью прозрачен) до 1 (непрозрачен)<br />
* '''ta''' - целевая прозрачность<br />
* '''da''' - на сколько надо изменить прозрачность от текущей (ta игнорируется)<br />
* '''v''' - скорость изменения прозрачности (в долях единицы в ms)<br />
* '''t''' - время изменения (v игнорируется)<br />
* '''go''' - новое состояние - Состояние в которое нужно перейти после окончания времени.<br />
* '''if''' - номер (начиная с нуля) команды [[#if|if]], при выполнении которой происходит переход go; команда ждет срабатывания условия, и не запускает следующую команду alpha, пока if не выполнится; <br />
* '''loop''' - зациклить команды - Начать выполнение команд alpha с первой команды.<br />
* '''break''' - прервать команды - Прервать выполнение команд alpha на этой команде (запустить их снова можно из команд процессов).<br />
* '''init''', '''set''', '''draw''', '''move''', '''rot''', '''alpha''', '''scale''', '''phys''' - Номер запускаемой команды.<br />
<br />
Если у объекта прозрачность ''al=0.00'', то он невидим для всякого взаимодействия. Если у объекта прозрачность ''al=0.01'', то он видим для клика, но невидим для дропа(команда drop на объект не видит объект с прозрачностью ''0.01''). Если у объекта ''al=0.02'', то он видим и для клика, и для дропа.<br />
<br />
=== scale ===<br />
<br />
Изменение размеров объекта<br />
* '''tx''', '''ty''' - целевой масштаб по каждой оси<br />
* '''dx''', '''dy''' - на сколько изменить масштаб по каждой оси<br />
* '''v''' - скорость изменения масштаба (в долях единицы в сек.)<br />
* '''t''' - длительность выполнения команды (v игнорируется)<br />
* '''go''' - новое состояние - Состояние в которое нужно перейти после окончания времени.<br />
* '''if''' - номер (начиная с нуля) команды [[#if|if]], при выполнении которой происходит переход go; команда ждет срабатывания условия, и не запускает следующую команду scale, пока if не выполнится; <br />
* '''loop''' - зациклить команды - Начать выполнение команд scale с первой команды.<br />
* '''break''' - прервать команды - Прервать выполнение команд scale на этой команде (запустить их сново можно из команд процессов).<br />
* '''init''', '''set''', '''draw''', '''move''', '''rot''', '''alpha''', '''scale''', '''phys''' - Номер запускаемой команды.<br />
<br />
=== phys ===<br />
<br />
Команда phys позволяет имитировать простую физику. В ней задается начальная скорость и действующая на объект сила (ускорение).<br />
<br />
* '''vx''', '''vy''' - начальная скорость<br />
* '''ax''', '''ay''' - величина ускорения по каждой оси<br />
* '''a''' - полное ускорение<br />
* '''tvx''', '''tvy''' - целевая скорость<br />
* '''tx''', '''ty''' - целевая координата<br />
* '''go''' - новое состояние - Состояние в которое нужно перейти после окончания времени.<br />
* '''if''' - номер (начиная с нуля) команды [[#if|if]], при выполнении которой происходит переход go; команда ждет срабатывания условия, и не запускает следующую команду phys, пока if не выполнится; <br />
* '''loop''' - зациклить команды - Начать выполнение команд phys с первой команды.<br />
* '''break''' - прервать команды - Прервать выполнение команд phys на этой команде (запустить их снова можно из команд процессов). <br />
* '''init''', '''set''', '''draw''', '''move''', '''rot''', '''alpha''', '''scale''', '''phys''' - Номер запускаемой команды.<br />
<br />
Рассмотрим подпрыгивающий мячик, который при касании с землей деформируется (вертикально сплюскивается). Это можно сделать в 3 состояния (падаем, касаемся и взлетаем). Первоначально мячик находится в координате y=-100, и имеет высоту картинки w=60. Падает он до координаты ty=0. При касании с землёй, мяч сжимается на 20 процентов (sy=0.8). При этом его центр должен опуститься на dy=0.8*w/2 = 24.<br />
<pre><br />
<br />
<st id="down"> // падаем<br />
<phys vy="0" ay="20" ty="0" go="touch"/><br />
</st><br />
<br />
<st id="touch"> // касаемся земли<br />
<move dy="24" t="300"/> // опускаем центр при сжатии<br />
<scale ty="0.8" t="300"/> // сжимаемся<br />
<move dy="-24" t="300"/> // поднимаем центр при разжатии<br />
<scale ty="1" t="300" go="up"/> // разжимаемся<br />
</st><br />
<br />
<st id="up"> // взлетаем<br />
<phys vy="0" ty="-200" go="down"/><br />
</st><br />
<br />
</pre><br />
Напомним, что если объект имеет начальную скорость взлета, равную v=sqrt(2*ay*h), то он подпрыгнет на высоту h. Однако, в данном случае, вместо задания начальной скорости при взлете, мы задаем целевую координату (ty), до которой мяч должен подпрыгнуть.<br />
<br />
=== rgb ===<br />
<br />
* '''trgb''' - целевой эффект rgb; подразумевает под собой цвет в виде HEX-кода; по-умолчанию: FFFFFF;<br />
* '''t''' - длительность выполнения команды в ms;<br />
* '''go''' - состояние, в которое нужно перейти поле окончания времени и срабатывания условия [[#if|if]], если оно указано;<br />
* '''if''' - номер (начиная с нуля) команды [[#if|if]], при выполнении которой происходит переход go;<br />
* '''loop''' - зациклить команды;<br />
* '''break''' - прервать выполнение команд wait на этой команде (запустить их снова можно из команд процессов).<br />
* '''init''', '''set''', '''draw''', '''move''', '''rot''', '''alpha''', '''scale''', '''phys''' - Номер запускаемой команды.<br />
<br />
=== spline ===<br />
<br />
Сплайн позволяет перемещать машину по заранее заданной траектории.<br />
<br />
====Параметры====<br />
<br />
*'''key''' - точки сплайна по которым движется <br />
*'''t''' - время движения по траектории<br />
*'''go''' - по окончанию переход в состояние<br />
*'''if''' - условие перехода<br />
*'''loop''' - количество повторений<br />
*'''break''' - прервать команды на этой<br />
*'''wait''' - номер запускаемого действия<br />
*'''init''' - номер запускаемого действия<br />
*'''alpha''' - номер запускаемого действия<br />
*'''rot''' - номер запускаемого действия<br />
*'''move''' - номер запускаемого действия<br />
*'''set''' - номер запускаемого действия<br />
*'''phys''' - номер запускаемого действия<br />
*'''scale''' - номер запускаемого действия<br />
*'''drow''' - номер запускаемого действия<br />
<br />
====Построение сплайна====<br />
<br />
# в состоянии машины добавляем правой кнопкой мыши действие "spline"<br />
# добавляем минимально необходимые параметры: '''key''' и '''t''', указываем время движения в '''t'''<br />
# выделяем для редактирования поле '''key'''<br />
# записываем координаты точек через запятую, сначала x потом y, например: -211,-248,-151,-248,-91,-247,59,-246,60,101,60,159,1,190<br />
Если записали все координаты вручную, то можно сохранить и проверять.<br />
Или можно в окне списка состояний нажать на кнопку "build spline" (справа вверху).<br />
[[Файл:Btn spline.jpg|500px]]<br />
<br />
Окно с списком состояний закроется, появится дополнительная панель с настройками сплайна и появится возможность указывать мышкой по экрану точки для сплайна.<br />
<br />
[[Файл:Spline panel.jpg|500px]]<br />
<br />
Точки сплайна указываются кликом левой кнопки мыши по экрану.<br />
<br />
Возможности редактирования:<br />
<br />
'''режимы:'''<br />
*'''add''' - по нажатию левой кнопкой мыши по экрану - будет добавлена новая точка, которая соединится с предыдущей<br />
*'''select''' - по нажатию левой кнопкой мыши по точке сплайна появится возможность отредактировать её положение перетащив её или поменяв её координаты в полях x и у<br />
*'''delete''' - по нажатию левой кнопкой мыши по точке сплайна точка удалится<br />
<br />
Чтобы удалить все точки сплайна необходимо нажать на кнопку "'''delete all knots'''"<br />
<br />
Сохранить сплайн можно нажав на кнопку "'''Save spline'''"<br />
<br />
====Дополнительные сведения====<br />
<br />
* Время движения между двумя соседними точками всегда одинаково, то есть чем дальше друг от друга соседние точки, тем быстрее будет двигаться объект, чем ближе - тем медленней.<br />
* Координаты сплайна просчитываются относительно точки пивота родительского объекта, если соответствующая машина является подобъектом. На координаты могут влиять модификаторы родительского объекта.<br />
<br />
== Воздействия ==<br />
<br />
=== click ===<br />
<br />
Команда вызывается, если на объект кликнули мышкой. Срабатывает на её нажатие.<br />
* '''go''' - состояние в которое при выполнении команды надо перейти (если if нет, то в любом случае);<br />
* '''if''' - номер (начиная с нуля) команды условия [[#if|if]], при срабатывании которого, происходит переход go.<br />
<br />
По клику машина записывает координаты клика в параметры: clickX, clickY.<br />
<br />
=== touch_in ===<br />
<br />
Наведение мыши/пальца на машину, если палец "тащат" по экрану.<br />
* '''go''' - состояние в которое при выполнении команды нужно перейти (если if нет, то в любом случае);<br />
* '''if''' - номер (начиная с нуля) команды условия [[#if|if]], при срабатывании которого, происходит переход ''go''.<br />
<br />
=== touch_out ===<br />
Выведение мыши/пальца из машины, если палец "тащат" по экрану.<br />
* '''go''' - состояние в которое при клике нужно перейти;<br />
* '''if''' - номер (начиная с нуля) команды условия [[#if|if]], при котором срабатывает переход ''go''.<br />
<br />
=== touch_up ===<br />
<br />
Отжатие мыши от машины<br />
<br />
* '''go''' - состояние в которое при отжатии мыши нужно перейти;<br />
* '''if''' - номер (начиная с нуля) команды условия [[#if|if]], при котором срабатывает переход ''go''.<br />
<br />
=== mouse_in ===<br />
<br />
Срабатывает при наведение мыши/пальца на машину даже если не нажата кнопка мыши, работает на desktop-ных системах (OSX, Windows)<br />
* '''go''' - состояние в которое при выполнении команды нужно перейти (если if нет, то в любом случае);<br />
* '''if''' - номер (начиная с нуля) команды условия [[#if|if]], при срабатывании которого, происходит переход ''go''.<br />
<br />
=== mouse_out ===<br />
Срабатывает при выведение мыши/пальца из машины даже если не нажата кнопка мыши, работает на desktop-ных системах (OSX, Windows)<br />
* '''go''' - состояние в которое при выполнении команды нужно перейти (если if нет, то в любом случае);<br />
* '''if''' - номер (начиная с нуля) команды условия [[#if|if]], при срабатывании которого, происходит переход ''go''.<br />
<br />
=== drag ===<br />
<br />
Данная команда позволяет "таскать" объект по сцене нажав и удерживая клавишу мишки или (палец в случае сенсорного устройства) на нем.Так же есть возможность ограничить разрешенную область таскания, за пределы которой объект вытащить невозможно. [[Файл:drag.jpg|right]]<br />
* '''x1''' - разрешено таскать, когда координата объекта правее;<br />
* '''x2''' - разрешено таскать, когда координата объекта левее;<br />
* '''y1''' - разрешено таскать, когда координата объекта ниже;<br />
* '''y2''' - разрешено таскать, когда координата объекта выше;<br />
* '''if''' - номер команды условия (начиная с нуля) разрешения таскания;<br />
* '''obj''' - объект у которого надо изменить состояние;<br />
* '''st''' - новое состояние объекта obj;<br />
* '''за пивот''' - "да" - таскать объект за пивот, "нет" - за ту точку, за которую схватили<br />
* '''приклеивать''' - приклеивать при клике к мышке.<br />
<br />
=== dragRot ===<br />
<br />
Данная команда позволяет вращать объект вокруг точки пивота. Нажав и удерживая клавишу мишки или палец (в случае сенсорного устройства) на нем, мы можем вращать его по часовой либо против часовой стрелки. При многократном вращении вокруг своей оси значение его угла не накапливается, а обнуляется выходя за границы [360 ; -360] градусов. [[Файл:dragRot.jpg|right]]<br />
* '''if''' - номер команды условия (начиная с нуля) разрешения таскания;<br />
* '''obj''' - объект у которого надо изменить состояние;<br />
* '''st''' - новое состояние объекта obj;<br />
* '''maxVel''' - Максимальная скорость вращения градус/сек;<br />
* '''objStart''' - объект при начале вращения;<br />
* '''stStart''' - его новое состояние;<br />
* '''objEnd''' - объект при завершении вращения;<br />
* '''stEnd''' - его новое состояние;<br />
<br />
=== drop ===<br />
<br />
Если нажатая кнопка мышки отпускается, вызывается эта команда. Обычно она используется в связке с командой drag<br />
* '''obj''' - объект, на который надо уронить таскаемый объект;<br />
* '''go''' - состояние в которое переходим при отпускании мышки;<br />
* '''if''' - номер (начиная с нуля) условия [[#if|if]] разрешения бросания.<br />
<br />
Рассмотрим совместное применение команд drag и drop на следующей задаче. Пусть есть ключ и ящик. Ключ можно взять мышкой и перетащить, бросив на ящик. Ящик при этом должен постепенно стать прозрачным, а ключ уменьшиться до нуля. Машина состояний для ключа выглядит следующим образом:<br />
<pre><br />
<br />
<st id="drag"><br />
<drag x1="-350" x2="350" y1="-250" y2="250"/><br />
<drop obj="box" go="open"/><br />
</st><br />
<br />
<st id="open"><br />
<set obj="box" st="open"/><br />
<scale tx="0.01" ty="0.01" t="500" go="hide"/><br />
</st><br />
<br />
<st id="hide"><br />
<init x="268" y="30"/><br />
<scale tx="1" ty="1" t="500" go="drag"/><br />
</st><br />
<br />
<br />
</pre><br />
Ящик:<br />
<pre><br />
<br />
<st id="close"> // начальное состояние ящика<br />
<init al="1"/> // если его кто-то сюда переведет - он появится.<br />
</st><br />
<br />
<st id="open"> <br />
<alpha ta="0" t="500"/> // исчезает по прозрачности за 500 ms<br />
</st><br />
<br />
</pre><br />
<br />
====Использование свойства "Условие перехода" ====<br />
<br />
Можно прописать условие, при котором выполняется переход при дропе.<br />
[[Файл:Drop_if.png|300px|thumb|right]]<br />
<br />
С помощью этого условия мы можем научить наш объект выполнять разные задачи в зависимости от того, как именно его дропнули.<br />
Пусть есть объект который можно таскать. Когда объект не таскается должен быть включен флаер, привязанный к этому объекту. При клике на объект, он должен поворачиваться на 90 градусов. При дропе на соответствующую маску объект стает на свое место(Если выполнены условия, к примеру: установлен предыдущий объект и наш объект имеет правильный угол). Если дроп в любое другое место, то должен включится флаер.<br />
<br />
Для того, чтобы научить машину различать клик по ней и ее таскание сделаем следующее. Пропишем ей 2 состояния: click и drag, а также выставим ей параметр "хранить нажатость" = 1. В click будем вычислять координаты объекта и записывать объекту параметр допустимого смещения при котором таскание будет восприниматься как клик. (В данном примере эти параметры: cx, cy, vx, vy. А допустимое смещение составляет 10 пикселей.)<br />
<br />
В состоянии drag будем проверять попадает ли координата объекта при дропе в границы допустимого смещения. Для того чтобы сравнить параметр объекта с переменной, вычтем из нашего объекта, то что мы записали в click. В зависимости от условий и места дропа переходим в соответствующее состояние.<br />
<br />
[[Файл:Click.png|330px]] [[Файл:Drag st.png|630px]]<br />
<br />
=== throw ===<br />
<br />
Если на объект наступили мышкой, не отпуская кнопки, мышку оттащили и затем отпустили, вызывается команда throw со следующими параметрами:<br />
* '''go''' - состояние, в которое, при клике, надо перейти;<br />
* '''if''' - номер (начиная с нуля) команды [[#if|if]] разрешения бросания;<br />
* '''force''' - получаемая скорость равна разнице пикселей от начала бросания (мышь нажата) до его конца (мышь отжата), умноженная на этот параметр. По умолчанию он равен 1.<br />
<br />
Сработав, эта команда задает начальные значения скорости для команды phys, поэтому должна использоваться совместно с ней (см. ниже пример).<br />
<br />
=== tap ===<br />
<br />
* '''go''' - Состояние в которое нужно перейти после окончания времени.<br />
* '''if''' - номер (начиная с нуля) условия [[#if|if]] разрешения бросания.<br />
<br />
=== apply ===<br />
<br />
Вызывается, если данная машина пересеклась с другой. Обычно используется в совокупности с throw, move, phys, drag.<br />
* '''obj''' - сработает , если пересеклись с этим объектом;<br />
* '''x1''' - сработает, если центр объекта левее этого x-са;<br />
* '''x2''' - сработает, если центр объекта правее этого x-са;<br />
* '''y1''' - сработает, если центр объекта выше этого y-ка;<br />
* '''y2''' - сработает, если центр объекта ниже этого y-ка;<br />
* '''rm''' - радиус этой машины (если rm=0, то она считается прямоугольной)<br />
* '''ro''' - радиус объекта obj (если ro=0, то он считается прямоугольным)<br />
* '''st''' - состояние, в которое надо перевести объект obj<br />
* '''go''' - состояние, в которое надо перейти при срабатывании;<br />
* '''if''' - номер (начиная с нуля) команды условия [[#if|if]] разрешения применения команды apply.<br />
<br />
[[Файл:Апплай.png|500px]]<br />
<br />
Блок схема работы '''apply'''<br />
<br />
[[Файл:Блок схема apply.png|500px]]<br />
<br />
* Сначала у нас проверяется координаты '''x1''', '''x2''', '''y1''', '''y2'''.<br />
* Далее проверяет если '''obj'''<br />
* Если '''obj''' нет, то идёт проверку, и выдаёт результат<br />
(если при этом если '''x1''', '''x2''', '''y1''', '''y2''' нет, то они считаются по ширине и высоте всего экрана.)<br />
* Если есть '''obj''', то проверяет есть ли радиусы '''rm''', '''ro'''.<br />
* Если он есть, то значит у нас '''apply''' по кругам<br />
* Если нет, то проверяем наличие '''x1''', '''x2''', '''y1''', '''y2'''.<br />
* Если они есть, то проверка и результат.<br />
* Если их нет, то проверка идёт по шейпам объектов, и выдаётся результат/<br />
Если не будет стоять ни каких галочек, то проверка будет идти по шейпам объектов.<br />
<br />
<br />
Пусть, например, есть снаряд, который при помощи мышки надо кинуть в "тыкву". Если мы промахнулись, снаряд должен вернуться обратно, а с тыквой ничего не произойти. Если мы в тыкву попадаем, снаряд также возвращается, а тыква "взрывается":<br />
<pre><br />
<br />
<st id="trow"><br />
<init x="-350" y="150"/> // начальное положение<br />
<throw go="fly"/> // бросаем<br />
</st><br />
<br />
<st id="fly"><br />
<phys ay="100"/> // летим<br />
<apply y2="300" go="throw"/> // с землей<br />
<apply obj="тыква" rm="8" ro="10" st="bang"/> // с тыквой<br />
</st><br />
<br />
</pre><br />
<br />
== Условия ==<br />
<br />
=== if ===<br />
<br />
В состоянии может быть произвольное число команд if. Их номера (начиная с нуля) указываются<br />
в параметре if других команд. Эти номера можно соединять при помощи логических связок:<br />
* '''&''' - логическое '''и''' (вместо значка '''&''' можно использовать запятую ''',''');<br />
* '''|''' - логическое '''или''';<br />
* '''!''' - логическое '''не'''.<br />
Пример записи логического выражения в поле if некоторой команды: '''(1&2)|(3&(!4))''',<br />
что означает: выполняется if под номером 1 и под номером 2, или под номером 3 и не под номером 4.<br />
<br />
'''!!!Важно:''' нужно использовать полную скобочную структуру : "((1&2)&3)" - правильно, "1,2,3" - не правильно ( не гарантируется 100% адекватная работа).<br />
<br />
Логические связки используются также как математической логике или любом языке программирования. <br />
Так:<br />
* A '''&''' B - истинно, если истинны оба условия A и B;<br />
* A '''|''' B - истинно, если истинно хотя бы одно условие (или оба);<br />
* '''!''' А - истинно, если условие A ложно.<br />
Скобки в логическом выражении определяют приоритет (порядок) выполнения логических операций.<br />
Отметим несколько тождеств, справедливых при формировании логических высказываний:<br />
* !(A & B) = (!A) | (!B)<br />
* !(A | B) = (!A) & (!B)<br />
* !(!A) = A<br />
<br />
Если при формировании условия (ниже) есть несколько проверок, то они соединены логическим '''и'''.<br />
Т.е., если хотя бы одна из них не выполняется, то считается, что условие не выполнилось.<br />
<br />
Параметры команды:<br />
* '''obj''' - находится ли объект obj в состоянии st или имеет ли его параметр par значение val. В этом поле можно указать this, это значит что if будет проводить проверку текущего объекта. Добавлено это вместе с параметром clone. Клоны рождаются и умирают в рамках одного экрана. Для различия клонов между собой машина имеет уникальный параметр "clone_num" у оригинала = -1, у клонов от 0 до N, собственно с помощью this машина может сама себя проверить клон ли она и если да то какой у нее номер;<br />
* '''st''' - имя состояния в котором может находиться объект obj;<br />
* '''par''' - имя параметра объекта obj, значение которого сравнивается с полем val;<br />
* '''val''' - значение параметра par, которое проверяется у объекта obj;<br />
* '''val_txt''' - Значение текстового параметра объекта для проверки условия;<br />
* '''val_res''' - Значение ресурсного параметра объекта для проверки условия;<br />
* '''op''' - операция сравнения par op val. Если операции нет, то предполагается проверка на равенство par=val. Иначе используются операторы:<br />
** '''<''' - меньше (par < val);<br />
** '''>''' - больше (par > val);<br />
** '''!=''' - не равно (par != val);<br />
** '''<>''' - не равно (par <> val);<br />
** '''>=''' - больше или равно (par >= val);<br />
** '''<=''' - меньше или равно (par <= val);<br />
* '''curScr''' - если текущий экран совпадает с этим, то условие выполнилось;<br />
* '''prScr''' - если предыдущий экран совпадает с этим, то условие выполнилось;<br />
* '''wasScr''' - если был (когда либо) этот экран, то условие выполнилось.<br />
* '''buy''' - был ли куплен данный inn-app (проверяется флаг поля в объекте [[Options]]);<br />
* '''url''' - валиден (правилен и может быть запущен) ли данный интернет-адрес; на ios ссылка должна выглядеть так comabsolutisttwilighttown://, т.е. в конце ссылки добавляем ://<br />
* '''is_mus''' - играет ли сейчас музыка (значение 1);<br />
* '''guest''' - объект который установил состояние (используется вместо параметра obj). Если указанный объект не менял состояние этой машины, то условие не срабатывает.<br />
<br />
Если использовать obj, par, val, то будет происходить проверка на равенство значения параметра объекта и значения записанного в поле val.<br />
Если же использовать obj, par, op, val, то будет происходить проверка в соответствии с операцией сравнения значения параметра объекта и значения записанного в поле val.<br />
<br />
Для проверки текущего значения прозрачности у объекта можно воспользоваться параметром ''cur_al''<br />
<br />
У машины (другой или самой себя) можно проверить текущее состояние '''st''' и предыдущее состояние '''prev_st''', эти параметры живут на время сессии.<br />
<br />
== Математика ==<br />
<br />
=== Основные математические операции ===<br />
Математика в appsalute creator представлена 6-ю основными операциями: (плюс), (минус), (умножить), (поделить), (целочисленное деление), (остаток от деления) <br><br />
Организована благодаря совместному использованию '''[[#var|var]]''' и '''[[#set|set]]'''. <br />
[[Файл:Example_mod.png|300px|right|Пример использования операции остатка от деления]]<br />
''(плюс)'' '''+'''<br><br />
''(минус)'' '''-'''<br><br />
''(умножить)'' '''*'''<br><br />
''(поделить)'' '''/'''<br><br />
''(целочисленное деление)'' '''\'''<br><br />
''(остаток от деления)'' '''%'''<br><br />
<br><br />
Примеры использования последних двух операций:<br><br />
5\2=2<br><br />
5%2=1<br><br />
<br />
=== var ===<br />
Благодаря использованию '''[[#var|var]]''' существует возможность cчитать любой числовой параметр любого объекта. Например: x - координату какой-то машины, текущее значение любого объекта counter или timer и конечно же считывание значения любого параметра из опций! Каким образом это устроено? Рассмотрим подробнее '''[[#var|var]]''': <br><br />
[[Файл:VAR.png|right]]<br />
*'''name''' - здесь выбираем имя для нашей будущей переменной, которой будем оперировать далее<br />
*'''obj''' - выбирается объект, параметры которого мы хотим считать<br />
*'''par''' - параметр, который нужно вычитать из объекта, указанного выше<br />
*'''val''' - указывается числовое значение, которое будет установлено по умолчанию в случае отсутствия obj и par<br />
*'''user''' - если стоит "1", то будет считываться с текущего профиля в опциях<br />
На изображении справа можно наблюдать каким образом организован '''[[#var|var]]'''. В данном случае объявлена переменная x_cor, которая считывает x-координату объекта actor_1, при этом считывание переменной происходит из текущего профиля, так, как в поле user установлено значение равное "1".<br />
<br />
=== set ===<br />
[[Файл:SET.png|right]]<br />
Использование '''[[#var|var]]''' без '''[[#set|set]]''' не имеет смысла. Так, как переменная создается, но не используется дальше. Рассмотрим следующий пример, где вычитаем x - координату из одного объекта и сохраним ее в опции, предварительно увеличив ее на 50 единиц (в данном случае 50 пикселей).<br />
На рисунке справа можно наблюдать, каким образом это сделано. В состоянии '''init''' объявляется переменная '''x_cor''', которая считывает координату '''x''' из объекта '''actor_1''', таким образом в переменную '''x_cor''' запишется положение по '''x''' объекта '''actor_1'''. Поле '''user''' в данном случае в '''1''' не обязательно устанавливать, так как работа ведется с машинами, а не с опциями. Если бы на месте '''actor_1''' оказался объект '''options''', то это было бы просто необходимо, иначе программа считает значение не из профиля. Далее в '''[[#set|set]]''' выбран объект '''options''', в параметр '''x_position''' которого будет сохранятся значение переменной '''x_cor''' увеличенной на 50. В поле '''round''' идет округление вычисляемого значения, если оно установлено в 1. Поле '''user ''' установлено в 1, это значит, что параметр '''x_position''' будет сохранен в профиль. После это выполняется сохранение опций путем задания объекту '''options''' состояния '''save'''.<br><br />
! ! !ВАЖНО: чтобы выполнить какие-то действия с '''[[#var|var]]''' его обязательно нужно указывать в поле '''val''' в '''set''', при этом, если он используется, то все выражение должно стоять в скобках. Если в поле '''val''' не используется переменная, то скобки необязательны.<br />
<br><br />
<br><br />
Существует также возможность использовать '''[[#var|var]]''' совместно с '''[[#if|if]]''', а также '''[[#var|var]]''' с '''[[#move|move]]'''<br />
<br><br />
Так же добавилась возможность записывать значение переменной в состояние "st", что значительно уменьшает<br />
необходимость в записи 1000 if-ов. При этом, тип переменной в '''[[#var|var]]''' должен быть "строка".<br />
И добавилась возможность записи переменной boolean: ((a)==(b)). true = 1, false = 0. Довольно полезная вещь,<br />
если не хотите забивать "память" ненужной математикой.<br />
<br />
=== var и if ===<br />
[[Файл:IF.png|right]]<br />
При подробном рассмотрении '''[[#if|if]]''' можно заметить, что в нем есть поле '''val''', соответственно в этом поле можно указать переменную. Таким образом в поле '''val''' необязательно указывать константу, а можно указать какую-то переменную, которая может постоянно изменяться. Например, существует два объекта, один находится состоянии покоя, а другой находится в движении. При этом первый объект (тот, который в состоянии покоя) постоянно опрашивает положение второго объекта, и в случае, если у объекта, который движется, '''х''' координата равна '''х''' координате первого объекта, то первый объект входит в состояние, где он начинает свое движение. На рисунке показан объект, который находится в состоянии покоя, рассмотрим его состояния:<br><br />
В данном объекте существует два состояния: '''init''' и '''move'''. В '''init''' объект опрашивает другой объект и в случае, когда условие срабатывает, то переходит в состояние '''move''', где начинает свое движение.<br />
В '''init''' создаем переменную, в которую записываем положение по '''x''' объекта '''actor_2''', в '''if''' проверяется условие на соответствие координат объектов '''actor_1''' и '''actor_2''', в данном случае координата объекта '''actor_2''' представлена в виде переменной '''x_cor'''. Если условие выполняется, то происходит переход в состояние '''move''', если нет, то заново проходим состояние '''init''' и повторяем вышеописанную последовательность действий.<br />
<br><br />
<br><br />
<br><br />
<br><br />
<br />
=== var и move ===<br />
Также с помощью '''[[#var|var]]''' есть возможность указать целевые координаты в '''[[#move|move]]'''. То есть, не обязательно указывать целевые координаты в виде констант, их можно указать теперь с помощью переменных. При использовании '''[[#var|var]]''' и '''[[#move|move]]''' можно организовать обмен двух объектов местами с анимацией движения. Для этого необходимо определять какой объект нажат первым, а какой вторым, сохранять их координаты через объект '''options''' и только потом менять их местами. На рисунке можно увидеть, как это организовано.<br />
[[Файл:var_move.png|1000px|thumb|center|]]<br />
Рассмотрим подробнее состояние данной машины:<br />
<br><br />
* '''init'''<br><br />
В этом состоянии ожидаем клик на объект и обнуляем параметр, который отвечает за то, какой по счету объект сейчас нажат. Так, как при обмене объектов, если мы делаем это по клику, важно знать, по какому кликнули первым, а по какому вторым.<br />
* '''check'''<br><br />
Проверяется параметр '''number''', если он равен '''0''', то это значит, что еще ничего не кликали и мы переходим в состояние, где в опции записываются координаты этого объекта, который считается нажатым первым. Если не равен '''0''', то считается, что этот объект нажат вторым и переходит в состояние, где в опции записываются координаты этого объекта, который считается нажатым вторым по счету.<br />
* '''first_object'''<br><br />
В этом состоянии записываются координаты объекта в опции. Чтобы записать координаты в опции используются '''[[#var|var]]''' и '''[[#set|set]]''' упоминаемые выше. В опции координаты первого нажатого объекта сохраняются под параметрами '''x_first''' и '''y_first'''. В конце параметру '''number''' присваиваем значение '''1''', чтобы указать, что следующий нажатый объект будет вторым по счету. <br />
* '''second_object'''<br><br />
В этом состоянии объект будет в том случае, если он будет нажатым вторым по счету, то есть после состояния '''check''' объект попадет в это состояние, где он запишет свои текущие координаты под параметрами '''x_second''' и '''y_second'''. Запись координат происходит таким же самым образом, что и в состоянии '''first_object'''. После этого он автоматически переходит в следующее состояние.<br />
* '''move_first'''<br><br />
В этом состоянии объект будет в том случае, если он был нажат первым, поэтому он будет двигаться на место второго нажатого объекта, который сохранил свои координаты в параметры'''x_second''' и '''y_second'''. Движение происходит следующим образом: сперва в переменную вычитываем координаты второго объекта, а потом в '''move''' вместо целевых координат записываем переменные, которые обязательно должны быть взяты в скобки.<br />
* '''move_second'''<br><br />
В этом состоянии объект будет в том случае, если он был нажат вторым, поэтому он будет двигаться на место первого нажатого объекта, который сохранил свои координаты в параметры '''x_first''' и '''y_first'''. Движение происходит следующим образом: сперва в переменную вычитываем координаты первого объекта, а потом в '''move''' вместо целевых координат записываем переменные, которые обязательно должны быть взяты в скобки.<br />
<br />
В результате проделанных манипуляций с машинами по кликам на две машины, они обменяются местами с анимацией движения. Это может быть очень полезным во многих мини играх!!!<br />
<br />
=== Важно знать ===<br />
* Переменная действует в рамках одного состояния, если нужно, чтобы она была глобальной, нужно сохранить ее в опции и потом в нужный момент считывать ее из опций.<br />
* Если складываем два числа, то в поле '''val''' они должны быть записаны в скобках: (5+3).<br />
* Если возникает необходимость написать какое-то более сложное арифметическое вычисление, то следует помнить, что на одно действие приходятся одни скобки. Например: (((5+3)\2)*2).<br />
* Количество открывающих и закрывающих скобок должно быть одинаковым.<br />
* В скобках можно писать переменную, если она была объявлена выше: (5+a).<br />
* Переменная может состоять из цифр и букв и знака нижнего подчеркивания.<br />
* Иногда бывает необходимым использование '''round''' в '''set''', так например, если какой-то параметр получен с помощью арифметических вычислений и потом используется его в каком-то условии, и условие проверяет параметр, как целочисленное значение, то могут возникнуть ошибки. Так, как число будет записано в следующем виде 123.0000 и программа будет считать, что оно не целочисленное, а дробное. И чтобы избавится от лишних нулей в дробной части следует округлять число.<br />
* Действия, которые требуют времени, такие как move, rot, wait и другие перестают работать для уменьшения вычислительной нагрузки на устройство.<br />
* Действия, которые не требуют времени, такие как set, init и другие продолжают функционировать.<br />
<br />
<br />
<pre><br />
Если с помощью переменной менять объекту любой параметр, например, координату X, то она<br />
запомнится (запишется как значение по умолчанию).<br />
Тогда при повторном попадании на экран считается не тот X, который указан в свойствах,<br />
а тот, который установлен через переменную.<br />
Если нужно при ините экрана возвращать начальные значения параметров,<br />
то можно сделать это двумя способами:<br />
- не использовать переменную;<br />
- создать отдельное состояние, которое будет "вручную" устанавливать начальные значения<br />
параметрам при ините экрана.<br />
Если координата (или другой параметр) меняется другим способом, то будут автоматически<br />
при ините экрана подтягиваться значения из свойств объекта.<br />
</pre><br />
<br />
=== Примеры применений ===<br />
С помощью математики можно организовать следующее:<br />
* динамические опции (изменение звука и музыки с помощью ползунка);<br />
* анимацию каунтера в играх (по окончанию уровня можно наблюдать, как изменяются очки);<br />
* подсчет очков (гибкая система подсчета очков);<br />
* обмен объектов местами (использование var и move)<br />
* увеличение z-координаты любого объекта (когда необходимо, чтобы нажатый или таскаемый объект был выше других по z);<br />
* простейший калькулятор;<br />
* и много других.<br />
<br />
== Копирование машины состояния с сохранением ссылки на себя ==<br />
Довольно часто бывает, что машина состояний ссылается только на глобальные объекты и на саму себя. При этом, если мы просто скопируем объект, он будет ссылаться на свою предыдущую копию. Этого можно избежать, сделав 3 шага:<br />
1. Переместить объект в отдельную сцену<br />
2. Скопировать данную сцену(имеется в виду обычное копирование, без ссылки)<br />
3. Перенести объект и его копию обратно, в нужную сцену<br />
4. Созданные сцены можно удалить :)<br />
<br />
== Guest ==<br />
<br />
'''Guest (гость)''' - объект, который перевел машину в текущее состояние. Пример: кнопка ''btn1'' по клику переводит машину ''mch1'' в состояние ''st1'', в этом состоянии у машины ''mch1'' гостем является кнопка ''btn1''. Гостем может быть объект любого типа, если он может менять состояние другому объекту (например: хидден-объект по нахождению может менять состояние объекту, кнопка, машина, пэчворк и т.д.)<br />
<br />
В машине состояний можно считывать (проверять) и передавать параметры и состояния гостя. Любое поле ''obj'' в выпадающем списке содержит строку ''guest'', что позволяет работать с гостем, как с любым другим объектом.<br />
<br />
=== Пример использования ===<br />
<br />
[[Файл:Guest1.jpg|left]]<br />
Пускай экран содержит 3 кнопки (''btn1'', ''btn2'' и ''btn3'') и одну машину ''mch1''. Нужно сделать так, чтобы по клику на любую из кнопок машина перемещалась в ее координаты и переводила кнопку в состояние ''disable''. Так же по клику на кнопку ''btn2'', машина должна перейти в состояние ''bonus''.<br><br />
Всем трем кнопкам по клику пропишем передавать объекту ''mch1'' состояние ''check''.<br><br><br />
Создадим в машине три состояния: ''init'' - состояние в котором машина будет находиться по умолчанию, ''check'' - состояние, которое будет вызываться тремя кнопками, в этом состоянии у машины ''mch1'' одна из трех кнопок будет гостем, ''bonus'' - последнее состояние.<br><br />
Две команды ''var'' считывают у гостя координаты, т.к. мы не знаем, какая именно кнопка перевела машину ''mch1'' в состояние ''check'', то обращаемся к гостю, а не к кнопкам. За ними следует две команды ''set'', которые передают координаты гостя машине. Еще один ''set'' переводит гостя в состояние ''disable''. И через ''wait'' осуществляется переход в состояние ''bonus'', если гость ''btn2''.<br />
<br />
<pre><br />
При смене состояния гость сохраняется, т.е. в состоянии bonus гостем останется btn2.<br />
</pre><br />
<pre><br />
Если машина изначально сама себе меняет состояния, то у нее нет гостя.<br />
</pre><br />
<br />
[[Файл:Guest2.jpg]]<br />
<br />
== Массив (Array) ==<br />
<br />
В данном объекте реализован массив, имеющий максимальную длину в 20 элементов.<br />
<br />
=== Свойства объекта массив: ===<br />
<br />
len - длинна массива. Длинна массива может как считываться, так и записываться. Влияет на количество сохраняемых объектов в Options.<br />
<br />
index1 - индекс элемента. (данный массив можно расширить до многомерного и использовать несколько индексов)<br />
<br />
val - значение элемента массива, с индексом index1<br />
<br />
a1..a20 - внутренние элементы массива(обращаться можно через свойство par объекта). Предполагается, что пользователь редактора к ним обращаться напрямую не будет, однако иногда для удобства полезны.<br />
<br />
=== Состояния объекта массив: ===<br />
<br />
get - при вызове этого состояния во внутреннюю переменную val записывается значение элемента с индексом index1<br />
<br />
set - при вызове этого состояния во внутреннюю переменную a1..a20, соответствующую индексу index1 записывается значение val<br />
<br />
load - загрузить значения массива из xml.<br />
<br />
save - сохранить элементы массива от 1 до len<br />
<br />
=== Как использовать? ===<br />
<br />
1. Загружаем массив, переводя объект array в состояние load<br />
<br />
2. Записываем значения массива<br />
<br />
а). Задаём значение свойству index1 объекта array (устанавливаем индекс ячейки, в которую будет заноситься число)<br />
б). Задаём значение свойству val объекта array (устанавливаем значение, которое будет заноситься в ячейку<br />
с индексом index1)<br />
в). Переводим объект array в состояние set<br />
<br />
3. Считываем значения массива<br />
а). Задаём значение свойству index1 объекта array (устанавливаем индекс ячейки, из которой будет считываться число)<br />
б). Переводим объект array в состояние get<br />
в). Считываем значение из свойства val объекта array<br />
<br />
4. Сохраняем массив, переводя объект array в состояние save. Если хотите изменить количество сохраняемых элементов - предварительно измените параметр len.<br />
<br />
=== Копирование объекта ===<br />
<br />
При копировании, необходимо заменить в состояниях load и save array.имя_параметра на другое имя. Например, array2.имя_параметра. Копировать следует через использование доп. сцены (см. выше)<br />
<br />
=== Достоинства ===<br />
<br />
Позволяет избежать необходимости каждый раз создавать большое количество if-ов и set-ов, если необходимо работать с нумерованным списком. Можно один раз создать структуру и копировать её неограниченное количество раз<br />
<br />
=== Недостатки ===<br />
<br />
Данный объект содержит довольно большое количество кода, поэтому при большом их обилии/длине может занизить скорость работы сцены и скорость загрузки сцены.<br />
<br />
=== Исходный XML код===<br />
Прим. id="369" - идентификатор объекта Options, сохраняющего все переменные приложения. id="7845" - идентификатор объекта<br />
<br />
<pre><br />
<obj id="7845" type="machine" nm="array" sync="1" w="1" h="1"><br />
<st id="init"/><br />
<st id="get"><br />
<var nm="a1" obj="7845" par="a1"/><br />
<var nm="a2" obj="7845" par="a2"/><br />
<var nm="a3" obj="7845" par="a3"/><br />
<var nm="a4" obj="7845" par="a4"/><br />
<var nm="a5" obj="7845" par="a5"/><br />
<var nm="a6" obj="7845" par="a6"/><br />
<var nm="a7" obj="7845" par="a7"/><br />
<var nm="a8" obj="7845" par="a8"/><br />
<var nm="a9" obj="7845" par="a9"/><br />
<var nm="a10" obj="7845" par="a10"/><br />
<var nm="a11" obj="7845" par="a11"/><br />
<var nm="a12" obj="7845" par="a12"/><br />
<var nm="a13" obj="7845" par="a13"/><br />
<var nm="a14" obj="7845" par="a14"/><br />
<var nm="a15" obj="7845" par="a15"/><br />
<var nm="a16" obj="7845" par="a16"/><br />
<var nm="a17" obj="7845" par="a17"/><br />
<var nm="a18" obj="7845" par="a18"/><br />
<var nm="a19" obj="7845" par="a19"/><br />
<var nm="a20" obj="7845" par="a20"/><br />
<set obj="7845" par="val" val="(a1)" round="1" if="0"/><br />
<set obj="7845" par="val" val="(a2)" round="1" if="1"/><br />
<set obj="7845" par="val" val="(a3)" round="1" if="2"/><br />
<set obj="7845" par="val" val="(a4)" round="1" if="3"/><br />
<set obj="7845" par="val" val="(a5)" round="1" if="4"/><br />
<set obj="7845" par="val" val="(a6)" round="1" if="5"/><br />
<set obj="7845" par="val" val="(a7)" round="1" if="6"/><br />
<set obj="7845" par="val" val="(a8)" round="1" if="7"/><br />
<set obj="7845" par="val" val="(a9)" round="1" if="8"/><br />
<set obj="7845" par="val" val="(a10)" round="1" if="9"/><br />
<set obj="7845" par="val" val="(a11)" round="1" if="10"/><br />
<set obj="7845" par="val" val="(a12)" round="1" if="11"/><br />
<set obj="7845" par="val" val="(a13)" round="1" if="12"/><br />
<set obj="7845" par="val" val="(a14)" round="1" if="13"/><br />
<set obj="7845" par="val" val="(a15)" round="1" if="14"/><br />
<set obj="7845" par="val" val="(a16)" round="1" if="15"/><br />
<set obj="7845" par="val" val="(a17)" round="1" if="16"/><br />
<set obj="7845" par="val" val="(a18)" round="1" if="17"/><br />
<set obj="7845" par="val" val="(a19)" round="1" if="18"/><br />
<set obj="7845" par="val" val="(a20)" round="1" if="19"/><br />
<if obj="7845" par="index1" val="1"/><br />
<if obj="7845" par="index1" val="2"/><br />
<if obj="7845" par="index1" val="3"/><br />
<if obj="7845" par="index1" val="4"/><br />
<if obj="7845" par="index1" val="5"/><br />
<if obj="7845" par="index1" val="6"/><br />
<if obj="7845" par="index1" val="7"/><br />
<if obj="7845" par="index1" val="8"/><br />
<if obj="7845" par="index1" val="9"/><br />
<if obj="7845" par="index1" val="10"/><br />
<if obj="7845" par="index1" val="11"/><br />
<if obj="7845" par="index1" val="12"/><br />
<if obj="7845" par="index1" val="13"/><br />
<if obj="7845" par="index1" val="14"/><br />
<if obj="7845" par="index1" val="15"/><br />
<if obj="7845" par="index1" val="16"/><br />
<if obj="7845" par="index1" val="17"/><br />
<if obj="7845" par="index1" val="18"/><br />
<if obj="7845" par="index1" val="19"/><br />
<if obj="7845" par="index1" val="20"/><br />
</st><br />
<st id="set"><br />
<var nm="val" obj="7845" par="val"/><br />
<set obj="7845" par="a1" val="(val)" round="1" if="0"/><br />
<set obj="7845" par="a2" val="(val)" round="1" if="1"/><br />
<set obj="7845" par="a3" val="(val)" round="1" if="2"/><br />
<set obj="7845" par="a4" val="(val)" round="1" if="3"/><br />
<set obj="7845" par="a5" val="(val)" round="1" if="4"/><br />
<set obj="7845" par="a6" val="(val)" round="1" if="5"/><br />
<set obj="7845" par="a7" val="(val)" round="1" if="6"/><br />
<set obj="7845" par="a8" val="(val)" round="1" if="7"/><br />
<set obj="7845" par="a9" val="(val)" round="1" if="8"/><br />
<set obj="7845" par="a10" val="(val)" round="1" if="9"/><br />
<set obj="7845" par="a11" val="(val)" round="1" if="10"/><br />
<set obj="7845" par="a12" val="(val)" round="1" if="11"/><br />
<set obj="7845" par="a13" val="(val)" round="1" if="12"/><br />
<set obj="7845" par="a14" val="(val)" round="1" if="13"/><br />
<set obj="7845" par="a15" val="(val)" round="1" if="14"/><br />
<set obj="7845" par="a16" val="(val)" round="1" if="15"/><br />
<set obj="7845" par="a17" val="(val)" round="1" if="16"/><br />
<set obj="7845" par="a18" val="(val)" round="1" if="17"/><br />
<set obj="7845" par="a19" val="(val)" round="1" if="18"/><br />
<set obj="7845" par="a20" val="(val)" round="1" if="19"/><br />
<if obj="7845" par="index1" val="1"/><br />
<if obj="7845" par="index1" val="2"/><br />
<if obj="7845" par="index1" val="3"/><br />
<if obj="7845" par="index1" val="4"/><br />
<if obj="7845" par="index1" val="5"/><br />
<if obj="7845" par="index1" val="6"/><br />
<if obj="7845" par="index1" val="7"/><br />
<if obj="7845" par="index1" val="8"/><br />
<if obj="7845" par="index1" val="9"/><br />
<if obj="7845" par="index1" val="10"/><br />
<if obj="7845" par="index1" val="11"/><br />
<if obj="7845" par="index1" val="12"/><br />
<if obj="7845" par="index1" val="13"/><br />
<if obj="7845" par="index1" val="14"/><br />
<if obj="7845" par="index1" val="15"/><br />
<if obj="7845" par="index1" val="16"/><br />
<if obj="7845" par="index1" val="17"/><br />
<if obj="7845" par="index1" val="18"/><br />
<if obj="7845" par="index1" val="19"/><br />
<if obj="7845" par="index1" val="20"/><br />
</st><br />
<st id="load"><br />
<var nm="a1" obj="369" par="array.a1" user="1"/><br />
<var nm="a2" obj="369" par="array.a2" user="1"/><br />
<var nm="a3" obj="369" par="array.a3" user="1"/><br />
<var nm="a4" obj="369" par="array.a4" user="1"/><br />
<var nm="a5" obj="369" par="array.a5" user="1"/><br />
<var nm="a6" obj="369" par="array.a6" user="1"/><br />
<var nm="a7" obj="369" par="array.a7" user="1"/><br />
<var nm="a8" obj="369" par="array.a8" user="1"/><br />
<var nm="a9" obj="369" par="array.a9" user="1"/><br />
<var nm="a10" obj="369" par="array.a10" user="1"/><br />
<var nm="a11" obj="369" par="array.a11" user="1"/><br />
<var nm="a12" obj="369" par="array.a12" user="1"/><br />
<var nm="a13" obj="369" par="array.a13" user="1"/><br />
<var nm="a14" obj="369" par="array.a14" user="1"/><br />
<var nm="a15" obj="369" par="array.a15" user="1"/><br />
<var nm="a16" obj="369" par="array.a16" user="1"/><br />
<var nm="a17" obj="369" par="array.a17" user="1"/><br />
<var nm="a18" obj="369" par="array.a18" user="1"/><br />
<var nm="a19" obj="369" par="array.a19" user="1"/><br />
<var nm="a20" obj="369" par="array.a20" user="1"/><br />
<set obj="7845" par="a1" val="(a1)" round="1" if="0"/><br />
<set obj="7845" par="a2" val="(a2)" round="1" if="1"/><br />
<set obj="7845" par="a3" val="(a3)" round="1" if="2"/><br />
<set obj="7845" par="a4" val="(a4)" round="1" if="3"/><br />
<set obj="7845" par="a5" val="(a5)" round="1" if="4"/><br />
<set obj="7845" par="a6" val="(a6)" round="1" if="5"/><br />
<set obj="7845" par="a7" val="(a7)" round="1" if="6"/><br />
<set obj="7845" par="a8" val="(a8)" round="1" if="7"/><br />
<set obj="7845" par="a9" val="(a9)" round="1" if="8"/><br />
<set obj="7845" par="a10" val="(a10)" round="1" if="9"/><br />
<set obj="7845" par="a11" val="(a11)" round="1" if="10"/><br />
<set obj="7845" par="a12" val="(a12)" round="1" if="11"/><br />
<set obj="7845" par="a13" val="(a13)" round="1" if="12"/><br />
<set obj="7845" par="a14" val="(a14)" round="1" if="13"/><br />
<set obj="7845" par="a15" val="(a15)" round="1" if="14"/><br />
<set obj="7845" par="a16" val="(a16)" round="1" if="15"/><br />
<set obj="7845" par="a17" val="(a17)" round="1" if="16"/><br />
<set obj="7845" par="a18" val="(a18)" round="1" if="17"/><br />
<set obj="7845" par="a19" val="(a19)" round="1" if="18"/><br />
<set obj="7845" par="a20" val="(a20)" round="1" if="19"/><br />
<if obj="7845" par="len" op="&gt;" val="0"/><br />
<if obj="7845" par="len" op="&gt;" val="1"/><br />
<if obj="7845" par="len" op="&gt;" val="2"/><br />
<if obj="7845" par="len" op="&gt;" val="3"/><br />
<if obj="7845" par="len" op="&gt;" val="4"/><br />
<if obj="7845" par="len" op="&gt;" val="5"/><br />
<if obj="7845" par="len" op="&gt;" val="6"/><br />
<if obj="7845" par="len" op="&gt;" val="7"/><br />
<if obj="7845" par="len" op="&gt;" val="8"/><br />
<if obj="7845" par="len" op="&gt;" val="9"/><br />
<if obj="7845" par="len" op="&gt;" val="10"/><br />
<if obj="7845" par="len" op="&gt;" val="11"/><br />
<if obj="7845" par="len" op="&gt;" val="12"/><br />
<if obj="7845" par="len" op="&gt;" val="13"/><br />
<if obj="7845" par="len" op="&gt;" val="14"/><br />
<if obj="7845" par="len" op="&gt;" val="15"/><br />
<if obj="7845" par="len" op="&gt;" val="16"/><br />
<if obj="7845" par="len" op="&gt;" val="17"/><br />
<if obj="7845" par="len" op="&gt;" val="18"/><br />
<if obj="7845" par="len" op="&gt;" val="19"/><br />
</st><br />
<st id="save"><br />
<var nm="len" obj="7845" par="len"/><br />
<var nm="a1" obj="7845" par="a1"/><br />
<var nm="a2" obj="7845" par="a2"/><br />
<var nm="a3" obj="7845" par="a3"/><br />
<var nm="a4" obj="7845" par="a4"/><br />
<var nm="a5" obj="7845" par="a5"/><br />
<var nm="a6" obj="7845" par="a6"/><br />
<var nm="a7" obj="7845" par="a7"/><br />
<var nm="a8" obj="7845" par="a8"/><br />
<var nm="a9" obj="7845" par="a9"/><br />
<var nm="a10" obj="7845" par="a10"/><br />
<var nm="a11" obj="7845" par="a11"/><br />
<var nm="a12" obj="7845" par="a12"/><br />
<var nm="a13" obj="7845" par="a13"/><br />
<var nm="a14" obj="7845" par="a14"/><br />
<var nm="a15" obj="7845" par="a15"/><br />
<var nm="a16" obj="7845" par="a16"/><br />
<var nm="a17" obj="7845" par="a17"/><br />
<var nm="a18" obj="7845" par="a18"/><br />
<var nm="a19" obj="7845" par="a19"/><br />
<var nm="a20" obj="7845" par="a20"/><br />
<set obj="369" par="array.a1" val="(a1)" round="1" user="1" if="0"/><br />
<set obj="369" par="array.a2" val="(a2)" round="1" user="1" if="1"/><br />
<set obj="369" par="array.a3" val="(a3)" round="1" user="1" if="2"/><br />
<set obj="369" par="array.a4" val="(a4)" round="1" user="1" if="3"/><br />
<set obj="369" par="array.a5" val="(a5)" round="1" user="1" if="4"/><br />
<set obj="369" par="array.a6" val="(a6)" round="1" user="1" if="5"/><br />
<set obj="369" par="array.a7" val="(a7)" round="1" user="1" if="6"/><br />
<set obj="369" par="array.a8" val="(a8)" round="1" user="1" if="7"/><br />
<set obj="369" par="array.a9" val="(a9)" round="1" user="1" if="8"/><br />
<set obj="369" par="array.a10" val="(a10)" round="1" user="1" if="9"/><br />
<set obj="369" par="array.a11" val="(a11)" round="1" user="1" if="10"/><br />
<set obj="369" par="array.a12" val="(a12)" round="1" user="1" if="11"/><br />
<set obj="369" par="array.a13" val="(a13)" round="1" user="1" if="12"/><br />
<set obj="369" par="array.a14" val="(a14)" round="1" user="1" if="13"/><br />
<set obj="369" par="array.a15" val="(a15)" round="1" user="1" if="14"/><br />
<set obj="369" par="array.a16" val="(a16)" round="1" user="1" if="15"/><br />
<set obj="369" par="array.a17" val="(a17)" round="1" user="1" if="16"/><br />
<set obj="369" par="array.a18" val="(a18)" round="1" user="1" if="17"/><br />
<set obj="369" par="array.a19" val="(a19)" round="1" user="1" if="18"/><br />
<set obj="369" par="array.a20" val="(a20)" round="1" user="1" if="19"/><br />
<set obj="369" par="array.len" val="(len)" round="1" user="1"/><br />
<if obj="7845" par="len" op="&gt;" val="0"/><br />
<if obj="7845" par="len" op="&gt;" val="1"/><br />
<if obj="7845" par="len" op="&gt;" val="2"/><br />
<if obj="7845" par="len" op="&gt;" val="3"/><br />
<if obj="7845" par="len" op="&gt;" val="4"/><br />
<if obj="7845" par="len" op="&gt;" val="5"/><br />
<if obj="7845" par="len" op="&gt;" val="6"/><br />
<if obj="7845" par="len" op="&gt;" val="7"/><br />
<if obj="7845" par="len" op="&gt;" val="8"/><br />
<if obj="7845" par="len" op="&gt;" val="9"/><br />
<if obj="7845" par="len" op="&gt;" val="10"/><br />
<if obj="7845" par="len" op="&gt;" val="11"/><br />
<if obj="7845" par="len" op="&gt;" val="12"/><br />
<if obj="7845" par="len" op="&gt;" val="13"/><br />
<if obj="7845" par="len" op="&gt;" val="14"/><br />
<if obj="7845" par="len" op="&gt;" val="15"/><br />
<if obj="7845" par="len" op="&gt;" val="16"/><br />
<if obj="7845" par="len" op="&gt;" val="17"/><br />
<if obj="7845" par="len" op="&gt;" val="18"/><br />
<if obj="7845" par="len" op="&gt;" val="19"/><br />
</st><br />
</obj><br />
</pre><br />
<br />
=== Машина состояний объекта ===<br />
[[Файл:array.jpg]]<br />
<br />
<br />
== Пример использования ==<br />
<br />
[http://fs5.absolutist.com/files/wikisample/machine.rar Download]<br />
<br />
== Clone ==<br />
Clone - параметр команды init в разделе "системные действия".<br />
<br />
[[Файл:Clone1.PNG]]<br />
<br />
<br />
Значение 1 означает, что в текущем местоположении машины будет создана ее копия.<br />
<br />
[[Файл:Clone2.PNG]]<br />
<br />
=== Свойства ===<br />
<br />
1) Клонированная машина состояний имеет все свойства, состояния и параметры исходного объекта клонирования.<br />
<br />
2) Клоны рождаются и умирают в рамках одного экрана.<br />
<br />
3) Клоны отличаются друг от друга лишь параметром '''clone_num''', который у оригинала равен "-1", а у клонов от 0 до N.<br />
<br />
4) Нежелательно применять клонирование к клону во избежание путаницы значений параметра '''clone_num'''.<br />
<br />
5) Если при проверке условия [[#if|if]] в поле '''obj''' указать this, это значит что if будет проводить проверку текущего объекта. Таким образом машина может сама себя проверить по параметру '''clone_num''' клон ли она и если да то какой у нее номер;<br />
<br />
=== Пример использования ===<br />
<br />
По ссылке пример использования с подробным описанием машин.<br />
<br />
[http://fs5.absolutist.com/files/wikisample/Clone.zip Download]<br />
<br />
== Параметр команды машины состояний ==<br />
<br />
В случае, когда необходимо изменить значение какого-либо параметра в командах машины состояний (например v в команде move) в процессе работы приложения, можно использовать блок "Параметр команды машины состояний" в команде ''set'' машины состояний. Приведу пример использования этого блока.<br />
<br />
Пусть есть 2 машины: управляющая и управляемая.<br />
<br />
[[Файл:Stm1.jpg|300px]][[Файл:Stm2.jpg|300px]]<br />
<br />
Управляемая машина практически пустая и не содержит каких либо данных о движении, но тем не менее при запуске она будет двигаться, меняя направление. Это движение - заслуга управляющей машины, которая на ходу изменяет параметры движения управляемой. Рассмотрим более детально ее состояния.<br />
<br />
В первом состоянии "wait" мы пытаемся изменить скорость движения управляемой машины. Для этого указали объект (sun), состояние в котором хотим поменять параметр (у машины sun это состояние move), имя команды в которой меняем параметр (в данном случае это move), номер команды (если таких команд несколько, то нужно указать порядковый номер начиная с 0; в нашем случае команда одна), имя параметра (мы хотим изменить скорость, поэтому имя параметра v) и значение (указали значение 200). После этого переходим в следующее состояние.<br />
<br />
В состоянии "1" управляющей машины сначала мы вывели объект sun из состояния move, изменили параметр целевой координаты x на 512 и затем вернули в состояние move, чтобы применить изменения параметров. Таким образом управляемая машина начала движение в x=512 со скоростью 200. Через 2 секунды мы переводим управляющую машину в состояние "2", где аналогичным образом изменяется целевая координата на -512.<br />
<br />
Такой способ задания параметров может найти применение в случае, когда параметры нужно задавать переменными.<br />
<br />
==Запись в viewer.log ==<br />
<br />
Во время работы приложения, машина состояний может писать информацию о своей работе в viewer.log. Для этого параметр '''Level''', в разделе '''[GameTrace]''' файла '''app.icf''' должен быть выставлен в значение '''Verbose'''.<br />
<br />
При этом нужно иметь ввиду, что приложение работает более медленно, чем при обычном использовании. При настройке процессов, привязанных к времени (анимация и т.д.) логирование нужно отключать, путем установки флага '''Level''' в значение '''Info'''.<br />
<br />
Ниже приведен пример записи из viewer.log. Жирным шрифтом выделено полезную информацию. <br />
<br />
*Machine::state() state machine '''stat_google_gold (id:30818)''' from '''enough_coins''' to '''enough_coins''' through object '''c_current_gold (id:8807)''' from state '''inc''' - машина с именем и id: '''stat_google_gold (id:30818)''' перешла из состояния: '''enough_coins''' в: '''enough_coins'''; ее состояние изменил объект с именем и id: '''c_current_gold (id:8807)''' из состояния: '''inc'''.<br />
*GMachine::Set::init() GMachine'''(id:28076)'''::Set::init '''set id:17''' - машина с id '''(id:28076)''' начала выполнять команду '''set id:17'''; сначала проверяется истинно ли условие выполнения команды (if).<br />
*GMachine::Command::calcExpr() GMachine::Command::calcExpr ((0|(!1))|(!2)) '''checkIf(0)=no''' - имеем некоторое сложное условие, проверяем его составляющие; if(0) не выполняется (имеет значение false).<br />
*GMachine::Command::calcExpr() GMachine::Command::calcExpr ((0|(!1))|(!2)) '''checkIf(1)=yes''' - условие if(1) выполняется (имеет значение true).<br />
*GMachine::Command::calcExpr() GMachine::Command::calcExpr ((0|(!1))|(!2)) '''checkIf(2)=yes''' - условие if(2) выполняется (имеет значение true).<br />
*GMachine::Command::checkIf() GMachine'''(id:28076)'''::Command::'''checkIf id:17 expr:((0|(!1))|(!2)) res:false''' - проверяется все выражение; общий результат false, set(17) не выполняется.<br />
*GMachine::Set::init() GMachine'''(id:28076)'''::Set::init '''set id:18''' - машина с id '''(id:28076)''' начала выполнять команду '''set id:18''', в данном set условие if отсутствует.<br />
*GMachine::Command::checkIf() GMachine'''(id:28076)'''::Command::'''checkIf id:18 expr: res:true''' - в команде set(18) условие '''checkIf id:18 expr: res:true''' есть истинно (точнее - не есть ложным, так как оно отсутствует); set(18) будет выполнен.<br />
*GMachine::Set::init() GMachine'''(id:28076)'''::Set::init '''set id:18 checkIf success''' - проверка условия прошла успешно, выполняем set(18).<br />
*GMachine::Set::init() GMachine'''(id:28076)'''::Set::init '''set id:18 obj:16039 -> par:param_name val:bundle_coins us:0''' - результат выполнения set(18) - объекту '''obj:16039''' устанавливаем параметр '''par:param_name val:bundle_coins''' равным '''us:0'''.<br />
*GMachine::Command::getVarValue() Command::'''getVarValue(bundle_item): float result = 0.00''' - вычитываем переменную с помощью команды var; вычитываем параметр '''bundle_item''', результат операции '''float result = 0.00'''.<br />
*GMachine::Set::init() Set::init: Expression: '''(bundle_coins)=0.000000(float)''' - используем значение переменной в команде set; переменная вчитывается в момент обращения к ней из другой команды (set, move и др.).<br />
<br />
==Использование скриптов Lua ==<br />
В машине состояний можно использовать скрипты [[Lua]]<br />
<br />
<br />
==Окно==<br />
В свойствах машины состояний есть 2 новых поля:<br />
*'''окно''' - если ''да'', то машина считает себя окном. При включении данного параметра с момента постановки окна в очередь ''statesmanager'а'' и до вызова ''back'' в текущей машине блокируются внешние воздействия и переход между состояниями.<br />
*'''тип окна''' - обычное; по альфе - при открытии отключает все нижние сцены по альфе; с фото - при открытии отключает все нижние сцены по альфе, предварительно делая фото этих сцен. Выключение сцен ''по альфе'' и ''с фото'' используются для больших окон основной очереди.<br />
[[mwindow]]<br />
<br />
[[Category:Main objects]]</div>Alexeevhttps://wiki.appsalutecreator.com/index.php?title=Edit&diff=8994Edit2017-07-20T13:24:16Z<p>Alexeev: /* Пример */</p>
<hr />
<div>{{TOC right}}[[Файл:Edit2.png|right]]<br />
'''Edit''' - [[Object|объект]], который используется для ввода текста с клавиатуры.<br />
<br />
Этот объект чаще всего используется для создания системы регистрации пользователей.<br />
<br />
== Основные параметры ==<br />
<br />
'''Группа - Параметры приветствия'''<br />
<br />
*'''текстID''' - Выводимый текст приветствия, перетаскивается из ресурса тектстов. <br />
<br />
*'''текст''' - Выводимый текст приветствия, без использования базы тектовых ресурсов.<br />
<br />
'''Группа - форматирования'''<br />
<br />
*'''dx''' - Бордюр (отступ текста слева и справа от границы прямоугольника объекта).<br />
<br />
*'''dy''' - Бордюр (отступ текста сверху и снизу от границы прямоугольника объекта).<br />
<br />
*'''отступ''' - Вертикальное расстояние между строчками в пикселях<br />
<br />
*'''поз. гориз.''' - Горизонтальное выравнивание текста (0 - нет выравнивания; 1 - прижать к левому краю; 2 - центр; 3 - к правому).<br />
<br />
*'''поз. верт.''' - Вертикальное выравнивание текста (0 - нет выравнивания; 1 - прижать к верхнему краю; 2 - центр; 3 - к нижнему).<br />
<br />
'''Группа - Параметры используемого шрифта'''<br />
<br />
*'''размер''' - Размер шрифта в поинтах. <br />
<br />
*'''цвет текста норм.''' - Цвет текста без ошибок (черный по умолчанию)<br />
<br />
*'''цвет текста с ошибкой''' - Цвет текста с ошибкой (красный по умолчанию)<br />
<br />
'''Группа - Дополнительные параметры'''<br />
<br />
*'''обработка - пустое поле ввода''' - изменяет состояние объекта, если поле ввода пустое. Это удобно использовать для запрета какого-то действия, пока не будет заполнено поле ввода.<br />
<br />
*'''обработка - НЕ пустое поле ввода''' - изменяет состояние объекта, если поле ввода заполнено. Это удобно использовать для разрешения какого-то действия, если заполнено поле ввода.<br />
== Добавляемые параметры ==<br />
<br />
[[Файл:edit3.png|right]]<br />
Меню выбора ''Добавляемые параметры'' к объектам активируется по нажатию правой кнопки мыши.<br />
<br />
<br />
[[Файл:+.png]] '''обработка - пустое поле ввода''' - Когда поле ввода станет пустым будет изменено состояние заданного объекта.<br />
*'''объект''' - Когда поле ввода станет пустым, перевести объект в состояние из следующего поля.<br />
*'''состояние''' - Новое состояние для объекта из предыдущего поля.<br />
<br />
[[Файл:+.png]] '''обработка - НЕпустое поле ввода''' - Когда поле ввода станет непустым будет изменено состояние заданного объекта.<br />
*'''объект''' - Когда поле ввода станет непустым, перевести объект в состояние из следующего поля.<br />
*'''состояние''' - Новое состояние для объекта из предыдущего поля.<br />
<br />
[[Файл:+.png]] '''обработка - нажат Enter''' - Когда будет нажата клавиша Enter изменим состояние заданного объекта.<br />
*'''объект''' - Когда будет нажата клавиша Enter, перевести объект в состояние из следующего поля.<br />
*'''состояние''' - Новое состояние для объекта из предыдущего поля.<br />
<br />
== Состояния ==<br />
<br />
*'''show''' - показать клавиатуру<br />
<br />
*'''hide''' - спрятать клавиатуру<br />
<br />
==Пример==<br />
[[Файл:Tedit2.png|right]]<br />
<br />
В машинах состояний мы можем использовать параметр ''text'' он позволяет считывать текущее имя игрока. С помощью этого параметра, можно записать в переменную типа "строка" текущее имя игрока для дальнейшей обработки (вывод на экран, проверка условий и т.д.). Например: проверка ввода логина и пароля.<br />
<br />
<br />
Пример, как с помощью поля Edit создавать профили игроков (используются объекты типа Options и Table)<br />
<br />
В объекте Options в поле ''Поле ввода'' указываем объект Edit, в графе''Таблица'' указываем таблицу, в которую будут записываться данные из Edit. <br />
<br />
На рисунке ниже изображен пример использования объекта типа Edit. На экране синее поле - это подложка поверх которой расположен объект Edit. Ниже поля ввода находится таблица, которая будет отображать все ранее созданные профили. Под таблицей находятся две кнопки: справа - кнопка которая создает новый профили или меняет на ранее созданный, слева - кнопка-отмена, которая осуществляет выход с экрана. Во время запуска приложения в поле ввода отображается приветствие.<br />
<br />
После введения в поле edit имени игрока необходимо с помощью машины или кнопки передать объекту Options последовательно состояния add и update. Тогда новый игрок добавиться в таблицу (т.е. создастся новый профиль). Чтобы выбрать один из уже созданных профилей, необходимо выбрать его курсором в таблице, затем передать опциям состояния change и update последовательно. Тогда произойдет смена профиля, на один из тех, которые были созданы ранее.<br />
<br />
'''В объект Text, в который будет выводиться имя пользователя, нужно ОБЯЗАТЕЛЬНО в поле text ввести строку "name" (без кавычек)!!!'''<br />
<br />
[[Файл:Edit1.jpg]]<br />
<br />
[[Category:Options]]</div>Alexeevhttps://wiki.appsalutecreator.com/index.php?title=Isomover&diff=8852Isomover2017-06-26T12:35:20Z<p>Alexeev: /* Добавляемые параметры */</p>
<hr />
<div>'''Isomover''' - [[Object|объект]] используется для осуществления движения и взаимодействия в изометрической карте. <br />
<br />
Isomover обязательно должен быть подобъектом [[isomap]]. <br />
<br />
В проекте с картой ([[isomap]]) и движущимися по ней объектами (isomover) часто используют [[economics]] и [[eitems]] потому, что для завершения процессов часто требуется применить предмет или ресурс.<br />
<br />
Начало движения множества изомуверов сильно нагружает систему, поэтому следует позаботиться, чтобы это происходило не в один момент времени. По возможности добавляйте небольшую и различную паузу каждому изомуверу перед стартом.<br><br><br />
==Основные параметры==<br />
*'''Положение''' (''x'',''y'') - рекомендуется выносить isomover-объекты за пределы карты. Иначе, если объект должен появляться не сразу, то он будет просто стоять без движения<br />
*'''Память''' - всегда должно быть значение 1, обязательное условие корректной работы. Это позволяет объекту двигаться последовательно, не инициализируясь после каждого движения в исходной точке<br />
*'''тип ребра min''' (''edge_t_min'') - перемещаться по ребрам не ниже заданного, -1 не проверять<br />
*'''тип ребра max''' (''edge_t_max'') - перемещаться по ребрам не выше заданного, -1 не проверять. Типы ребер задаются в isomap<br />
*'''Старт''' (''start'') - точка старта, выбирается из списка точек Isomap<br />
*'''Финиш''' (''finish'') - точка финиша, выбирается из списка точек Isomap<br />
*'''Скорость (макс)''' (''vel_max'') - максимальная скорость, с которой передвигается объект Isomover<br />
*'''Скорость''' (''vel'') - не использовать, вычисляется по формуле автоматически, позже будет скрыто. V = Vmax*(k+(1-k)*(P/Pmax))<br />
*'''Жизнь (макс)''' (''pow_max'') - максимальная жизнь<br />
*'''Жизнь''' (''pow'') - текущая жизнь, высчитывается по формуле автоматически<br />
*'''Сохранять жизнь в опции''' (''powsave'') - если да, то объекты сцены сохранят уровень жизни при выходе со сцены и возвращении на нее<br />
*'''Коэффициент скорости''' (''speed_k'') - коэффициент k в формуле расчета скорости. Чтобы скорость не зависела от значения жизни - указываем speed_k = 1<br />
*'''Менять угол''' (''fixangle'') - изменение угла для предания плавности смены графики при дугообразном перемещении объекта. С появлением 3D-объектов больше не используется<br />
*'''Тип''' (''mtype'') - объекты можно разделять на типы (люди, монстры, звери и т.д.). Взаимодействие происходит между объектами разных типов, настраивается в добавляемых параметрах<br />
*'''Радиус''' (''mradius'') - значения радиуса. Попадание изомувера другого типа в этот радиус позволит начать взаимодействие.<br />
*'''Цель при действии''' (''mtarget'') - мувер может быть целью взаимодействия пока сам действует<br />
*'''Запретить действие''' (''disact'') - мувер не сможет перейти из acting_wait в acting<br />
*'''Время появления''' (''appear_time'') - время в миллисекундах появления и исчезания изомувера (длительность перехода по alpha)<br />
*'''Время провала''' (''fail_time'') - длительность анимации смерти объекта, по его окончанию произойдет переход в состояние ''disappear''<br />
*'''Время паузы''' (''pause_time'') - длительность "заморозки" объекта<br />
*'''Предмет паузы''' (''pause_item'') - предмет для включения паузы<br />
*'''fail при 0 жизни''' (''zerofail'') - 1- при нулевом уровне жизни изомувер перейдет в fail, 0 - останется жив<br />
*'''Не пересчитывать маршрут''' (''softrecalc'') - 1- при отключении ребер графа не произойдет пересчета маршрута, 0 - маршрут будет пересчитан<br />
*'''Реагировать на''' (''tapreact'') - 1- на тап, 0- на клик<br />
<br><br />
<br />
==Дополнительные параметры==<br />
[[Файл:Isomover1.png|right|300px]]<br />
*'''Графический ресурс:'''<br />
**вверх (''res0'') - графический ресурс движения вверх<br />
**вверх/вправо (''res1'') - графический ресурс движения вверх/вправо<br />
**вправо (''res2'') - графический ресурс движения вправо <br />
**вниз/вправо (''res3'') - графический ресурс движения вниз/вправо<br />
**вниз (''res4'') - графический ресурс движения вниз <br />
**вниз/влево (''res5'') - графический ресурс движения вниз/влево<br />
**влево (''res6'') - графический ресурс движения влево <br />
**вверх/влево (''res7'') - графический ресурс движения вверх/влево. Достаточно указать первые пять ресурсов, а остальные редактор отобразит автоматически симметрично<br />
**деятельность (''resa'') - графический ресурс для состояния acting<br />
**иконка персонажа (''char_ico'') - иконка, которая будет находится сверху над персонажем. Изменение масштаба во время игры не влияет на масштаб иконки. Рекомендуется создавать ее с пивотом у нижней границы, тогда при масштабировании не будет образовываться зазор между иконкой и графикой объекта<br />
**смещение иконки персонажа (''char_ico_shift'') - смещение иконки по вертикали<br />
**рисовать при действии (''resad'') - 1- мувер рисуется при состоянии acting, 0- не рисуется<br />
**провал (''resf'') - графический ресурс состояния fail. Может быть картинкой или анимацией<br />
**пауза (''resp'') - графический ресурс состояния pause<br />
**восстановление жизни (''resheal'') - графический ресурс восстановления жизни<br />
*'''3D ресурс'''<br />
**модель (''mdl'') - трехмерный ресурс для отображения объекта<br />
**scale x (''mdlSx'') - масштаб по оси ''x''<br />
**scale y (''mdlSy'') - масштаб по оси ''y''<br />
**scale z (''mdlSz'') - масштаб по оси ''z''<br />
*'''Звуки'''<br />
**всплывание подложки (''snd_panel'') - звук показывающейся подложки<br />
**исчезание подложки (''snd_panel_hide'') - звук прячущейся подложки<br />
**переход в acting (''snd_to_acting'') - звук перехода в состояние acting<br />
**применение предмета (''snd_item_used'') - звук применение предмета при взаимодействии<br />
**предмет при паузе (''snd_item_pause'') - звук применение предмета при паузе<br />
**конец паузы (''snd_pause_end'') - звук при окончании паузы<br />
**фейл взаимодействия (''snd_fail'') - звук при переходе в fail<br />
**успех взаимодействия (''snd_success'') - звук при переходе в win<br />
**клик (''snd_click'') - звук при клике<br />
*'''Коэффициент скорости'''<br />
**вертикальное (''speed_0'') - на этот коэффициент умножается скорость при вертикальном движении<br />
**диагональное (''speed_1'') - на этот коэффициент умножается скорость при диагональном движении<br />
**горизонтальное (''speed_2'') - на этот коэффициент умножается скорость при горизонтальном движении<br />
Обычно горизонтальный коэффициент равен 1.00, чуть меньше диагональный и еще меньше вертикальный. Это необходимо для создания реалистичности движения относительно перспективы. То есть объекты, двигаясь вверх, как бы отдаляются от нас в глубь, поэтому по экрану они движутся медленней<br />
[[Файл:Isomover2.png|right]]<br />
*'''Таймер''':<br />
**подложка (''digBg'') - фон для цифр таймера<br />
**цифры (''digNorm'') - набор из 10-и цифр в виде ресурса анимации (клипа)<br />
**двоеточие (''colNorm'') - графический ресурс двоеточия<br />
**dx (''dx'') - смещение таймера по оси ''x'' относительно пивота изомувера<br />
**dy (''dy'') - смещение таймера по оси ''y'' относительно пивота изомувера<br />
**dx между цифрами (''digShift'') - расстояние между цифрами таймера<br />
**dx от (''colShift'') - отступы числовых разрядов влево и вправо от двоеточия<br />
**жизнь (''objlife'') - здесь выбирается объект типа прогресс_бар для отображения шкалы уровня жизни. Progress_bar создается отдельным объектом<br />
Таймер позволяет отобразить время до окончания взаимодействия объектов. Например "корабль" прибыл в "порт" и начал отгружать груз. С помощью числового таймера или progress_bar можно увидеть через сколько закончится отгрузка. На рисунке справа показано взаимодействие двух объектов с изображение шкалы жизни одного из объектов и времени до конца взаимодействия.<br />
*'''Преследование'''<br />
**тип (''chasetype'') - тип объекта, который можно преследовать<br />
**радиус (''chaseradius'') - если объект указанного типа окажется в этом радиусе, то начнется преследование (например полицейская погоня)<br />
*'''Дорожное движение'''<br />
**радиус (''stopradius'') - объекты, которые двигались по одному ребру, останавливаются на расстоянии этого радиуса (необходимо для препятствия наслоений объектов на дороге, железнодорожных путях)<br />
*'''восстановление жизни''':<br />
**критический уровень (''pow_min'') - Критический уровень жизни<br />
**предмет (''pow_item'') - Предмет восстановления <br />
**время (''pow_time'') - Время восстановления жизни<br />
<br />
*курсор (''curs'') - Графический ресурс курсора текущего и всех дочерних объектов<br />
*прокликиваемая (''passClk'') - Если 1, то картинка прозрачна для клика мышкой (пропускает объектам под ней). Если 2, то картинка сама обрабатывает клик, но и пропускает его дальше" regexp="нет=0, да=1, обработать и пропустить=2<br />
*группа (''gr'') - Группа, в которую входит текущий объект<br />
*eitems (''eitems'') - Объект типа eitems<br />
<br><br />
<br />
==Добавляемые параметры==<br />
[[Файл:Isomover9.png|right|300px]]<br />
[[Файл:+.png]] '''Взаимодействие с другими объектами''':<br />
*тип (''mtype'') - тип объекта с которым по настроенному ниже сценарию будет происходить взаимодействие, -1 для любого типа<br />
*min жизнь (''minlife'') - минимальное значение жизни для начала взаимодействия, -1 не проверять<br />
*max жизнь (''maxlife'') - максимальное значение жизни для начала взаимодействия, -1 не проверять<br />
*тип актив (''mtype_a'') - тип мувера, который активирует взаимодействие, если данный в процессе подготовки<br />
*анимация (''res_a'') - анимация взаимодействия, например боя, разгрузки, разговора. Перетаскивается мышкой из редактора ресурсов<br />
*старт тип (''stype'') - тип старта взаимодействия<br />
**0 - бесконечное ожидание тапа. Переход в состояние acting не начнется, пока не произойдет тап по объекту<br />
**1 - автоматический переход в состояние acting<br />
**2 - время, через которое произойдет переход из acting_wait в acting после начала взаимодействия объектов<br />
**3 - переход по значению жизни<br />
*старт таймер (''stimer'') - время, за которое нужно активировать взаимодействие тапом<br />
*старт изм.жизни (''slife'') - скорость изменения жизни до активации взаимодействия тапом<br />
*старт изм.жизни другого (''slife_o'') - скорость изменения жизни враг до активации взаимодействия тапом<br />
*предмет (''item'') - предмет, необходимый для запуска активности. Актуально, когда имеется объект economics<br />
*иконка (''ico'') - иконка активности<br />
*смещение иконки (''ico_shift'') - смещение иконки активности по вертикали<br />
*актив тип (''atype'') - тип старта взаимодействия<br />
**0 - бесконечное ожидание тапа. Переход в состояние acting не начнется, пока не произойдет тап по объекту<br />
**1 - автоматический переход в состояние acting<br />
**2 - время, через которое произойдет переход из acting_wait в acting после начала взаимодействия объектов<br />
**3 - переход по значению жизни<br />
*актив таймер (''atime'') - время, которое длится взаимодействие<br />
*актив изменение жизни (''alife'') - скорость изменения жизни текущего объекта (ед/сек) в состоянии active<br />
*актив изменение жизни другого (''alife_o'') - скорость изменения жизни другого объекта (ед/сек) в состоянии active<br />
<br />
[[Файл:Isomover3.png|right|300px]]<br />
*объект инит (''obj'') - объект, состояние которого нужно изменить при переходе изомувера в acting_wait<br />
*состояние инит (''st'') - новое состояние другого объекта<br />
*объект старт (''obj_s'') - объект, состояние которого нужно изменить при переходе изомувера в acting<br />
*состояние старт (''st_s'') - новое состояние другого объекта<br />
*объект фейл (''obj_f'') - объект, состояние которого нужно изменить при переходе изомувера в состояние fail (проигрыш)<br />
*состояние фейл (''st_f'') - новое состояние другого объекта<br />
*объект успех (''obj_w'') - объект, состояние которого нужно изменить при переходе изомувера в состояние win (в случае победы)<br />
*состояние успех (''st_w'') - новое состояние другого объекта<br />
*дельта жизнь (''deltalife'') при успехе взаимодействия изменить значение жизни на эту величину<br />
*переводить другой в фейл (''o_fail'') - 1- переводить цель действия в fail, 0- в idle<br />
*переводить другой в мув (''o_move'') - при неудачном действии 1- переводить цель действия в move, 0- в idle<br />
*можно ускорить (''canspeed'') - 1- действие можно ускорить. От этого параметра зависит, какое событие будет вызываться по клику на объект в состоянии acting<br />
*звук ожидания (''snd_wait'') - звук, который будет воспроизводиться в состоянии acting_wait <br />
*звук действия (''snd_act'') - звук, который будет воспроизводиться в состоянии acting<br />
Для каждого типа объектов, с которыми взаимодействие возможно, необходимо добавить отдельный параметр "взаимодействие с другими объектами" и настроить его. Объекты инит, старт, фейл и успех вызываются при переходе текущего объекта в соответствующие состояния. Например, это может быть диалоговое окно, предлагающее продолжить взаимодействие, запуск дополнительных индикаторов, фейерверк в случае победы.<br />
<br />
[[Файл:+.png]] '''Клик при простое''' (''nst_idle''):<br />
*объект - объект, состояние которого меняется, если изомувер был нажат в состоянии idel<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Изменить состояние объекта''' (''nst_move''), он же '''клик при движении''':<br />
*объект - объект, состояние которого меняется, если изомувер был нажат в состоянии move<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Клик при паузе''' (''nst_pause''):<br />
*объект - объект, состояние которого меняется, если изомувер был нажат в состоянии pause (заморозка)<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Изменить состояние объекта''' (''nst_aw_n'') он же '''клик при acting_wait, если другие действия не возможны'''<br />
*объект - объект, состояние которого меняется, если изомувер был нажат в состоянии acting_wait<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Изменить состояние объекта''' (''nst_a_1'') он же '''клик при acting, ускорение возможно'''<br />
*объект - объект, состояние которого меняется, если изомувер был нажат в состоянии acting и ускорение возможно<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Изменить состояние объекта''' (''nst_a_2'') он же '''клик при acting, ускорение НЕвозможно'''<br />
*объект - объект, состояние которого меняется, если изомувер был нажат в состоянии acting и ускорение не возможно<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Изменить состояние объекта''' (''nst_beact'') он же '''клик при beeng_acting'''<br />
*объект - объект, состояние которого меняется, если изомувер был нажат в состоянии beeng_acting, когда воздействие совершалось над ним другим объектом<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Конец движения''' (''nst_finish''):<br />
*объект - объект, состояние которого меняется, если изомувер закончил движение (достиг точки finish)<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Отправили в текущую ноду''' (''nst_place''):<br />
*объект - объект, состояние которого меняется, если изомувер направлен в ту же ноду, в которой и находится<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Перешел в fail''' (''nst_gopause''):<br />
*объект - объект, состояние которого меняется, если изомувер перешел в fail<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Перешел в pause''' (''nst_heal''):<br />
*объект - объект, состояние которого меняется, если изомувер Перешел в pause<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Восстановил здоровье''' (''nst_low_time''):<br />
*объект - объект, состояние которого меняется, если изомувер Восстановил здоровье<br />
*состояние - новое состояние объекта<br />
[[Файл:+.png]] '''Время истекло: изменить состояние объекта''' (''nst_low_time'') он же '''время на исходе: изменить состояние объекта''':<br />
*значение, при котором срабатывает обработчик<br />
*объект - объект, состояние которого меняется по истечению времени<br />
*состояние - новое состояние объекта<br />
<br><br />
<br />
==Состояния==<br />
[[Файл:isomover_box.png|right|350px]]<br />
*'''idle''' - дефолтное состояние, в которое isomover переходит после всех манипуляций. Недвижимым объектам следует передавать idle, чтобы они появились (нарисовались) на карте. Для движущихся объектов его практически не используют, объект сам рисуется с началом движения.<br><br />
*'''acting_wait''' - первое состояние взаимодействия (запускается первый таймер, анимация взаимодействия и ожидается старт).<br><br />
*'''acting''' - второе состояние взаимодействия (вызывается после применения предмета или клика, запускает второй таймер).<br><br />
*'''being_acted''' - в этом состоянии пребывает тот объект, над которым идет действие. Объект в этом состоянии невидим.<br><br />
*'''move''' - состояние движения от старта к финишу.<br><br />
*'''move_to_smooth''' - состояние движения от текущей ноды (или следующей, если объект идет) к финишу.<br><br />
*'''appear''' - показать по альфе за время появления.<br><br />
*'''disappear''' - скрыть по альфе за время появления.<br><br />
*'''prepare_acting''' - вызвать взаимодействие без оппонента. Перед вызовом нужно в поле param записать номер взаимодействия по порядку.<br><br />
*'''start_acting''' - продолжить взаимодействие без оппонента. Перед вызовом нужно в поле param записать номер взаимодействия по порядку.<br />
*'''pause''' - состояние "заморозки"<br />
<br><br />
<br />
==Особенности работы==<br />
[[Файл:Isomover6.png|right|300px]][[Файл:Isomover8.png|left|200px]]<br />
Движение объекта типа ''isomover'' задается с помощью отдельной машины состояний через которую происходит управление состояниями move, acting и остальными. Рассмотрим на конкретном примере. У нас есть объект '''woman''' типа ''isomover''. Необходимо, чтобы наш изомувер начал движение с точки b1 и дальше начал двигаться бесконечно по кольцу b2-b3-b4-b5. Движение задается машиной состояний ''woman_machine''.<br><br />
Для управления циклическим ходом назначим дополнительный параметр ''ww''. Название параметра должно быть уникально и не совпадать с параметрами игровых объектов.<br><br />
Для того, чтобы изомувер двигался каждый раз к новой точке, необходимо повторно инициализировать его точку финиша. Однако, если мы продолжим указывать ему состояние move для движения, то каждый раз он будет начинать движение с точки старта. Чтобы это исправить воспользуемся состоянием move_to_smooth, которое заставляет двигаться изомувер от текущей ноде к финишу, будто старт и финиш мы все время смещаем на шаг.<br />
<br>Основная логика будет находиться в состоянии ''circle_moving'' нашей машины. Надо сделать так, чтобы изомувер переходил в это состояние после движения по каждому из ребер. Для этого зайдем в свойства изомувера, нажмем правой кнопкой мыши и добавим параметр '''конец движения'''. У него есть поля ''объект'' и ''свойство''. Объект - машина состояний ''woman_machine'', состояние ''circle_moving'' этой машины. Таким образом, в конце каждого акта движения изомувер будет запускать состояние, в котором мы будем менять его точку финиша и запускать его движение.<br />
<br>Не забываем, что все операции с переменными должны отделяться скобками, как и сама переменная<br><br><br />
<br />
===Пример===<br />
Ознакомится с принципами работы isomover можно на примере следующего приложения. В isomap помещены два объекта isomover1 и isomover2. isomover2 совершает движение по определенному маршруту, заданному с помощью машины состояний iso2_mach (двигается из ноды p4 к заданной ноде p3 и совершает движение по кругу p3->p2->p8->p7->p3->...). isomover1 выходит из ноды p11 к заданной ноде p2 и ожидает клика на карту в точки "перекрестков" (по клику совершает движение к заданной ноде). Движение осуществляется с помощь машины iso1_navig. Во время движения isomover1 совершает атаку на isomover2, что описано в Добавленном свойстве объекта isomover1 "взаимодействие с другими объектами", если тот оказывается в достаточной близости (уничтожает его и двигается дальше). isomover2 будет "воскресать" после уничтожения и двигаться по заданному маршруту по истечению некоторого времени.<br />
*'''Пример:<br />
S:\!MOBILE\!!!EditorGames\Wiki_sample\Isomap.rar<br />
<br />
<br />
<br />
[[Category:Main objects]]<br />
[[Category:Game mechanic]]</div>Alexeev