Триггеры
|
|
Farengeit | Дата: Четверг, 28.08.2014, 18:04 | Сообщение # 1 |
 Лейтенант
Группа: Администраторы
Сообщений: 51
Награды: 2
Репутация: 1010
Статус: Offline
| Для начала, я расскажу о том, что это вообще такое - триггер и для чего оно нужно в MUGEN. Триггерами ("trigger" в переводе с англ. "курок") называется непосредственно часть кода стейт-контроллеров персонажа, которая описывает условия, при которых данный стейт-контроллер выполняется. Это своего рода спусковой механизм, который активизирует стейт-контроллер. Вот пример триггеров:
triggerall = Vel X = 0 trigger1 = Pos Y > -2 trigger2 = AnimElem = 3 trigger3 = Time = [2,9]
Также триггерами называются непосредственно сами переменные, описывающие текущее состояние персонажа (в приведенном примере, это "Vel X", "Pos X", "AnimElem", "Time"), вместо которых MUGEN автоматически, каждый игровой тик (60 раз в секунду) подставляет соответствующие значения (скорость движения персонажа по горизонтали, позицию по вертикали, номер элемента текущей анимации и время нахождения в данном стейтдефе - соответственно). Привожу для примера небольшой код стейта с одним триггером (описывать все элементы не буду - для этого есть тутор по стейт-контроллерам):
[State 200, 2] type = ChangeState trigger1 = AnimTime = 0 ;стейт активируется тогда, когда закончится текущая анимация value = 0 ctrl = 1
Фактически, триггер стейт-контроллера представляет собой математическое выражение, которое либо верно или истинно (если оно не равно нулю, - в таком случае триггер сработает и стейт выполнится), либо неверно или ложно (равно нулю - триггер не сработает). Рассмотрим пример "trigger2 = AnimElem = 3". На первом элементе анимации выражение примет вид "trigger2 = 1 = 3". Т.к. 1 не равен 3, то равенство неверно, условие не выполняется, и выражение ЛОЖНО, равно нулю - триггер не сработает. Для второго элемента анимации условие тоже не выполняется. В случае с третьим элементом имеем выражение "trigger2 = 3 = 3" и получаем верное равенство "3 = 3", которое истинно (т.е., возвращает единицу, щелкает нашим триггером и запускает контроллер). Если мы запишем "trigger2 = AnimElem <= 3", то триггер сработает только на 1, 2 и третьем элементах, если "trigger2 = AnimElem > 3", то на 4, 5, 6 и т.д. Также мы можем записать просто "trigger2 = AnimElem" - в этом случае, текущий номер анимации не будет сравниваться с каким-либо числом и триггер будет срабатывать каждый игровой тик (т.к. элемент анимации не может равен нулю - отсчет идет от номера 1). Также можно встретить запись вроде "trigger1 = 1" - это тоже означает, что триггер будет срабатывать постоянно (можно поставить любое число, отличное от нуля, даже отрицательное). А вот если записать "trigger1 = 0", то триггер вообще никогда не сработает.
|
|
|
|
Farengeit | Дата: Четверг, 28.08.2014, 18:24 | Сообщение # 2 |
 Лейтенант
Группа: Администраторы
Сообщений: 51
Награды: 2
Репутация: 1010
Статус: Offline
| Для триггеров используются следующие математические операторы:
+ - Сложение.
- - Вычитание.
* - Умножение.
/ - Деление. Если оба числа - целые (без десятичной запятой), то остаток от деления отбрасывается: 7/2 = 3. Если хотя бы одно дробное - то получаем дробное число: 7.0/2.0 = 3.5. Деление на ноль выдаст ошибку - "bottom"
% - Остаток от деления. Если хотя бы одно число не целое или равно нулю - получим "bottom".
** - Возведение в степень. Не забывайте, что любое число в степени 0 равно 1. Также следует соблюдать осторожность при работе с большими числами, иначе число может выйти за пределы допустимых значений и вы получите ошибку, а так же в отрицательными и дробными. Выражения типа -1 ** .5 дадут нам "bottom".
! - Логическое "НЕ". !x равно нулю если x не равен нулю, и 1, если равен.
&& - Логическое "И". x && y равно 1, если x и y не равны нулю и ноль в остальных случаях.
|| - Логическое "ИЛИ". x || y равно 1, если хотя бы один из операторов (x и/или y) не равен нулю, и 0 в остальных случаях.
^^ - Логическое "ИСКЛЮЧАЮЩЕЕ ИЛИ". x ^^ y равно 1, если только один из операторов (x или y) не равен нулю, и 0 в остальных случаях.
~ - Побитовое "НЕ". ~x - инверсия битов в двоичном представлении числа. Только для целых чисел.
& - Побитовое "И". n-нный бит x&y устанавливается в 1 если n-нный бит x и y равен 1. Только для целых чисел.
| - Побитовое "ИЛИ". n-нный бит x|y устанавливается в 1 если n-нный бит x и/или y равен 1. Только для целых чисел.
^ - Побитовое "ИСКЛЮЧАЮЩЕЕ ИЛИ". n-нный бит x^y устанавливается в 1 если n-нный бит только x или только y равен 1. Только для целых чисел (побитовые команды встречаются в мугене крайне редко - не заморачивайтесь с ними).
= - Оператор равенства. Если x = y, то выражение истинно и дает 1, если не равно - 0.
:= - Оператор присвоения. Слева от него обязательно должна быть указана переменная (var(N) или fvar(N), где N - номер переменной), а справа - значение, которое присваивается переменной.
!= - Оператор неравенства. x != y дает 1, если x не равен y, и 0, если равен.
< - Оператор "Меньше". x < y дает 1, если x меньше у, и 0, в остальных случаях.
<= - Оператор "Меньше или Равно". x <= y дает 1, если x меньше либо равно у, и 0, в остальных случаях.
> - Оператор "Больше". x > y дает 1, если x больше у, и 0, в остальных случаях.
>= - Оператор "Больше или Равно". x <= y дает 1, если x больше либо равно у, и 0, в остальных случаях.
=[,] !=[,] =[,) !=[,) =(,] !=(,] =(,) !=(,) - Интервальные операторы. Имеют следующий смысл:
z=[x,y] - x<=z<=y; z!=[x,y] - x>z>y; z=[x,y) - x<=z< y; z!=[x,y) - x>z>=y; z=(x,y] - x< z<=y; z!=(x,y] - x>=z>y; z=(x,y) - x< z< y; z!=(x,y) - x>=z>=y
Приоритет математических операторов (от высшего к низшему).
! ~ ** * / % + - > >= < <= = != интервалы := & ^ | && ^^ ||
То есть, сначала в выражении выполнится логическое "НЕ", потом возведение в степень, потом умножение (деление, нахождение остатка от деления), потом сложение (вычитание) и т.д. В связи с этим настоятельно рекомендую использовать скобки (), если порядок действий в выражении должен быть другим.
|
|
|
|
Farengeit | Дата: Пятница, 29.08.2014, 17:48 | Сообщение # 3 |
 Лейтенант
Группа: Администраторы
Сообщений: 51
Награды: 2
Репутация: 1010
Статус: Offline
| Продолжаем наше знакомство с триггерами стейт-контроллеров (я настоятельно рекомендую изучать и то, и другое параллельно - и триггеры, и стейт-контроллеры. Так вам будет легче понять и усвоить информацию.). Расскажу пор нумерацию триггеров. Иногда для одного стейт-контроллера нам необходимо использовать несколько условий для его выполнения, или одно условие должно учитывать несколько различных характеристик - например, время стейта, номер текущей анимации и номер элемента анимации. Для этого триггеры последовательно нумеруются, начиная с 1: trigger1, trigger2, trigger3 и т.д. В некоторых случаях используется запись triggerall - ниже я поясню, что она означает. Нумеровать триггеры нужно по порядку, не пропуская номеров (если вы напишите trigger1, trigger2, trigger4, то последний триггер не сработает никогда - MUGEN просто пропустит его). Объясню на примере про нумерацию триггеров:
[State 200, ChangeAnim] type = ChangeAnim trigger1 = Time >= 20 ;время должно быть больше либо равно 20 trigger2 = Anim != 201 ;номер текущей анимации не должен быть 201 trigger3 = AnimElem = 5 ;номер текущего элем. анимации должен быть 5 value = 0
Данный контроллер меняет текущую анимацию на анимацию стойки (которая всегда находится под номером 0). Изменит он анимацию в том случае, если: время будет больше либо равно 20, ИЛИ номер текущей анимации не будет 201, ИЛИ номер текущего элемента анимации будет равен 5. То есть, при такой записи в любом из этих трёх случаев триггер сработает (логика "ИЛИ" - достаточно выполнения хотя бы одного из трёх условий), запустит стейт контроллер и игрок изменит текущую анимацию на нулевую. Данный стейт можно записать по другому, но он будет работать в точности так же:
[State 200, ChangeAnim] type = ChangeAnim trigger1 = Time >= 20 || Anim != 201 || AnimElem = 5 value = 0
Теперь немного видоизменим наш стейт:
[State 200, ChangeAnim] type = ChangeAnim trigger1 = Time >= 20 ;время должно быть больше либо равно 20 trigger1 = Anim != 201 ;номер текущей анимации не должен быть 201 trigger1 = AnimElem = 5 ;Номер текущего элем. анимации должен быть 5 value = 0
Теперь картинка будет следующая: стейт-контроллер изменит анимацию только в том случае, если: время будет больше либо равно 20 И номер текущей анимации не будет 201 И номер текущего элемента анимации будет равен 5. При такой записи работает логика "И" - необходимо наличие всех трёх условий для запуска контроллера. Вот альтернативный вариант записи этого же варианта:
[State 200, ChangeAnim] type = ChangeAnim trigger1 = Time >= 20 && Anim != 201 && AnimElem = 5 value = 0
А теперь расскажу немного про "triggеrall". Он используется при наличии хотя бы одного триггера (trigger1) а чаще нескольких и работает в паре с каждым из них в отдельности. Это означает, что для включения контроллера необходимо выполнения trigger1 и triggerall, или trigger2 и triggerall, но не само выполнение triggerall в отдельности. Поясню на нашем примере, опять немного измененном:
[State 200, ChangeAnim] type = ChangeAnim triggerall = Anim != 201 ;номер текущей анимации не должен быть 201 trigger1 = Time >= 20 ;время должно быть больше либо равно 20 trigger2 = AnimElem = 5 ;Номер текущего элем. анимации должен быть 5 value = 0
Логика будет следующая: стейт-контроллер изменит анимацию только в том случае, если: время будет больше либо равно 20 И номер текущей анимации не будет 201, ИЛИ номер текущего элемента анимации будет равен 5 И номер текущей анимации не будет 201 (т.е. только два варианта для активации контроллера). Этот же вариант запишем в нескольких альтернативных вариантах записи (скобки нужны для определения порядка действий - сначала "И", потом "ИЛИ"):
[State 200, ChangeAnim] type = ChangeAnim trigger1 = Time >= 20 && Anim != 201 trigger2 = AnimElem = 5 && Anim != 201 value = 0
[State 200, ChangeAnim] type = ChangeAnim trigger1 = (Time >= 20 && Anim != 201) || (AnimElem = 5 && Anim != 201) value = 0
|
|
|
|