The Sims 3, Gran Turismo и MUGEN

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » The Sims 3, Gran Turismo и MUGEN » M.U.G.E.N. » Справка по M.U.G.E.N.


Справка по M.U.G.E.N.

Сообщений 1 страница 4 из 4

1


Информация предоставлена с официального сайта Elecbyte

            И так, как мы знаем, игровой движок M.U.G.E.N. состоит из файлов различного формата, в которых так же содержатся данные, о которых нам предстоит узнать. Если вы не поняли зачем зашли в эту тему, или ищите с чего начать, тогда вам лучше ознакомится с Руководством по созданию персонажа.

            Сам Муген можно скачать по прямой ссылке с официального сайта Elecbyte, версия движка Mugen 1.1b1.


          Формат файла AIR         

            Введение

            AIR - это формат, который описывает набор анимаций. Вы увидите формат AIR, используемый для анимации персонажей, фона, лайфбаров и т. д.

            Анимация (специально называемая анимационным действием в M.U.G.E.N) описывает одну последовательность спрайтов для отображения. Файл анимации персонажа (.air) может содержать столько анимационных действий, сколько для этого необходимо.


            Формат

            Вот типичная запись из файла .air. Формат которого мы будем объяснять.

; Анимация стойки
[Begin Action 000]
Clsn2Default: 2
Clsn2[0] = -100, 10,-79
Clsn2[1] =  -4,-926,-79
0,1, 0,0, 7
0,2, 0,0, 7
0,3, 0,0, 7
0,4, 0,0, 50
0,5, 0,0, 7
0,6, 0,0, 7
0,7, 0,0, 7
0,8, 0,0, 60

            Точка с запятой (;) используется для комментариев. Их можно использовать везде и все, что после точки с запятой в этой строке - все игнорируется.

            [Begin Action n] Это определяет действие. Число n называется номером действия. Каждое действие должно иметь уникальный номер действия, чтобы отличаться от других действий. У вас может быть много действий, но имейте в виду, что есть зарезервированные номера действий. Эти числа и связанные с ними действия будут перечислены ниже.

            Clsn2Default: 2 Это говорит о том, что определены два поля столкновений, и они будут определены для всех записей ниже определения Clsn. В этом случае для каждого спрайта в этом действии. Если вы не хотите иметь блоки, которые по умолчанию, тогда измените Clsn2Default на Clsn2. Вы должны поместить определение Clsn перед записью спрайта. Каждая запись спрайта может иметь свои собственные коллизионные блоки. Clsn2 относится к простому коллизионному блоку, а Clsn1 относится к «атакующему» блоку. Вы используете атакующие блоки при атакующих действиях, таких как пробивание и удар ногами или специальные приёмы. Чтобы определить простые поля и блоки атаки, используйте программу AirEdit, включенную в набор инструментов разработки M.U.G.E.N.

            0,3, 0,0, 7 Запись, подобная этой, называется «элементом анимации» или просто «элементом» для краткости. Первый номер - это номер группы спрайтов. Второй номер - номер изображения в группе спрайта. Эти номера присваиваются вашим спрайтам при создании файла .sff.

            Таким образом, группа №0 и изображение №3 были определены с помощью sprmaker с записью, таким как: work/mypic.pcx 0 (номер группы) 3 (номер изображения) 40 ось X 40 ось Y.

            Третьим и четвертым номерами элемента являются смещения X и Y от этой оси спрайта. Если вы хотите, чтобы спрайт появился на 5 пикселей вперед, поставьте «5» для третьего номера. Чтобы создать спрайт на 15 пикселей вверх, поставьте «-15» для 4-го номера и так далее. В большинстве случаев нормально, когда смещение равно 0,0.

            5-й номер - это время, чтобы отобразить элемент перед перемещением на следующий элемент, измеряется в игровых тиках (ticks) игры. За обычную скорость игры 60 игровых тиков равняется как за одну секунду. Для 5-го числа вы можете указать «-1», если вы хотите, чтобы этот элемент отображался неограниченно (или пока вы не переключились на другое действие). Если вы решите сделать это, сделайте это только на последнем элементе действия.

            «Looptime» действие - это сумма всех времен каждого элемента. В основном, это общая длина действия в игровых тиках. Если последний элемент имеет время «-1», время цикла будет считаться бесконечным. Мы называем это «no loop». Действия с конечным временем цикла возвращаются к первому элементу после того, как он завершит отображение последнего элемента, и продолжается цикл до тех пор, пока вы не переключитесь на другое действие.

            В примере, описанном выше, время цикла будет: 7 + 7 + 7 + 50 + 7 + 7 + 7 + 60 = 152 тика.

; Анимация стойки
[Begin Action 000]
Clsn2Default: 2
Clsn2[0] = -100, 10,-79
Clsn2[1] =  -4,-926,-79
0,1, 0,0, 7
0,2, 0,0, 7
Loopstart
0,3, 0,0, 7
0,4, 0,0, 50
0,5, 0,0, 7
0,6, 0,0, 7
0,7, 0,0, 7
0,8, 0,0, 60

            Добавление строки со словом «Loopstart» заставит анимацию начать повторный цикл из элемента в следующей строке. В приведенном выше примере, когда отображается элемент со спрайтом 0,8, следующий элемент, который будет показан, будет отображаться со спрайтом 0,3.

            При тестировании анимации вы можете найти функции приостановки и продвижения кадра. Чтобы сделать паузу, нажмите кнопку «Pause». Чтобы продвинуть игру по одной игровой секунде (tick), нажмите Scroll Lock. Продвижение Frames (фреймов) работает только тогда, когда игра приостановлена.


            Дополнительные параметры

            Вот запись: 15,1, 0,0, 5

            Если вы хотите перевернуть спрайт по горизонтали и/или по вертикали, вам нужно будет использовать параметры «флип»: V для вертикального перевертыша и H для горизонтального. Эти параметры будут 6-м на линии. Например:

15,1, 0,0, 5, H    ;<-- Это переворачивает его по горизонтали
15,2, 0,0, 5, V    ;<-- Это переворачивает его по вертикали
15,3, 0,0, 5, VH  ;<-- Это переворачивает в обоих направлениях, т.е. поворачивается на 180 градусов

            Перевертывание спрайта особенно полезно для создания бросков. Противник, который бросается, временно получает данные анимации игрока и вводит действие анимации «брошен» (being thrown). Возможно, вам придется перевернуть спрайты, чтобы действие «thrown» (кинуть) выглядело правильно.

            Для некоторых вещей, таких как ударные искры, вы можете использовать добавление цвета для рисования спрайта, что делает его «прозрачным». Вам не нужно будет использовать это, чтобы создать персонажа, поэтому вам не нужно беспокоиться об этом, если вы этого не сделаете. Параметры для сложения и вычитания цвета - «A» и «S» соответственно, и они должны идти как 7-е место на линии. Например:

15,4, 0,0, 5, , A   ;<-- Добавление цвета (параметр "переворот" не включен)
15,4, 0,0, 5, H, S ;<-- Переключение по горизонтали и вычитание цвета

            Если вы хотите указать альфа-значения для добавления цвета, используйте формат параметров «AS ??? D ???», где ??? Представляет значения исходной и целой альфа гаммой соответственно. Значения варьируются от 0 (низкий) до 256 (высокий). Например, «AS64D192» означает «Добавить Source_64 в Dest_192». Кроме того, «AS256D256» эквивалентен «A». Сокращение для «AS256D128» - «A1».

15,4, 0,0, 5, , A1              ;<-- Цвет становится на 50% темнее
15,4, 0,0, 5, , AS128D128 ;<-- Смешивается 50% от источника с 50%


            Зарезервированные номера действий персонажа

            Механизм общего состояния M.U.G.E.N (data/common1.cns) требует, чтобы в вашем персонаже присутствовало несколько действий обязательной анимации (будет показано предупреждение, если не хватает необходимой анимации). Есть также некоторые действия, которые являются необязательными, но которые будут использоваться, если они присутствуют в вашем персонаже.

            Если вы не знаете, как должно выглядеть какое-либо из этих действий, посмотрите на пример chars/kfm/kfm.air.

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

            «opt», кроме номера, означает, что анимация является необязательной.

           

Номер

Описание

Комментарии

0

Стойка

5

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

Должен быть параметр looptime

6

Поворот в приседании

Должен быть параметр looptime

10

Встать на корточки

Конечный результат looptime

11

Присесть

12

Встать с корточек

Конечный результат looptime

20

Идти вперёд

21

Идти спиной назад

40

Начало прыжка (на земле)

Анимация начала прыжка, когда игрок еще не прыгнул и находится на земле

41

Нейтральный прыжок (вверх)

Показывается, когда игрок движется вверх

42

Прыжок вперёд (вверх)

Показывается, когда игрок движется вперёд и вверх по направлению

43

Прыжок назад (вверх)

Показывается, когда игрок движется назад и вверх

44 opt

Нейтральный прыжок (вниз)

Активируется, когда Y-скорость> -2

45 opt

Прыжок вперёд (вниз)

См. выше

46 opt

Прыжок назад (вниз)

См. выше

47

Прыжок приземления

Показывается, когда игрок приземляется с прыжка

100

Бег вперёд/рывок вперёд

105

Рывок назад

120

Начало обороны (стойка)

Конечный результат looptime

121

Начало обороны (на корточках)

Конечный результат looptime

122

Начало обороны (воздух)

Конечный результат looptime

130

Защита (стойка)

131

Защита (на корточках)

132

Защита (воздух)

140

Конец обороны (стойка)

Конечный результат looptime

141

Конец обороны (на корточках)

Конечный результат looptime

142

Конец обороны (воздух)

Конечный результат looptime

150

Удержание удара (стойка)

Конечный результат looptime

151

Удержание удара (на корточках)

Конечный результат looptime

152

Удержание удара (воздух)

«Нет цикла»

170 opt

Проиграть

(См. Примечание 1)

175 opt

Время закончилось, ничья

(См. Примечание 1)

180 opt

Победа

«Нет цикла» (181-189 для нескольких) (См. Примечание 1)

190 opt

Вступление

«Нет цикла» (См. Примечание 1)

195 opt

Насмешка

Конечный результат looptime (См. Примечание 1)

5000

Стойка/высокий удар (легкий)

looptime около 10-20

5001

Стойка/высокий удар (средний)

* (См. Примечание 2)

5002

Стойка/высокий удар (тяжелый)

*

5005

Восстановление после высокого удара (легкий)

«Нет цикла» (См. Примечание 3)

5006

Восстановление после высокого удара (средний)

*

5007

Восстановление после высокого удара (тяжелый)

*

5010

Стойка/невысокий удар (легкий)

looptime около 10-20

5011

Стойка/невысокий удар (средний)

*

5012

Стойка/невысокий удар (тяжелый)

*

5015

Восстановление после невысокого удара (легкий)

«Нет цикла»

5016

Восстановление после невысокого удара (средний)

*

5017

Восстановление после невысокого удара (тяжелый)

*

5020

Удар сидя (легкий)

«Нет цикла»

5021

Удар сидя (средний)

*

5022

Удар сидя (тяжелый)

*

5025

Восстановление после удара сидя (легкий)

«Нет цикла»

5026

Восстановление после удара сидя (средний)

*

5027

Восстановление после удара сидя (тяжелый)

*

5030

Падение от высокого удара

looptime около 10-20

5035 opt

Переход от состояния падения

looptime около 5-15 (См. Примечание 3)

5040

Восстановление

«Нет цикла»

5050

Падение

«Нет цикла»

5060 opt

Падение (спускаться вниз)

«Нет цикла»

5070

Споткнуться

5080

Лечь на землю (оставаться внизу)

(См. Примечание 4)

5090

Лечь на землю (получить удар в воздухе)

5100

Удариться о землю после падения

looptime около 3

5160

Подпрыгнуть в воздух

5170

Удар о землю после прыжка

looptime около 3 или 4

5110

Лежащий

5120

Встать с лежащего состояния

5140 opt

Умерший (первые раунды)

5150 opt

Умерший (финальный раунд)

5200

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

5210

Восстановление в воздухе

5300

Головокружение

5500 opt

Экран "Continue?"

Если пропустить, работает анимация головокружения

5510 opt

Экран "Yes" to "Continue?"

Если пропустить, работает первая выигрышная анимация (не реализовано)

5520 opt

Экран "No" to "Continue?"

(не реализовано)

            Дополнительные анимации удара вверх (Hit Up)  (См. Примечание 5)

           

Номер

Описание

Комментарии

5051 opt

Падение Hit Up

5061 opt

Идти вниз с положения Hit Up

5081 opt

Лечь от удара Hit Up (оставаться лежа)

5101 opt

Отскочить от земли в воздух

looptime около 3

5161 opt

Отскочить в воздух

5171 opt

Удар о землю от отскока

looptime около 3 или 4

5111 opt

Лежащий

5121 opt

Встающий

5151 opt

Умерший (первые раунды)

5156 opt

Умерший (финальный раунд)

            Дополнительные анимации удара вверх (Hit Up) по диагонали (См. Примечание 6)

           

Номер

Описание

Комментарии

5052 opt

Падение Hit Up

5062 opt

Идти вниз с положения Hit Up

5082 opt

Лечь от удара Hit Up (оставаться лежа)

5102 opt

Отскочить от земли в воздух

looptime около 3

5162 opt

Отскочить в воздух

5172 opt

Удар о землю от отскока

looptime около 3 или 4

5112 opt

Лежащий

5122 opt

Встающий

5152 opt

Умерший (первые раунды)

5157 opt

Умерший (финальный раунд)

            Примечание 1: На самом деле им не нужно использовать только указанные номера. Если это больше чем рекомендуемый номер M.U.G.E.N. Если необходимо, не стесняйтесь использовать любые другие номера действий.

            Примечание 2: Если средний и тяжелый удары не включены, они по умолчанию имеют легкий удар.

            Примечание 3: «Нет цикла» означает, что последний кадр имеет время -1. Для восстановления анимации первым кадром каждого восстановления должен быть последний кадр соответствующего удара. Если действие 5000 имеет кадры 5000,0 и
                                     5000, 1, то действие 5005 должно начинаться с кадра 5000, 1. Это связано с тем, что анимация будет заблокирована в первом кадре восстановления после того, как анимация удара закончится, но до того, как игрок восстановится
                                     после удара. Если у вас есть анимация перехода Стойка/Верхний удар перехода (Stand/Air Hit transition), тогда первый кадр Воздушного восстановления (Air Recover) и Воздушного Падения (Air Fall) должны быть последним кадром
                                     переходной (transition) анимации.

            Примечание 4: Анимация «Стойка/Верхний удар перехода»  Stand/Air Hit transition воспроизводится после каждой анимации удара в (или на) воздухе, но до анимации Air Recover (воздушного восстановления) и Air Fall (воздушного падения).

            Примечание 5: Вы можете установить цикл на LieDown Hit (лежащий на земле), если хотите, чтобы игрок выглядел так, будто он «подергивается» после удара.

            Примечание 6: Этот набор анимаций является необязательным. Это альтернативный набор падающих анимаций, который используется при попадании HitDef с «Up» в качестве animtype.

            Примечание 7: Этот набор анимаций является необязательным. Это альтернативный набор падающих анимаций, который используется при попадании HitDef с «DiagUp» в качестве animtype.


            Рекомендуемые номера действий

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

            Вам может понадобиться пространство для ваших анимаций и state номеров. Это дает вам возможность добавлять дополнительные действия по мере необходимости (некоторые атаки могут использовать несколько состояний и анимаций). Например, Standing Light Kick (Легкий удар ногой стоя) и Standing Strong Kick (Сильный удар ногой стоя) могут иметь номера действий 200 и 210 соответственно.

           

Номер

Описание

0-199

Зарезервированные

200-299

Стоячие атаки

300-399

Еще стоячие атаки, атаки на бегу

400-499

Атаки сидя

500-599

Еще сидячие атаки

600-699

Воздушные атаки

700-799

Еще воздушные атаки

800-999

Не используется - используйте, если вам нужно больше состояний (states)

1000-2999

Все специальные атаки

3000-4999

Все супер и гипер атаки

5000-5999

Зарезервированные

Примечание автора: Под 9000 используются аватары и иконки для Versus экрана, боев, экрана выбора персонажа и т.п.


Материал перевел и подготовил Sceletron

0

2


Информация предоставлена с официального сайта Elecbyte

          Обновить M.U.G.E.N. до версии 1.1         

            Изменение персонажа на версию 1.1

            M.U.G.E.N 1.0 совместим с большинством контента из версии 2002.04.14. Тем не менее, есть некоторые новые функции, которые будут доступны только в том случае, если mugenversion персонажа обновляется до 1.1. Вы можете обновить свой контент, выполнив следующие действия:

            DEF файл

- В разделе [Info] установите mugenversion = 1.1.
- В разделе [Info] добавьте строку localcoord = 320, 240. При желании это значение можно настроить для подходящего размера координатного пространства игрока.

            CNS файл

- Найдите все контроллеры состояния HitDef и добавьте 1 к pausetime для каждого (это изменение поведения связано с исправлением ошибки в версии 1.0).
- Если у игрока CNS есть переопределенное состояние state 5900, вам нужно будет добавить контроллер type = RemapPal в ваше состояние state 5900. Вы можете скопировать контроллер из состояния 5900 в common1.cns.
- Найдите все контроллеры состояния PlaySnd с параметром volume и измените его, чтобы вместо этого использовать параметр volumescale. Поведение volumescale отличается от volume тем, что он интерпретирует его параметр как процент вместо смещения,
  например вместо volume = 0, используйте volumescale = 100. Эта информация содержится в разделе «Изменения музыки и звуков» этого поста.
- Добавьте котировки выигрыша вашему персонажу, добавив раздел [Quotes] в файл CNS. См. пример в файле kfm.cns.
- Используйте триггер trigger1 = StageVar, чтобы определить, на каком этапе игрок включен, вместо предыдущих методов.
- Используйте триггер уровня AI (trigger1 = AILevel), чтобы определить активацию игрока AI вместо предыдущих методов.
- Используйте триггеры GameWidth и GameHeight вместо констант, таких как 320 и 240, где указаны ширина и высота зоны воспроизведения.
- Найдите все экземпляры gethitvar(zoff) и замените на 0 или иначе измените логику, чтобы отключить проверку.
- Найти все контроллеры AssertSpecial и добавить строку ignorehitpause = 1, если Flag является одним из - nostandguard, nocrouchguard, noairguard, noautoturn, noshadow, nojugglecheck, nowalk, unguardable, invisible.
- Найдите snap, mindist и maxdist во всех HitDefs и удалите третий (z) параметр, если он существует, например snap = 40, -10, 0, -1 становится snap = 40, -10, -1.
- Найдите все триггеры trigger = vel z и pos z и замените на 0 или иным образом измените логику, чтобы отключить проверку.
- Найдите все экземпляры velset в разделах [Statedef ...] и удалите третий (z) параметр, если он существует, например velset = 0, 0, 0 становится velset = 0, 0.
- Исправьте триггеры trigger = HitDefAttr, которые были искажены. Правильный синтаксис - это HitDefAttr <функция> <значение1>, <значение2>, где <функция> это = или !=, <значение1> имеет хотя бы одну букву «SCA», а <значение2> - это набор из
  2-символьных строк, например HitDefAttr = SC, а должен быть HitDefAttr = SC, NA, SA, HA.


            Изменение арены на версию 1.1

            M.U.G.E.N 1.0 совместим с аренами версии 2002.04.14.

            Добавьте следующие параметры в раздел [Info]:

displayname = "..."                ;Имя для отображения на экране выбора (заменить ... с фактическим именем)
versiondate = 01,30,2010       ;Дата версии арены (ММ, ДД, ГГГГ или X.XX) (заменить на фактическую дату)
mugenversion = 1.1               ;Версия M.U.G.E.N на этом этапе работает над (1.1)
author = "..."                         ;Имя автора арены

            Добавьте следующие параметры в раздел [Camera] и соответствующим образом настройте значения (см. документацию по созданию арены).

overdrawhigh = 0
overdrawlow = 0
cuthigh = 35
cutlow = 25

            В разделе [StageInfo] добавьте следующее:

localcoord = 320, 240
xscale = 1
yscale = 1

            В разделе [Music] используйте bgmvolume вместо bgvolume. bgmvolume принимает значение 100 для 100%, 50 для 50% и так далее. Подробности приведены в разделе «Изменения музыки и звуков» этого поста.

            Если на арене есть параметр hires = 1, используйте xscale = .5 и yscale = .5 и удалите строку hires = 1. Возможно, потребуется изменить некоторые другие параметры.


            Изменение основной темы на 1.1

            system.def

            Добавьте следующие строки в раздел [Info] в файле system.def.

versiondate = 01,30,2010  ;Дата версии (ММ, ДД, ГГГГ или Х.ХХ) (заменить на фактическую дату)
mugenversion = 1.0          ;Версия M.U.G.E.N работает на (1.1)
localcoord = 320,240         ;Ширина и высота локального координатного пространства

            Дополнительно: добавьте разделы [Infobox] и [Infobox Text], чтобы настроить содержимое окна информации F1 для выбора режима. См. data/mugen1/system.def для примера.

            Есть некоторые системные файлы D4 (hi-res), сделанные для версии MUGEN 2002 года, для которой требуется параметр Doubleres = 4 в файле mugen.cfg. Поскольку 1.0 не предназначен для функциональности Doubleres в пользу координатных пространств, вам нужно будет обновить эти данные. Общей проблемой является то, что шрифты слишком большие. В fight.def и system.def отредактируйте или добавьте параметр масштаба ко всем элементам, которые сделаны слишком большими. Например Добавьте p1.name.scale = .5, .5, если нет линии масштабирования; В противном случае что-то вроде p1.name.scale = .5, .5 становится p1.name.scale = .25, .25.

            fight.def

            Добавьте раздел [FightFx] в fight.def. Размер графики fightfx.sff можно настроить с помощью параметра scale.

[FightFx]
scale = 1


            Изменение файла спрайтов на 1.1

            1.1 представляет SFF v2, который имеет множество функций палитры, а также дополнительные параметры сжатия. Подумайте о преобразовании ваших спрайт-файлов в SFF v2, чтобы использовать новые функции.


            Изменения музыки и звуков на 1.1

            Некоторые изменения в музыке и звуковой системе были сделаны в ходе разработки 1.1. Изменения, которые вы увидите, в двух словах:

- Улучшенная поддержка MP3 и OGG
- Расширяемая архитектура плагинов M.U.G.E.N.
- Поддержка циклов Loopstart и loopend, для совместимых плагинов
- Более интуитивные настройки громкости: Master, wave/sfx, BGM
- «Смещения» звука заменяются коэффициентами масштабирования объемного звучания
- Различные исправления BGM
- Улучшенное качество звука

            Вы должны использовать обновленный mugen.cfg, включающий в себя работу BGM!

            Краткий FAQ по Audio

Вопрос: Какие плагины поддерживается?
Ответ: M.U.G.E.N распознает только специально разработанные для него плагины. Так, например, плагины Winamp не будут работать.

Вопрос: Как создать плагин для моего любимого типа?
Ответ: Обратитесь к плагину SDK.

Вопрос: Как найти точки повторного цикла для моих MP3 или OGG?
Ответ: Чтобы получить хороший результат, вам нужно будет открыть файл в аудиоредакторе и определить точные точки, в которых музыка повторяется.

Вопрос: Как установить точки повторного цикла для других типов файлов?
Ответ: Это вы не можете. Плагины, совместимые с Looppoint, еще не созданы для других типов файлов.

Вопрос: Звук заикается/пропускается!
Ответ: Попробуйте включить размер буфера аудио и/или отключить частоту дискретизации миксера в файле mugen.cfg (раздел [Sound]). Кроме того, отключите высококачественную передискретизацию (resampling), если она включена.

            Новая система BGM пытается отслеживать ее статус. Вы можете найти сводную статистику времени для обратного вызова миксера, написанного в конце mugen.log. Вы также можете проверить, не обнаружена ли система декодера, ища строки, в которых говорится: «possible read starvation detected» Эта информация помогает нам устранить возможные причины звуковой коррупции.

Вопрос: Почему существуют три папки Microsoft.VC90.CRT? Это какая-то шутка?
Ответ: Эти папки являются неудачным результатом того, как загружаются среды Visual C, и обычно требуются для правильной работы. Однако есть способ избавиться от них. Вам необходимо загрузить и установить распространяемый пакет  Visual C++ 2008 SP1 redistributable package (x86). Как только вы это сделаете, папки Microsoft.VC90.CRT можно безопасно удалить.

            Детальный список изменений

            В комплект входят следующие плагины. См. комментарии в mugen.cfg для дополнительных параметров и использования.

- mpg123

            Поддерживает воспроизведение MP3 с использованием декодера libmpg123, в котором есть несколько оптимизированных движков декодирования, написанных на сборке. Поддерживает повторные точки, регулировку громкости ReplayGain и поиск образцов. (Примечание: поиск потеряет незаметное количество точности, если MP3 находится на частоте дискретизации, отличной от частоты дискретизации микшера.) Mpg123 также исправляет проблемы с «моими MP3 медленными/быстрыми».

- vorbisplug

            Обеспечивает воспроизведение Ogg Vorbis с использованием libogg и libvorbisfile. Поддерживает точки цикла, регулировку громкости ReplayGain и поиск образцов. Использует встроенную службу повторной выборки M.U.G.E.N для преобразования скорости, где это необходимо. Это должно обеспечить заметно лучший выход, чем воспроизведение микшера по умолчанию SDL.

- sdlmix

            Плагин Wrapper для выбранных BGM-сервисов, предоставляемых микшером SDL. Это означает, что MIDI, MOD и другие файлы трекера.

            Sdlmix выполняет бесшовный цикл от конца до начала файлов BGM (за исключением файлов MOD/tracker, которые естественным образом соединяются). Однако произвольные точки цикла и точки повтора не могут быть указаны.

            Система громкости также была обновлена. В настоящее время имеется настройка громкоговорителя, настройка громкости voice/sfx и настройка громкости BGM звука. Вот и все. Настройки громкости - это числа с плавающей запятой между 0% и 100% и умножаются вместе, чтобы дать конечный финальный звук. Плагины также могут иметь индивидуальные множители.

            Для звуковых эффектов произведение всех объемных шкал (master volume, wave volume и любые дополнительные масштабные коэффициенты в случае CNS) не могут превышать 100%. Если продукт слишком велик, он уменьшается до 100%. Для плагинов значение шкалы громкости, превышающее 100% (после включения масштабирования объема плагина) зависит от конкретного плагина.

            Изменения в mugen.cfg

- [Options] WavVolume и MidiVolume удалены (они стали лишними).
- [Sound] Добавлены параметры SampleRate и BufferSize. Они управляют параметрами микшера. Подробнее см. комментарии в mugen.cfg.
- [Sound] ModVoices, MasterWavVolume, MidiVolume, MP3Volume, ModVolume, CDAVolume параметры удалены.
- [Sound] Добавлен параметр SFXResampleMethod. Он указывает, как выполнять преобразование скорости звуковых эффектов. SDL-метод использует встроенное преобразование SDL, которое не выполняет интерполяции. Это относительно быстро, но дает
               результаты низкого качества. Метод libresample выполняет ограниченную интерполяцию, которая имеет более высокое качество, но может замедлить загрузку на небольшую величину и требует больше рабочей памяти. Если вы используете
               параметр libresample, вы можете установить SFXResampleQuality в 1 для еще более высокого качества за счет увеличения использования ресурсов.
- [Sound] Добавлен параметр BGMResampleQuality. Это работает так же, как SFXResampleQuality, но для музыки. Обратите внимание, что libresample всегда используется для преобразования скорости музыки; Преобразование SDL не поддерживается.
- [Sound] MasterVolume, WavVolume, BGMVolume параметры используемые для управления томами. Их также можно включить на экране в «Options».
- [Music] Музыкальная группа добавлена для спецификации плагина.
- [Misc] SFXBackgroundMode настраивает, как звуки должны воспроизводиться в фоновом режиме. Выберите Mute «Отключить звук» или Play «Воспроизвести».
- [Misc] BGMBackgroundMode настраивает, как музыка должна воспроизводиться в фоновом режиме. Выберите Mute «Отключить звук», Pause «Пауза» или Play «Воспроизвести».

            Изменения в CNS

- [Data] Параметр «volume» теперь игнорируется. Используйте «volumescale», чтобы указать коэффициент масштабирования фактора в процентах (100, т.е. никаких изменений, по умолчанию).
- (PlaySnd) параметр «volume» теперь игнорируется. Используйте «volumescale», чтобы указать коэффициент масштабирования звука в процентах.

            Новые параметры арены

- [Music] bgmvolume (заменяет bgvolume)

            Bgmvolume - множитель с плавающей запятой для звуков арены. 100% без изменений. Старый параметр «bgvolume» устарел и игнорируется.

- [Music] bgmloopstart, bgmloopend

            Определяет начальную и конечную точки музыки в цикле. Если они установлены, и цикл включен, музыка будет воспроизводиться от начала до заданной точки, а затем продолжит цикл из цикла, чтобы заданным циклом работать бесконечно. Точная спецификация этих параметров зависит от плагина. Для mpg123 точки цикла указываются в терминах образца. Никакие другие плагины не поддерживают точки повтора в настоящее время. Bgmloopstart по умолчанию - 0 (начало), а bgmloopend по умолчанию - -1 (конец файла).

            Новые параметры системы

- [Music] {title, select, vs, victory экраны}.bgm.loopstart (также loopend и volume).
- [Demo Mode] fight.stopbgm

            Если fight.playbgm = 0, то установка fight.stopbgm = 0 позволяет титульному BGM продолжить воспроизведение во время Demo mode.

            Новые параметры заставки (storyboard)

- bgm.loopstart, bgm.loopend


Материал перевел и подготовил Sceletron

0

3

Информация предоставлена с официального сайта Elecbyte

          Формат CNS         

            Введение

            Файл CNS игрока выполняет две цели:

1. Он определяет переменные этого игрока, такие как скорость ходьбы, графика рисования и т.д.
2. Он содержит состояния игрока, которые описывают все движения, которые игрок может сделать. States - это строительные блоки, которые можно использовать для создания простых, а также сложных ходов.

            Как и многие другие файлы персонажа, CNS - это текстовый файл, который вы можете редактировать с помощью любого текстового редактора.

            В CNS файле точка с запятой (;) считается символом «для комментариев» персонажа. Любой текст в той же строке после точки с запятой будет проигнорирован программой. CNS в основном не учитывает регистр, т. Е. «MyName» обрабатывается так же, как «myname» и «mYnAMe». Единственным исключением является командный триггер (подробно описанный в документации CMD).

            Некоторая терминология

            Когда мы говорим «группа», мы подразумеваем любой блок из строк текста, начинающийся с того, что выглядит как [groupname], и заканчивается перед следующей группой. Например, группа Foo состоит из первых трех строк в следующем:

[Foo]
линия1
линия2

[Group 2]
еще больше линий

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

[SomeGroup]
value1 = 1234
value2 = "строка"

            Эквивалентно:

[SomeGroup]
value2 = "строка"
value1 = 1234


            Переменные персонажа

            Пока нет полной документации. См. Chars/kfm/kfm.cns для комментариев к каждой переменной.

            Некоторые важные примечания:
- В [Size] вы можете использовать xscale и yscale для изменения ширины и высоты вашего персонажа. Это избавляет от необходимости масштабировать каждый из спрайтов.
- Настройте скорости игрока в разделе [Velocity]
- Установите ускорение игрока вниз - yaccel в [Movement]


            Состояния States

            Анимации и звуки являются наиболее заметными проявлениями персонажа MUGEN, но истинным «сердцем» этого символа является его CNS файлы. Файл CNS, также известный как файл состояний персонажей, содержит коды, которые фактически дают персонажу его функциональность - позволяя ему выполнять ходы при командовании, ударять своего противника или подчиняться закону силы тяжести.

            Структура файла CNS проста. Код организован в логические группы, называемые [StateDef]s. Блоки [StateDef] нумеруются, а типичный персонаж может содержать сотни из них. Внутри каждого [StateDef] имеется ряд блоков [State], также известных как контроллеры состояний. Каждый контроллер State представляет собой пару trigger - действий: он определяет некоторые действия для персонажа и принимает условия, при которых это действие должно быть выполнено.

            В каждый момент (tick) игрового времени, персонаж выполняет код в некотором [StateDef] блоке. Например, если персонаж лениво стоит, то он обычно выполняется в блоке [StateDef 0]. Для краткости мы говорим, что персонаж «находится в состоянии 0». При каждом tick (счет игрового времени), когда персонаж находится в состоянии 0, он будет оценивать контроллеры состояния в блоке [StateDef 0] сверху вниз, проверять условия и принимать любые действия, которые там указаны. Если персонаж должен измениться на какой-либо другой блок [StateDef], скажем, чтобы указать состояние state 417, поскольку он выполняет перемещение, он может выполнить контроллер состояния ChangeState, чтобы переключиться. Затем персонаж начнет выполнять код в [StateDef 417] точно таким же способом.

            Каждый персонаж MUGEN дополнительно имеет три специальных состояния с номерами -1, -2 и -3. Это единственные допустимые состояния с отрицательными числами. Состояние state -1 обычно содержит контроллеры состояния, которые определяют правила перехода состояния на основе пользовательского ввода команды (commands). Состояние state -2 содержит другие контроллеры состояния, которые необходимо проверять каждый tick. Состояние state -3 содержит контроллеры состояния, которые проверяются каждый тик, если игрок временно не использует данные состояния другого игрока (например, когда игрока бросают).

            Чтобы собрать все вместе: для каждого tick игрового времени MUGEN делает один проход через каждое из специальных состояний сверху вниз, в порядке увеличения номера состояния (-3, -2, затем -1). Для каждого столкновения контроллера состояния, его типовые (type) триггеры условия оцениваются и, если они выполнены, контроллер выполняется. Затем обработка переходит к следующему контроллеру состояния в состоянии state. Переход состояния (ChangeState) в любом из специальных состояний обновит текущий номер state состояния игрока и прервет обработку оставшейся части этого состояния. После того, как все контролеры состояния в специальных состояниях были проверены, текущее состояние игрока обрабатывается снова сверху вниз. Если переход состояния выполняется из текущего состояния, остальные контроллеры состояния (если есть) в текущем состоянии пропускаются, а обработка продолжается с начала нового состояния. Когда достигнут конец текущего состояния и не происходит переход состояния, обработка останавливается для этого тика (tick).

            Существует одно исключение из приведенного выше сценария. Если персонаж является «вспомогательным» (helper) персонажем, то есть порожденным контроллером состояния Helper, этот персонаж не будет иметь особых состояний state -3 и -2. Персонаж helper не будет иметь специального состояния state -1, если только оно не включено. (Это контролируется контроллером состояния Helper при создании персонажа.)

            Введение в States

            Программирование состояний states является самой сложной частью создания персонажа. Это влечет за собой много работы, тестирования, а иногда и проб и ошибок. В этом разделе мы часто будем говорить про программирование игрока, а также и его противника. Назовем игрока, чьи состояния мы будем редактировать P1, и его противника P2.

            Не озадачивайте себя, если вы многого не понимаете из этого документа в своем первом чтении. Лучший способ узнать о состояниях states - сначала поиграть со значениями (values) в CNS завершенного персонажа и посмотреть, какие последствия есть у него или у неё. Не стоит бояться «настройки» CNS; M.U.G.E.N предназначен для обнаружения ошибок синтаксиса и сообщает о них.

            В комплект поставки дистрибутива M.U.G.E.N входит персонаж с именем Kung Fu Man (короткая версия KFM). Его можно найти в каталоге chars/kfm.

            Файл CMD содержит декларации имен команд и определение состояния State -1, специального состояния, которое используется для управления тем, как персонаж отвечает на ввод пользователя.

            Ниже приведены некоторые концепции, которые будут полезны для вас.

            Жизнь и энергия

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

            Контроль

            Когда мы говорим, что игрок «имеет контроль», мы имеем в виду, что он готов ходить или прыгать или атаковать. Игрок, у которого нет контроля, не будет реагировать на ваши нажатия (с клавиатуры или джойстика). Например, когда P1 находится в состоянии ожидания, он имеет контроль и будет двигаться вперед, если вы нажмете кнопку «вперед». Игрок, как правило, не имеет контроля, когда он находится в состоянии атаки, иначе вы могли бы просто уйти на полпути во время удара.

            Однако существует исключение из правила. Иногда вы можете позволить игроку реагировать на определенные ходы, даже если у него нет контроля. Это называется «прерыванием перемещения» или «отменой хода».

            Мы будем часто ссылаться на «контрольный флаг» игрока. «Flag» - это значение (value), которое является либо true, либо false.

            Игровое время и время состояния state

            M.U.G.E.N отслеживает время, прошедшее в игре. Каждый раз, когда игра обновляется (это включает в себя обновление игроков, проверку блоков ударов и изображения на экране), мы говорим, что время игры увеличилось на единицу. Время, которое игрок провел в состоянии state, называется «временем состояния». Время состояния начинается с 0 в начале состояния state и увеличивается на один тик за каждый тик игрового времени.

            Положение, скорость и ускорение

            Те из вас, кто имеет базовые знания математики, должны понимать эти понятия. M.U.G.E.N использует следующую систему координат. Чем больше X-позиция, тем правее игрок. Чем меньше X-позиция, тем ближе он находится к левому игроку. Y-позиция нуля равна уровню земли. По мере того как Y-позиция игрока увеличивается, он движется вниз. Например, отрицательное положение оси Y означает, что игрок находится в воздухе. Точно так же, когда мы говорим, что игрок имеет положительную X-скорость, это означает, что он движется вперед, а если он имеет отрицательную X-скорость, то движется назад. Игрок с положительной Y-скоростью движется вниз, а отрицательная Y-скорость означает, что он движется вверх. Положительное X-ускорение означает, что X-скорость игрока увеличивается, отрицательное X-ускорение означает, что его X-скорость уменьшается. Аналогично и для Y-ускорения.

            "Жонглирование"

            M.U.G.E.N допускает определенные движения «жонглировать», то есть ударять противников, которые были поражены в воздухе, или лежат на земле. Система жонглирования работает так: каждый человек начинает с заданного количества жонглирующих «очков», начиная с первого удара, который заставляет противника падать, "очков" обычно 15.

            Быстрая терминология: когда мы говорим, что игрок «падает», значит, он не восстанавливает контроль в воздухе и упадет на землю.

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

            Например, атака, требующая 7 жонглирующих очков, теоретически может использоваться для жонглирования противника дважды (при условии, что вы начали с 15 очков), оставив противнику 1 очко на выход. Последующие атаки будут пропущены.

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

            Основные части состояния States

            Примечание. В этом разделе предполагается, что вы, по крайней мере, просмотрели документацию по файлам формата AIR и поняли понятия анимации, так как знаете смысл ключевых слов и фраз, таких как действие и элемент действия.

            Вот краткое примерное состояние для P1:

[Statedef 200]
type = S
physics = S
movetype = I
ctrl = 0
anim = 200
velset = 0

[State 200, 1]
type = ChangeState
trigger1 = AnimTime = 0
value = 0
ctrl = 1

            Это состояние воспроизводит действие 200 анимации P1 и возвращает P1 в свое состояние после окончания анимации. В этом случае предположим, что действие 200 имеет конечное время цикла. То есть в действии 200 нет элементов со временем, равным -1.

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

            Все States должны иметь один раздел Statedef и один или несколько State разделов.

            Statedef содержит начальную информацию о состоянии, такую как состояние (стойка, приседание, в воздухе) и какой ход он делает (атакующий, бездействующий).

            Каждый раздел состояния называется state контроллером или кратковременным контроллером. Контроллеры сообщают программе, что делать с P1, и когда это делать. Существует много видов контроллеров, каждый со своей собственной функцией. Например, есть контроллеры для изменения положения или скорости игроков, определения эффектов атак, создания снарядов, переключения между действиями анимации, состояниями изменения и т.д. Каждый контроллер должен иметь по крайней мере один триггер. Триггер - это событие, которое вызывает активацию контроллера. Примерами являются: триггер в начале состояния, триггер в конце анимации (как показано в примере выше), триггер по элементу анимации Action, триггер, когда P2 находится в пределах определенного диапазона P1, и так далее.

            Подробная информация о StateDef

            Каждый state должен начинаться с одной группы StateDef, также известной как раздел Statedef. Группа StateDef должна выглядеть так (укажите один или несколько параметров, где находятся точки):

[Statedef state_number]
. state_parameters
.
.

            Замените state_number номером состояния state, которое вы программируете. За исключением номеров специальных групп (см. приложение A), вы можете использовать любой номер state, который вы выберете. Чтобы избежать выбора номера специальной группы, не выбирайте числа от 0-199 и между 5000-5999.

            Следующие строки должны включать следующие основные параметры:

- type
- movetype
- physics
- anim

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

- velset
- ctrl
- poweradd
- juggle
- facep2
- hitdefpersist
- movehitpersist
- hitcountpersist
- sprpriority

            type

            Это type состояния P1 в состоянии state. Он определяет, будет ли игрок стоять, приседать, быть в воздухе или лежать. Соответствующими значениями являются «S», «C», «A» и «L» соответственно (без кавычек). Чтобы оставить тип неизменным из предыдущего состояния, используйте значение «U». Если эта строка отключена, предполагается, что тип «S». Обычно вы будете использовать «S», «C» и «A». Например, для состояния type crouching (приседание) требуется строка:

type = C

            Type используется для определения нескольких факторов, что наиболее важно, как P1 будет реагировать на попадание. Например, находясь в состоянии type «stand» (стойка), P1 будет реагировать так, как будто он стоит на земле. Если type «air» (воздух), то P1 будет реагировать на попадание соответственно.

            S - Standing (стойка), C - Crouching (приседание), A - in Air (в воздухе), L - Lying down (лежать), U - Unchanged (без изменений).

            movetype

            Это тип перемещения P1: «A» (attack) для атаки «I» (idle) для простоя и «H» (hit) для попадания (получения удара). Чтобы оставить movetype неизменным из предыдущего состояния, используйте значение «U» (unchanged). Значение считается «I», если эта строка отсутствует. «A» и «H» должны быть понятными. «I» используется для состояний, в которых P1 не атакует и не получает урон. Например, состояние атаки должно иметь строку:

movetype = A

            Вам нужно указать тип movetype, чтобы программа знала, как обрабатывать состояние. Неправильное указание movetype может привести к некорректной работе P1.

            physics

            Вам нужно указать, какую физику использовать в этом состоянии. Допустимые значения: «S» (stand) для стойки, «C» (crouching) для приседания, «A» (air) для воздуха, а «N» (none) - нет. Чтобы оставить физику без изменений из предыдущего состояния, используйте значение «U» (unchanged). Если отсутствует или отключено, предполагается значение «N». Тип физики используется для определения поведения P1.

- Для физики «S» P1 будет испытывать трение с землей. Значение коэффициента трения задается в Переменных персонажа.
- Для физики «C» P1 будет испытывать трение, как в состоянии «S».
- Для физики «А» P1 будет ускоряться вниз, и если его Y-позиция больше 0 (то есть он касается земли), он сразу же войдет в свое состояние приземления.
- Если вы используете «N», P1 не будет использовать какую-либо из этих предварительно запрограммированных физик.

            Не путайте «physics» со состоянием «type». Они, как правило, одинаковы, но вам предоставляется выбор, если вы хотите больше контроля движений. Например, вы можете использовать «N» (без физики) и указать свое собственное определение ускорения и посадки для воздушного состояния.

            anim

            Этот параметр изменяет действие анимации P1. Укажите номер действия в качестве значения. Если вы не хотите, чтобы P1 менял анимацию в начале состояния, отключите этот параметр.

            Таким образом, чтобы иметь состояние с номером 400, где игрок совершает атаку в положении сидя с действием 400, типичными параметрами будут:

[Statedef 400]
type = c
movetype = a
physics = c
anim = 400

            velset

            Вы можете использовать velset для установки скорости P1 в начале состояния. Формат представляет собой числовую пару, представляющую скорость X и Y-скорость соответственно. Отключая эту линию, скорость P1 останется неизменной. Например,

velset = 4,-8

            P1 начинает перемещаться по диагонали вверх и вперед.

            Есть исключение из этого. Даже если у вас есть velset = 0, атака P2 в углу будет отталкивать P1.

            ctrl

            Этот параметр установит управление P1. Значение «0» устанавливает флаг в false, «1» устанавливает его значение true. Если этот параметр отключен, флаг управления P1 остается неизменным. Например, чтобы дать управление P1, используйте

ctrl = 1

            poweradd

            При включении параметра poweradd, добавляется энергия в панель энергии игрока. Значение - это число и может быть положительным или отрицательным. Этот параметр обычно используется в атаках, где вы хотите, чтобы игрок мог получить энергию, просто выполняя атаку. Например, чтобы добавлялось 40 энергии при атаке, введите

poweradd = 40

            juggle

            Параметр жонглирования полезен только для атак. Он определяет, сколько точек жонглирования требуется. Если пропустить для атаки, эта атака будет жонглировать, если предыдущее атакующее состояние успешно жонглировало. Вы должны включить параметр  juggle для всех атак. Если атака охватывает более одного состояния state, включите параметр juggle только в первом состоянии этой атаки. Для подробностей см. выше в этом посте "Жонглирование".

            facep2

            Когда вы включаете линию facep2 = 1, игрок будет повернут, если необходимо, лицом к противнику в начале состояния. Facep2 имеет значение по умолчанию «0», если оно отключено или отсутствует.

            hitdefpersist

            Если установлено значение 1, любые HitDefs, которые активны во время перехода состояния в это состояние, будут оставаться активными. Если установлено значение 0, значение по умолчанию, любые такие HitDefs будут отключены, когда будет выполнен переход состояния.

            movehitpersist

            Если установлено значение 1, информация о переходе из предыдущего состояния (независимо от того, атакована или пропущена, защищена и т.д., см. триггеры «Move*» в документе триггеров), будет перенесена в это состояние. Если установлено значение 0 (по умолчанию), эта информация будет сброшена при входе в это состояние.

            hitcountpersist

            Если установлено значение 1, счетчик ударов (количество ударов этой атаки) будет перенесен из предыдущего состояния в это состояние. Если установлено значение 0 (по умолчанию), счетчик сбрасывается при переходе состояния. Этот параметр не влияет на combo счетчик, который отображается на экране. См. документацию триггера HitCount и UniqHitCount о том, как проверить счетчик попаданий.

            sprpriority

            Если этот параметр присутствует, приоритет наслаивания спрайтов игрока будет установлен на указанное значение. Если отключено, приоритет спрайта останется без изменений. Common1.cns (файл CNS, который унаследован каждым игроком) определяет приоритет спрайта для постоянных или приседающих игроков равным 0, а прыгающие игроки имеют 1. Для большинства состояний атаки вам нужно установить sprpriority = 2, чтобы атакующий появился впереди.

            См. sprprriity в документации state контроллеры о том, как изменить приоритет спрайта с помощью контроллера.

            Подробная информация о State контроллерах

            Формат контроллера

            Все состояния должны иметь как минимум один контроллер состояния State Controller, иначе это приведет к ошибке. Группы state controller имеют следующий формат:

[State state_номер, некоторое_число]
type = controller_type
trigger1 = condition_exp
<универсальные необязательные параметры>
<дополнительные параметры в зависимости от контроллера>

            State_номер должен быть одним и тем же номером состояния из StateDef. Некоторое_число может быть любым количеством, которое вы выберете; Это число, которое сообщается при обнаружении ошибки, поэтому вы знаете, какой контроллер необходимо устранить.

            Универсальными (применимыми ко всем state controller) дополнительными параметрами являются параметры ignorehitpause и persistency. Если ignorehitpause установлен в 1, MUGEN проверяет этот контроллер состояния, даже если персонаж приостановлен ударом. В противном случае этот контроллер состояния не будет проверяться во время паузы при нажатии. По умолчанию 0, что рекомендуется для всех, кроме исключительных ситуаций. Для объяснения параметра persistency см. «Триггер постоянства» в этом посте.

            Controller_type - это имя используемого контроллера. Каждый тип контроллера имеет разный эффект и требует разных параметров. См. state контроллеры для полного списка контроллеров состояния.

            Порядок контроллеров значителен. Контроллеры, перечисленные первыми, являются проверенными и, если необходимо, активируются первыми.

            Ниже приведен пример контроллера, который дает управление P1 в начале состояния (тот же эффект, что и установка ctrl = 1 в качестве параметра в StateDef):

[State 300, 1] ;State 300. 1 - просто произвольное число.
type = CtrlSet ;Изменяет флаг управления.
trigger1 = Time = 0
value = 1

            В этом примере тип CtrlSet позволяет вам изменить флаг управления P1. Строка, которая считывает trigger1 = Time = 0, означает, что этот контроллер активируется, когда время состояния равно 0, то есть в начале этого состояния. Значение строки value = 1 говорит о том, что мы хотим установить значение флага управления равным 1, что означает true. Если мы хотим, чтобы P1 запустил состояние без управления, нам просто нужно изменить последнюю строку на value = 0.

            Давайте посмотрим на другой пример. Этот контроллер перемещает P1 вперед на 10 пикселей дважды: на второй и третий элемент его текущей анимации. Не беспокойтесь, если вы не знаете, какие параметры идут с помощью каких типов контроллеров. Вы можете узнать больше о них из документации state controller (здесь).

[State 300, 2]
type = PosAdd                  ;Добавляет к позиции P1
trigger1 = AnimElem = 2 ;Триггер второго элемента.
trigger2 = AnimElem = 3 ;Триггер на 3-м элементе.
x = 10

            Как вы видите выше, каждый контроллер должен иметь по крайней мере один триггер. Триггер - это условие, при котором контроллер активируется. В этом примере два триггера, и контроллер активируется, когда один из них является true.

            Триггеры

            Логика триггера

            Первый триггер должен всегда быть trigger1, а последующие триггеры должны быть trigger2, затем trigger3 и так далее. Логикой для принятия решения о том, должен ли быть активирован контроллер, является:

1. Все ли условия триггера истинны (true)? Если да, то да, активируйте контроллер.
2. В противном случае повторите тест для trigger2 и т.д., пока не будет найдено больше триггеров.

            Это можно рассматривать как «ИЛИ» логики.

            Будьте осторожны; пропуск числа приведет к игнорированию некоторых триггеров. Например, если у вас есть триггеры trigger1, trigger2 и trigger4 без trigger3, то trigger4 будет проигнорирован.

            Теперь, если вы хотите, чтобы перед запуском контроллера было выполнено более одного условия? Вот часто используемый пример для тестирования, если игрок в воздухе, достиг земли. Используемые триггеры:

trigger1 = Vel Y > 0  ; True если Y-скорость > 0 (спускается)
trigger1 = Pos Y > 0 ; True если Y-позиция > 0 (под землёй)

            На этом этапе вас может смутить формат триггера. На счет этого вопроса не беспокойтесь. Мы скоро доберемся до него.

            Как вы можете видеть выше, оба триггера имеют одинаковое число. Когда несколько триггеров имеют одинаковое число, он реализует «И» логику. То есть, контроллер активируется, если каждый из триггеров с одинаковым числом является true, но не когда один или несколько из них являются false.

            Вы можете объединить обе идеи. Например:

trigger1 = Vel Y > 0 ; True Если Y-скорость равна > 0 (спускается)
trigger1 = Pos Y > 0 ; True если Y-позиция > 0 (под землёй)
trigger2 = Time = 5  ; True, если время состояния равно 5

            Контроллер для этого был бы активирован, если игрок приземлился на землю (Y-скорость и Y-позиция оба равны > 0), ИЛИ, если его состояние было 5.

            Вот резюме:

- Триггеры с одинаковым номером активируют контроллер только в том случае, если все они являются true.
- Триггеры с разными номерами активируют контроллер, если один или несколько из них являются true.

            Формат триггера:

trigger? = condition_exp

            Condition_exp это арифметическое выражение для проверки на равенство 0. Если condition_exp равно 0, то триггер имеет значение false. Если condition_exp отличное от нуля, то триггер имеет значение true. Condition_exp обычно является простым реляционным выражением, как в приведенных выше примерах, но может быть как простым, так и сложным, если необходимо.

            Можно использовать логические механики между выражениями. Например, это эквивалентно предыдущему примеру выше.

trigger1 = ((Vel Y > 0) && (Pos Y > 0)) || Time = 5

            См. «Выражения» далее в этом посте, для подробного объяснения арифметических выражений.

            Полезным ярлыком, который вы можете использовать, является triggerall. Он задает условие, которое должно быть истинным для всех триггеров. Например, рассмотрим:

triggerall = Vel X = 0
trigger1 = Pos Y > -2
trigger2 = AnimElem = 3
trigger3 = Time = [2,9]

            Для любого из trigger1 до trigger3, которые должны быть проверены, условие triggerall должно быть true. В этом случае, пока X-скорость не равна 0, контроллер состояния не будет активирован. Если вам нужно, вы можете иметь более одного условия triggerall. Обратите внимание, как минимум один trigger1 должен присутствовать, даже если вы укажете triggerall.

            Триггер постоянства

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

[State 310, 1]
type = PosAdd
trigger1 = Vel Y > 1
x = 10

            Этот контроллер состояния перемещает P1 вперед на 10 пикселей для каждого тика игрового времени, когда Y-скорость P1 больше 1. То есть, контроллер активируется каждый раз, когда условие триггера true. Если мы хотим, чтобы контроллер был активирован только один раз, нам нужно будет добавить строку:

[State 310, 1]
type = PosAdd
trigger1 = Vel Y > 1
persistent = 0       ;<-- Добавьте эту строку
x = 10

            Peristent имеет значение по умолчанию 1, что означает, этот контроллер активируется каждый раз, когда триггер является true. Установка persistent 0 позволяет активировать контроллер только один раз во время этого состояния. Это верно, пока P1 не покинет это состояние. Если P1 вернется к этому состоянию позже, контроллер может быть активирован еще раз.

            Постоянный параметр также может принимать значения, отличные от 0 и 1:

[State 310, 1]
type = PosAdd
trigger1 = Vel Y > 1
persistent = 2       ;<-- Измените эту строку
x = 10

            В этом случае установка persistent на 2 означает, что контроллер будет активирован один раз каждые 2 раза, когда триггер будет true. Настройка persistent на 3 активирует контроллер каждые 3 раза и т.д.

            Trigger перенаправление

            Возможно, вы захотите проверить время жизни цели игрока или исходного игрока (если игрок является помощником) и т.д. Это возможно с помощью так называемого триггерного перенаправления. Подробнее см. в разделе «Выражения» этого поста.


            Часто используемые контроллеры

            Контроллер null будет полезен для отладки. Этот контроллер в принципе ничего не делает. Вы можете использовать его для временного отключения некоторых контроллеров, вместо того, чтобы закомментировать весь раздел. Например, вы можете отключить это:

[State 300, 1] ;Контроллер, который ускоряет P1 вперед
type = VelAdd
trigger1 = Time >= 0
x = .8

            Просто закомментируйте type и поставьте null:

[State 300, 1] ;Контроллер, который ускоряет P1 вперед
type = null ;VelAdd
trigger1 = Time >= 0
x = .8

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

            Теперь давайте рассмотрим пример:

[Statedef 200]
type = S
physics = S
movetype = I
ctrl = 0
anim = 200
velset = 0

[State 200, 1]
type = ChangeState
trigger1 = AnimTime = 0
value = 0
ctrl = 1

            [State 200, 1] является контроллером ChangeState. Как следует из названия, оно изменяет номер состояния P1 (т.е. блок [StateDef], из которого выполняется P1). Параметр value должен иметь номер состояния для изменения. Необязательный параметр ctrl может быть установлен на флаг управления P1, когда он изменяет состояния.

            Теперь давайте сделаем это состояние атакой. Прежде всего, действие анимации требует атаки коллизионных полей. Быстрый обзор документации AIR (см. 1 пост в этой теме): Clsn1 предназначен для атаки, а Clsn2 - это место, куда игрок может попасть. Таким образом, P1 попадет в P2, если любой из блоков P1 Clsn1 будет пересекаться с любым из блоков P2 Clsn2.

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

[Begin Action 200]
200,0, 0,0, 3
200,1, 0,0, 4
200,2, 0,0, 4
200,3, 0,0, 3

            После определения ограничивающих полей это выглядит так:

[Begin Action 200]
Clsn2: 1
  Clsn2[0] = -10,0, 10,-80
200,0, 0,0, 3
Clsn1: 1
  Clsn1[0] =  10,-70, 40,-60
Clsn2: 2
  Clsn2[0] = -100, 10,-80
  Clsn2[1] =  10,-70, 40,-60
200,1, 0,0, 4
Clsn2Default: 1 ;Используйте это поле для последних двух кадров
  Clsn2[0] = -10,0, 10,-80
200,2, 0,0, 4
200,3, 0,0, 3

            Как вы можете видеть, каждый элемент имеет форму Clsn2, определенную для него (последние два элемента используют одни и те же поля). Второй элемент - единственный с полем Clsn1.

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

            Теперь мы готовы настроить состояние в CNS. Объясним приведенные ниже изменения.

[Statedef 200]
type = S
physics = S
movetype = A  ;<-- измените "I" на "A"
ctrl = 0
anim = 200
velset = 0

[State 200, 1] ;<-- добавьте этот state controller
type = HitDef
trigger1 = AnimElem = 2
attr = S, NA
animtype  = Light
damage    = 10
guardflag = MA
pausetime = 12,12
sparkxy = 0,-55
hitsound   = 5,0
guardsound = 6,0
ground.type = High
ground.slidetime = 12
ground.hittime  = 15
ground.velocity = -5
air.velocity = -2.5,-3.5

[State 200, 2]
type = ChangeState
trigger1 = AnimTime = 0
value = 0
ctrl = 1

            Параметр movetype в StateDef имеет значение A для «совершения атаки». Не забудьте сделать это для всех состояний атаки. Как и прежде, P1 возвращается в свое состояние после того, как его анимация закончилась.

            Этот контроллер HitDef выглядит как монстр! Не волнуйтесь, мы рассмотрим его медленно.

type = HitDef
trigger1 = AnimElem = 2

            Это указывает тип контроллера как HitDef, что означает «Определение удара». Он запускается (trigger) во втором элементе анимации. Любой блок Clsn2 с момента активации триггера примет определение этого удара.

            Если, например, у вас был Clsn1 как во втором, так и в третьем элементе анимации, запуск одного HitDef во втором элементе делает его применимым к обоим элементам анимации. Таким образом, P1 ударит не более одного раза: если второй элемент ударит, третий промахнется. Если второй элемент промахивается, третий может по-прежнему ударить. Чтобы атака совершалась дважды, вы должны вызвать trigger HitDef для каждого из двух элементов.

attr = S, NA

            Это атрибут атаки. Он используется для определения того, может ли атака попасть в P2. В этом случае это стойка нормальная атака.

            attr имеет формат attr = arg1, arg2, где:

- arg1 - либо S, C, либо A. Подобно типу statetype для StateDef, это говорит о том, является ли атака стоячей (S), приседающей (C) или воздушной атакой (A).
- arg2 - 2-символьная строка. Первый символ либо N (normal) для «нормального», либо S (special) для «специального», либо H (hyper) для «гипер» (или «супер», как это обычно принято). Второй символ должен быть либо A (attack) «для атаки» (обычный удар атаки), Т (throw) для «броска», либо Р (projectile) для снаряда.

animtype = Light

            Это относится к типу анимации, в которую попадает P2 при совершение ему атаки. Выбирайте из light (легкая), medium (средняя), hard (тяжелая) или back (задняя). Первые три должны быть понятны. Back - это анимация, в которой P2 сбит с ног.

damage = 10

            Это урон, который P2 получает при попадании, и не получает урон, если он защищается (блокирует). Если мы изменим эту строку на damage = 10, 1, тогда это будет наносить 1 пункт урона, когда игрок будет обороняться.

guardflag = MA

            Guardflag определяет, как P2 может защитить атаку. Здесь он может быть защищен высоким High (стойка), низким Low (приседающим) и в воздухе. Аргумент должен быть строкой символов, которая включает любое из следующего: H для «high», L для «low» или A для воздуха. M Mid (середина) эквивалентна выражению HL.

pausetime = 12,12

            Это время, когда каждый игрок останавливается на ударе. Первый аргумент - время заморозки P1, измеренное в tick игры. Второй момент - это время, когда P2 ошеломлен, прежде чем отступить от удара.

sparkxy = 0,-55

            Это - то, где происходит вспышка удара/обороны. Аргументы должны быть в форме X, Y. X относительно фронта P2. Отрицательный X делает вспышку глубже внутри P2. Y относительно P1. Отрицательный Y делает вспышку выше.

hitsound = 5,0

            Это звук, который можно воспроизвести при ударе (из fighter.snd). Включенный fight.snd позволяет вам выбирать от 5,0 (легкий звук удара) до 5,4 (болезненный удар). Чтобы воспроизвести звук из собственного файла SND игрока, перед первым номером следует указать S. Например, hitsound = S1,0.

guardsound = 6,0

            Этот звук играет при обороне (из fight.snd). Сейчас у нас только 6,0. Чтобы воспроизвести звук из собственного файла SND игрока, перед первым номером следует ввести S.

ground.type = High

            Это тип атаки для наземных атак (это также по умолчанию относится и к воздушным атакам, если вы не указали параметр air.type). В данном случае это высокая атака. Выберите High для атак, которые отталкивают голову назад P2, Low для атак, которые выглядят так, как будто они попали в живот, Trip для атаки низкого размаха или None, чтобы ничего не делать с P2. Атаки с High и Low уровнями одинаковы на P2, если AnimType - Back.

ground.slidetime = 12

            Это время в игровых tick, которое P2 отскакивает назад после удара (на этот раз не включено время паузы для P2). Применимо только для ударов, которые удерживают P2 на земле.

ground.hittime = 15

            Время, когда P2 остается в состоянии удара после атаки. Применимо только для ударов, которые удерживают P2 на земле.

ground.velocity = -5

            Начальная скорость X для P2 после получения удара, если P2 находится в состоянии стойки или приседания на земле. Вы можете указать Y-скорость в качестве второго аргумента, если вы хотите, чтобы P2 был выбит в воздух, например ground.velocity = -3, -2.

air.velocity = -2.5,-3.5

            Начальная скорость, которая задается P2, если P2 попал в воздух.

            Есть больше вещей, которые вы можете контролировать в HitDef, тут мы всего лишь разобрали приведенный выше пример. Подробнее см. документацию по sctrls.


            Общие состояния (common1.cns)

            Если вы посмотрите на файл DEF игрока, то увидите строку:

stcommon = common1.cns  ;Общие состояния

            Каждый игрок распределяет некоторые общие состояния, которые являются основными элементами игрового движка. Эти общие состояния находятся в data/common1.cns. Некоторые примеры - состояния для запуска и получения удара. Полный список имеется в Номерах специальных состояний дальше этого поста.

            Если существует общее состояние, которое вы хотели бы переделать для конкретного игрока, все, что вам нужно сделать, это сделать состояние в CNS этого игрока с тем же номером, что и тот, который вы хотели бы переделать. Затем, когда игрок переходит к определенному номеру состояния, он вводит это новое состояние, а не одно в common1.cns.

            Вы должны помнить, что при изменении определенных состояний, которые имеют специальные свойства, закодированные внутри M.U.G.E.N, новые состояния, которые вы делаете, будут по-прежнему иметь те же особые свойства, что и те, которые вы переделали. Например, состояние бега (state 100) задает скорость игрока любым значениям, указанным в его переменных игрока. Если вы измените state 100, новое состояние будет по-прежнему иметь свойство установки скорости игрока.

            Общим примером является переопределение состояния ходьбы. Поведение M.U.G.E.N по умолчанию для текущего состояния состоит в том, чтобы игрок продолжал двигаться вперед с постоянной скоростью, пока вы не отпустите клавишу «вперед». В этот момент он возвращается в состояние ожидания.

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

; {RUN_FWD (перезаписан на type-рывок)
[Statedef 100]
type    = S          ;Ходьба по земле
physics = N         ;Мы определим нашу собственную физику
anim = 100         ;Анимационное действие 100
ctrl = 0               ;Нет контроля за продолжительностью рывка

[State 100, 1]      ;Чтобы начать рывок вперед
type = VelSet
trigger1 = Time = [0,5]
x = 6

[State 100, 2]      ;Трение после первоначального рывка
type = VelMul
trigger1 = Time > 5
x = .85

[State 100, 3] ;
type = ChangeState
trigger1 = AnimTime = 0
value = 0
ctrl = 1

            Здесь мы предполагаем, что Action 100 имеет конечное время цикла. Скорость в run.fwd под [Velocity] переменных игрока не игнорируется, но [State 100,1] переопределяет эту деталь, установив скорость X равным 6.


            Номера специальных состояний

            Если вы не планируете изменять общее состояние, избегайте выбора номеров состояний в диапазоне 0-199 и 5000-5999. Вот список состояний в common1.cns.

           

Номер

Описание

0

Стойка

10

Встать на корточки

11

Приседание

12

Встать с корточек

20

Походка

40

Подготовка к прыжку

45

Начало прыжка в воздух

50

Подпрыгнуть

52

Приземление

100

Бег вперёд

105

Скачок назад

106

Рывок назад (по земле)

120

Оборона (запуск)

130

Стойка обороны (удержание)

131

Оборона сидя (удержание)

132

Оборона в воздухе (удержание)

140

Оборона (окончание)

150

Удар в блок (встряска)

151

Удар в блок (отброшен назад)

152

Удар в блок сидя (встряска)

153

Удар в блок сидя (отброшен назад)

154

Удар в блок в воздухе (встряска)

155

Удар в блок в воздухе (сбит)

170

Проиграл (время кончилось)

175

Ничья (время кончилось)

190

Предварительное вступление

191

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

5000

Стойка, получить удар (встряска)

5001

Стойка, получить удар (отброшен назад)

5010

Сидя, получить удар (встряска)

5011

Сидя, получить удар (отброшен назад)

5020

В воздухе, получить удар (встряска)

5030

В воздухе, получить удар (отброшен)

5035

В воздухе, получить удар (переходное состояние)

5040

В воздухе, получить удар (восстановится, не падение)

5050

В воздухе, получить удар (падение)

5070

Споткнуться, получить удар (встряска)

5071

Споткнуться, получить удар (отброшен)

5071

Споткнуться, получить удар (отброшен)

5080

Сбитый, получить удар (встряска)

5081

Сбитый, получить удар (отброшен назад)

5100

Сбитый, получить удар (удар о землю после падения)

5101

Сбитый, получить удар (отчеканить от земли)

5110

Сбитый, получить удар (лечь)

5120

Сбитый, получить удар (подниматься)

5150

Сбитый, получить удар (умереть)

5200

В воздухе, получить удар (восстановление после падения на землю; продолжение падения)

5201

В воздухе, получить удар (восстановление после падения на землю)

5210

В воздухе, получить удар (восстановление падения в воздухе)

5500

Экран анимации Continue

5900

Инициализация (в начале раунда)


            Продолжение в следующем сообщении этой темы...


Материал перевел и подготовил Sceletron

0

4

Информация предоставлена с официального сайта Elecbyte

          Формат CNS продолжение         

            Выражения

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

            Типы данных

            MUGEN использует три типа данных: 32-битные целые числа, 32-битные плавающие точки (значение float) и специальное нулевое значение «bottom». Целые числа представляют собой целые числа между -2^31 и 2^31-1, или от -2 млрд. до 2 миллиардов. Float представляют собой числа с плавающей запятой с одинарной точностью. То есть, это числа с «десятичной частью» и около 7 значительных цифр точности. Floats могут представлять собой мелкие дроби или очень большие числа.

            Когда вы пишете числа в выражении, MUGEN выводит тип данных из наличия десятичной точки. Таким образом, «7» всегда является целое число, например, если вам нужно 7 в качестве float, вы должны написать «7.0».

            «Bottom» - это особый тип данных, который аннулирует любое выражение, которое оно появляется (с несколькими очень ограниченными исключениями). Его присутствие означает какое-то условие ошибки. Вы должны попытаться закодировать таким образом, чтобы bottom никогда не создавалось. Для получения дополнительной информации вы можете увидеть выделенный раздел bottom далее этого поста.

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

            «Type promotion» происходит, когда значения разных типов данных должны быть скомбинированы (например, путем добавления). Как правило, это означает, что целое число будет изменено на float с возможной потерей точности в этом процессе. В следующих разделах мы рассмотрим любые сценарии продвижения соответствующего типа.

            Арифметические данные

            Арифметические данные позволяют выполнять основные операции, такие как сложение, умножение, деление и т.д. У MUGEN есть выбор данных, которые должны быть знакомы большинству программистов. Они заключаются в следующем:

+
            Добавляет два числа. Если X и Y - оба целых числа, то X + Y также является целым числом. Если оба являются float, то X + Y является float. Если один из них является float, то другой повышается до float, а затем добавляются два floats.

-
            Вычитание чисел. Тип проведения действует так же, как и добавление.

*
            Умножение двух чисел. Тип проведения действует так же, как и добавление.

/
            Деление двух чисел. Если X и Y - оба целых числа, то x/y дает целое частное, т.е. число раз, когда Y равномерно переходит в X. Например, 7/2 = 3. Если X и Y оба являются floats, то x/y возвращает float. Тогда наш предыдущий пример станет 7.0/2.0
            = 3.5. Деление на 0 приведет к значению bottom.

%
            Остаток или мод данные. Если X и Y оба целых числа, то X % Y дает остаток, когда X делится на Y. Если один или оба являются floats, или если Y равно 0, то создается bottom.

**
            Данные возведения в степень. Если X и Y оба являются неотрицательными целыми числами, то X**Y дает целое число, представляющее X, возведенного в степень Y. (Определим 0 ** 0 = 1). Тем не менее, очень легко перегрузить максимально
            возможное значение для целого числа при вычислении больших мощностей. В этих случаях MAX_INT (наибольшее возможное целое число) будет возвращено, и будет оказано предупреждение. Если один из X или Y является отрицательным
            или является float, то оба аргумента повышаются до float, а X ** Y вычисляется как экспоненцирование реальных чисел. Недопустимое возведение в степень, такое как -1 ** .5, приведет к созданию bottom.

!
            Логический оператор NOT (нет). ! X имеет значение 0 (целое число), если X отлична от нуля, а 1 (целое число), если X равно нулю.

&&
            Логический оператор AND (и). X && Y оценивается как 1 (целое число), если X и Y оба отличны от нуля, а 0 (целое число) в противном случае.

||
            Логический оператор OR (или). X || Y оценивается как 1 (целое число), если один или несколько из X и Y отличны от нуля, а 0 (целое число) в противном случае.

^^
            Логический оператор XOR. X ^^ Y оценивается как 1 (целое число), если ровно один из X и Y отличен от нуля, а 0 (целое число) в противном случае.

~
            Битовый оператор NOT. ~ X инвертирует биты X двоичного (второе дополнение) представления. Производит bottom, если X является float.

&
            Битовый оператор AND. N-й бит X&Y устанавливается тогда и только тогда, когда установлены энный бит как X, так и Y. Производит bottom, если X или Y является float.

|
            Битовый оператор OR. N-й бит X|Y устанавливается тогда и только тогда, когда установлен n-й бит X или Y (или у обоих). Возвращает bottom, если любой X или Y является float.

^
            Битовый оператор XOR. Энный бит X^Y имеет значение тогда и только тогда, когда п-й бит точно один из X и Y имеет значение. Возвращает bottom, если любой из X или Y является float.

=
            Оператор равенства. Если X и Y являются как целое число, так и оба float, X = Y оценивается как 1 (целое число), если X и Y равны, и 0 в противном случае. Если ровно один из X или Y является float, то они оба преобразуются во float перед
            тестированием на равенство.

:=
            Оператор присваивания. В левой части должно быть указано имя (var(n) или fvar(n) для подходящих значений n) перенаправляемой переменной. Если левая часть содержит целую переменную, то правая часть усекается до целого числа перед
            назначением. Если левая сторона содержит переменную с float, то правая сторона преобразуется во float, если необходимо перед назначением. В обоих случаях значение выражения - это значение, присвоенное переменной.

!=
            Оператор неравенства. Если X и Y являются как целое число, так и оба float, X!=Y принимает значение 1 (целое число), если X и Y не равны, и 0 в противном случае. Если ровно один из X или Y является float, то они оба преобразуются во float
            перед проверкой равенства.

<
            Оператор меньшего размера. Если X и Y являются как целое число, так и оба float, X<Y принимает значение 1 (целое число), если X<Y, и 0 в противном случае. Если ровно один из X или Y является float, то они оба преобразуются во float перед
            проверкой равенства.

<=
            Аналогично <, за исключением того, что если X = Y, то X<=Y возвращает 1 (целое число).

>
            Оператор большего размера. Если X и Y являются как целое число, так и оба float, X>Y принимает значение 1 (целое число) если X>Y, и 0 (целое число) в противном случае. Если ровно один из X или Y является float, то они оба преобразуются во float
            перед проверкой равенства.

>=
            Аналогично >, за исключением того, что если X=Y, то X>=Y возвращает 1 (целое число).

=[,] !=[,] =[,) !=[,) =(,] !=(,] =(,) !=(,)
            Интервальные операторы. Они принимают три аргумента: X, Y и Z. Если любой из X, Y или Z является float, все они преобразуются во float. После преобразования, если необходимо, X = [Y,Z] эквивалентно (X>=Y) && (X<=Z). Аналогично, X= (Y,Z)
            эквивалентно (X>Y) && (X<Z). Полуоткрытые интервалы имеют очевидный смысл.

            Операторы с отрицательным интервалом работают следующим образом: X!= [Y,Z] эквивалентно (после преобразования, если необходимо) в (X<Y) || (X>Z). X!= (Y,Z) эквивалентно (X<=Y) || (X>=Z). Полуоткрытые интервалы снова имеют очевидный
            смысл.

            Вы можете просмотреть интервальные операторы как производящие соответствующие открытые, закрытые или полуоткрытые интервалы на целых числах или floats. Символ = означает назначение членства в этом контексте.

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

            Приоритет и ассоциативность операторов

            Если рассматривать выражение, подобное 3+2*5, результат будет различным, если вы сначала умножаете * (получается 13), или если вы сначала складываете + (будет 25). Для устранения неоднозначности выражений, подобных этому, операторам присваиваются разные уровни приоритета. В этом случае приоритет умножения * выше, чем приоритет складывания +, поэтому сначала выполняется *, затем к результату применяется +. Поэтому правильный ответ 13.

            Если два оператора имеют одинаковый приоритет, то выражение определяется слева направо, за исключением унарных операторов и оператора присваивания, которые связывают справа налево. Например, * и / имеют одинаковый приоритет, поэтому 5.0*5/6 имеет значение 25.0/6, что соответствует 4.166667. С другой стороны, 5/6*5.0 имеет значение 0*5.0, что соответствует 0.0. Напротив, поскольку унарные операторы связывают справа налево, -!0 сгруппировано как -(!0), которое имеет значение как -(1), которое затем получается -1.

            Если часть выражения сгруппирована в круглые скобки (), то сначала выполняется оценка этой части выражения. Например, в выражении (3+2)*5 сначала выполняется +, давая 5*5, которое затем получает значение 25. Если скобки вложены друг в друга, сначала заключаются самые внутренние скобки.

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

Оператор(ы)

Уровень приоритета

! ~ - (унарные операторы)

Наибольший

**

* / %

+ -

> >= < <=

= != интервалы

:=

&

^

|

&&

^^

||

Наименьший

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

            Синтаксис выражения

            В принципе, любое нормальное арифметическое выражение допустимо. Кроме того, поскольку относительные операторы (>, <= и т.д.) Рассматриваются как рейсы ints, возможно работать с их возвращаемыми значениями, давая некоторые необычные выражения, такие как:

1.0 = (2 = (1 > 0) + !(0 < 1))

            1 > 0 термин имеет значение 1, а термин 0 < 1 имеет значение 0. Следовательно! (0 < 1) принимает значение 1, поэтому выражение упрощается:

1.0 = (2 = 1 + 1)

            Так как 2 = 1 + 1, то термин в скобках имеет значение 1, так что выражение еще более упрощает (после преобразования типа) в

1.0 = 1.0

            который имеет значение 1 (int), так как имеет место равенство.

            Значимым ограничением в синтаксисе выражений является то, что операторы интервалов допускаются только к самой правой стороне выражения. Если часть выражения заключена в круглые скобки, то эта часть считается подвыражением, и в правой части этого подвыражения разрешен интервал. Итак, это хорошо сформированное выражение, которое оценивается как 0:

(1 = [0,2]) = (0,1)

            Но следующее неверно:

1 = [0,2] = (0,1)

            Кроме того, перед интервалом не появляются символы оператора, кроме = или !=. Таким образом, выражение, подобное 5 > [0,2], или 4 + [1,4), не допускается.

            В список параметров, разделенных запятыми, таких как аргументы некоторых триггеров функции типа или параметров для state контроллеров, каждое выражение в списке считается отдельным подвыражение, и, следовательно, интервалы могут появляться в конце этих подвыражений.

            Триггеры состояний type и функций type

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

[State 1234, 5]
type = ChangeState
trigger1 = time = 0
value = 0

            Вся строка «trigger1 = time = 0» является триггером состояния type. Если выражение «time = 0» имеет не нулевое значение, то выполняется контроллер ChangeState. Если выражение «time = 0» равно нулю, то контроллер ChangeState не будет выполнен. Независимо от того, является ли условие нулевым или ненулевым, влияет  запуск триггера.

            С другой стороны, слово «Time», появляющееся в выражении, является триггером функции type. Он возвращает значение, а именно количество времени, в течение которого игрок находился в состоянии State 1234. Обратите внимание, что триггер функции type ничего не запускает. Он просто дает значение, которое может быть использовано внутри выражения.

            Чтобы дополнительно проиллюстрировать разницу, рассмотрим другой state контроллер:

[State 1234, 5]
type = VarSet
trigger1 = 1
v = 0
value = time + 5

            Обратите внимание, что триггер состояния type «trigger1 = 1» не содержит в нем никаких триггеров функционального типа. Поскольку выражение «1» всегда соответствует 1, контроллер будет запускаться каждый кадр. Чтобы определить, какое значение присвоить var0, выражение имеет значение «Time + 5». Триггер функции type «Time» возвращает игрока в начальное положение. Затем добавляется 5, и результат сохраняется в var0.

            Полный список триггеров состояния можно найти в trigger.html.

            В общем, какой из двух типов триггеров является средством, ясно из контекста. Там, где есть некоторая двусмысленность, будут использоваться термины «триггер состояния type» и «триггер функционального type».

            Trigger перенаправление (redirection)

            В приведенном выше примере триггер Time возвратил игрока в начальное состояние. Но иногда, можно проверить statetime цели игрока, или parent игрока (если игрок является помощником) и т.д. Это может быть достигнуто с помощью предшествующего имени триггера ключевым словом, указывающим, чья информация должна быть возвращена. Этот процесс известен как триггер перенаправление (redirection). Например,

5 + (parent, time)

            Возвращает 5 + statetime родителя (parent) игрока.

            Полный список ключевых слов перенаправления:

parent
            Перенаправляет триггер Parent'a игрока. (Игрок должен быть помощником (хелпером)).

root
            Перенаправляет триггер в корневой каталог.

helper
            Перенаправляет триггер на первый найденный помощник. См. соответствующий триггер «NumHelper» в документации триггера.

helper(ID)
            Идентификатор должен быть хорошо сформированным выражением, которое имеет значение положительного целого числа. Триггер затем перенаправляет помощника с соответствующим идентификационным номером.

target
            Перенаправляет триггер на первую найденную цель.

target(ID)
            Идентификатор должен быть хорошо сформированным выражением, которое имеет значение неотрицательного целого числа. Затем триггер перенаправляется на цель с соответствующим целевым идентификатором. Идентификатор targetID указан
            в параметре «ID» контроллера HitDef.

partner
            Перенаправляет триггер партнеру игрока. Обычные помощники и нейтральные игроки не считаются противниками. См. соответствующий триггер «numpartner» в документации триггера.

enemy
            Перенаправляет триггер на первого найденного оппонента. Обычные помощники и нейтральные игроки не считаются противниками. См. соответствующий триггер «numenemy» в документации триггера.

enemy(n)
            n должно быть хорошо сформированным выражением, которое имеет значение неотрицательного целого числа. Триггер перенаправляется на n-го противника.

enemyNear
            Перенаправляет триггер ближайшему противнику.

enemyNear(n)
            n должно быть хорошо сформированным выражением, которое имеет значение неотрицательного целого числа. Триггер перенаправляется на n ближайшего противника.

playerID(ID)
            ID должно быть хорошо сформированным выражением, которое имеет значение неотрицательного целого числа. Триггер перенаправляется на конкретного игрока с уникальным идентификатором, равным номеру ID. См. триггеры «ID» и «PlayerExistID»
            в документации триггера.

            Если триггер перенаправляется на недопустимый пункт назначения (например, если он перенацелен на помощника, когда его не существует), то возвращается назад.

            Примечание: рекурсивное перенаправление (например, «корень, цель, время») не поддерживается.

            bottom

            Существует несколько источников неустранимой ошибки в выражениях. Например, можно попытаться разделить на 0, назначить квадратный корень отрицательным числом или попытаться перенаправить триггер на несуществующее место назначения. В этих ситуациях bottom используется как способ закончить определение выражения. Если bottom появляется где угодно в выражении (с двумя исключениями, которые должны быть указаны ниже этого сообщения: см. Специальные формы), тогда значение всего выражения становится bottom. Например, рассмотрим выражение:

5 + fvar(0) ** 0.5

            если fvar(0) были равны -1 во время оценки, то выражение будет равно 5 + bottom, давая основание.

            Триггеры условия type считают bottom равным 0. Таким образом, выражение, которое генерирует ошибку, никогда не вызовет срабатывание триггера. Так, например, в

type = ChangeState
trigger1 = helper, statetype = A
value = 0

            Контроллер ChangeState никогда не будет выполнен, если не существует помощников, потому что выражение «helper, statetype = A» будет оцениваться как bottom, что равно 0.

            Как правило, предупреждение выводится на консоль отладки MUGEN при создании bottom. Это связано с тем, что наличие bottom указывает на возможную ошибку или двусмысленность в логике. Например, в приведенном выше примере ChangeState, если не существует помощников, то утверждение «helper, statetype = A» пустое, и неясно, следует ли считать его истинным или ложным.

            Специальные формы

            Триггеры IfElse и Cond обрабатывают bottom особым образом. Оба этих триггера принимают форму:

<trigger_name>(<exp_cond>,<exp_true>,<exp_false>)

            <exp_cond> - это выражение условия, которое, в зависимости от того, является ли оно ненулевым, которое возвращает контроль из <exp_true> или <exp_false>. Если bottom создается в выражении, которое не возвращается, то оно не распространяется на остальную часть выражения. Например, рассмотрим выражение IfElse (time> 0, 1.0/time, 2)). Если time>0, то значение выражения равно 1.0/time, что является допустимым значением float. Если time = 0, то значение выражения равно 2, хотя неиспользуемая ветвь делится на 0 и, таким образом, создает bottom.

            Однако, несмотря на то, что вышеуказанный триггер IfElse никогда не возвращает bottom, он все еще имеет раздражающую функцию: деление на 0 все еще генерирует предупреждение для вывода отладки. Это потому, что IfElse оценивает все свои аргументы, даже неиспользуемые. Напротив, Cond будет оценивать только аргументы, которые он использует. Таким образом, если мы перепишем наше выражение как Cond (time>0, 1.0/time, 2), аргумент 1.0/time никогда не будет оцениваться, когда time равно 0, и поэтому не будет генерироваться предупреждение.

            Вы можете задаться вопросом, когда использовать Cond против IfElse. Ответ заключается в том, что вы почти всегда хотите использовать Cond, если только один из <exp_true> или <exp_false> не имеет побочного эффекта, который вам нужен. Другими словами, если вы выполняете назначение переменной в одной из ветвей, которая всегда должна выполняться, независимо от значения <exp_cond>, тогда вам нужно использовать IfElse. В противном случае вы должны использовать Cond, особенно для изоляции bottom.

            Как избежать предупреждений

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

- Принуждение floats к ints
            Если MUGEN ожидает int где-нибудь (например, номер var), но предоставляется float, MUGEN преобразует int во float. Однако он будет жаловаться, потому что это может представлять собой ошибку с вашей стороны. Чтобы избавиться от предупреждения,
            укажите, что вы знаете, что вы делаете, предоставляя явное преобразование в int с помощью floor() или ceil().

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

trigger1 = helper(1234), time > 20

            генерирует предупреждение, если помощник 1234 не существует, но

trigger1 = numhelper(1234) > 0
trigger1 = helper(1234), time > 20

            Не будет. Это связано с тем, что первая строка trigger1 вызывает отмену оценки перед попыткой перенаправления.

            Кроме того, вы можете использовать триггер Cond, чтобы изолировать код, который потенциально может вызвать предупреждение. Предположим, нам нужно выражение, которое дает helper(1234)'у жизнь, если она существует, или в противном случае, жизнь игроку. Тогда мы могли бы написать:

Cond(numhelper(1234) > 0, (helper(1234), life), life)

            (Дополнительные скобки вокруг helper(1234), life не требуется, но улучшают читаемость.)

- Отсутствует требуемая анимация/спрайты
            Это не проблема выражений. Добавьте анимацию/спрайты!

            Выражения в аргументах триггера

            Большинство триггеров функционального типа либо не принимают аргументов, либо принимают аргументы в списке параметров. Например, триггер time не принимает аргументов, тогда как триггер ifelse принимает три аргумента.

ifelse(exp1,exp2,exp3)
            Где exp1, exp2 и exp3 - все допустимые выражения. В такой ситуации exp1, exp2 и exp3 считаются отдельными подвыражениями, поэтому интервалы могут появляться на самом крайнем конце каждого из этих подвыражений. Порядок определения списков
            параметров - слева направо.

            Из-за нерегулярного синтаксиса некоторые старые триггеры функции type не могут принимать выражения в качестве своих аргументов. Из-за этого они не могут быть интегрированы в выражения стандартным образом. Для нестандартных триггеров этого типа триггеры могут появляться только с определенными наборами операторов и аргументов (которые описаны в trigger.doc). В частности, эти триггеры не могут принимать выражения в качестве аргументов. Например,

trigger1 = AnimElem = (1+1)

            является недопустимым выражением.

            Триггеры типа «старого стиля» появляются только в «предложениях» формы «триггер, реляционный оператор, аргумент». Эти положения рассматриваются как единое целое (в частности, единственный пусковой механизм) для целей определения выражения. Это означает, среди прочего, что понятие приоритета оператора не применимо к операторам, появляющимся в статическом стиле триггера функционального типа. Например, в

trigger1 = AnimElem = 5 + 4

            выражение разбивается на три единицы:

AnimElem=5    +    4
|_________|  |_|  |_|

            Единица «AnimElem = 5» рассматривается как имя пустого триггера, поэтому оператор + не имеет приоритета над =, появляющимся в имени «AnimElem = 5». Другими словами, это выражение означает нечто вроде «Выполнить триггер под названием« AnimElem = 5 », а затем добавить 4 к результату».

            Некоторые триггеры функционального типа в старом стиле имеют замены, совместимые с выражением. Это следующие:

- AnimElem, замененный AnimElemTime
- TimeMod, замененный оператором %
- ProjHit, ProjContact, ProjGuarded; заменяется ProjHitTime, ProjContactTime и ProjGuardedTime

            Полный список нерегулярных триггеров см. в файле trigger.html. Нерегулярные триггеры отмечены знаком ***.

            Выражения в state и параметрах состояния state контроллера

            По большей части, любой параметр для statedef или state контроллера состояния может быть выражением. Исключениями являются параметры, которые задаются как строки. Например, атрибуты hit, guardflags и т.д. Не могут быть указаны как выражения. Кроме того, параметры ignorehitpause и persistent (во всех контроллерах) являются нерегулярными, поскольку они не могут принимать выражения.

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

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

            Организация для повышения эффективности

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

            MUGEN оценивает триггеры состояния type для state контроллера в следующем порядке: Сначала он оценивает triggerall, сверху вниз. Если какой-либо из triggerall оценивается в 0, остальные триггеры пропускаются, и оценка переходит к следующему контроллеру. Если все triggeralls оцениваются как ненулевые, то движок игры начинает оценивать trigger1 сверху вниз. Если какой-либо из них оценивается в 0, тогда оценка переходит к первому trigger2 и так далее. Если все триггеры в блоке (помимо triggerall) оцениваются как ненулевые, то параметры state контроллера оцениваются и контроллер запускается.

            Другими словами, логическая оценка триггеров закорочена. В C-подобной нотации эту установку можно обозначить

triggerall,1 && triggerall,2 && ... && ((trigger1,1 && trigger1,2
  && ...) || (trigger2,1 && trigger2,2 && ...) || ... )

            где (например,) trigger1,2 обозначает вторую строку trigger1; trigger2,1 обозначает первую строку trigger2; и т.п. Логическая оценка этой триггерной группы затем была бы короткозамкнутой, как в C.

            Из-за этой системы значительный выигрыш в эффективности может быть достигнут путем организации выражений, чтобы триггеры type условия были максимально простыми и максимально возможными. Основная часть «работы» может быть выгружена в параметры state контроллера, которые оцениваются только один раз во время запуска, а не каждый кадр, в котором игрок находится в состоянии. Например,

[State -1]
type = ChangeState
trigger1 = command = "a"
trigger1 = power < 1000
value = 3000

[State -1]
type = ChangeState
trigger1 = command = "a"
trigger1 = power >= 1000
value = 3001

[State -1]
type = ChangeState
trigger1 = command = "a"
trigger1 = power >= 2000
value = 3002

            может быть более компактно выражены как:

[State -1]
type = ChangeState
trigger1 = command = "a"
value = 3000 + (power >= 1000) + (power >= 2000)

            Вы также можете помочь движку, установив триггеры, которые, скорее всего, будут ложными в верхней части блока triggerall. Аналогично, блок trigger1 должен быть наиболее вероятным блоком для запуска, но в самом блоке trigger1 триггеры, которые, скорее всего, будут вычисляться до 0, должны быть размещены превыше. Для state контроллеров со многими триггерами, содержащими повторяющиеся условия, может быть лучше разбить контроллеры на два отдельных блока, каждый со своим набором триггеров.

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

trigger1 = (command="abc" && command!="holddown" && power>=1000) ||
           (command="abc" && command!="holddown" && var(5)) ||
           ((command != "abc" || command = "holddown") && power>=2000)

            может быть записано как (предполагая, что var(0) доступен):

trigger1 = (var(0):=(command="abc" && command !="holddown") && power>=
         1000) || (var(0) && var(5)) || (!var(0) && power>=2000)

            Здесь вы должны сбалансировать коэффициент удобочитаемости при разложении общих подвыражений от потери читаемости при использовании оператора :=.


Материал перевел и подготовил Sceletron

0


Вы здесь » The Sims 3, Gran Turismo и MUGEN » M.U.G.E.N. » Справка по M.U.G.E.N.


Рейтинг форумов | Создать форум бесплатно