SRB2. Создаем врагов.

Подготовка.

Перед началом, скачайте пак картинок с MEGA.

Разбираем код противника.

Писать мы будем на языке SOC. Комментарии в SOC, задаются решеткой (#)

Скопируйте данный код к себе в MAINCFG:

Freeslot
S_BOUNCY_STND
S_BOUNCY_RUN1
S_BOUNCY_RUN2
SPR_UCUP
MT_BOUNCYBALL
 
State S_BOUNCY_STND
SpriteName = UCUP
SpriteFrame = A
Duration = 5
Next = S_BOUNCY_STND
Action = A_Look
Var1 = 0
Var2 = 0

State S_BOUNCY_RUN1
SpriteName = UCUP
SpriteFrame = A
Duration = 80
Next = S_BOUNCY_RUN2
Action = A_BunnyHop
Var1 = 8
Var2 = 12

State S_BOUNCY_RUN2
SpriteName = UCUP
SpriteFrame = A
Duration = 5
Next = S_BOUNCY_RUN1
Action = A_FaceTarget
Var1 = 0
Var2 = 0
 
Object MT_BOUNCYBALL
MapThingNum = 1337
SpawnState = S_BOUNCY_STND
SpawnHealth = 1
SeeState = S_BOUNCY_RUN2
SeeSound = sfx_None
ReactionTime = 32
AttackSound = sfx_None
PainState = S_NULL
PainChance = 200
PainSound = sfx_None
MeleeState = S_NULL
MissileState = S_NULL
DeathState = S_XPLD1
XDeathState = S_NULL
DeathSound = sfx_pop
Speed = 3
Radius = 20*FRACUNIT
Height = 20*FRACUNIT
DispOffset = 0
Mass = 100
Damage = 0
ActiveSound = sfx_None
Flags = MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE
RaiseState = S_NULL

Начнем его разбирать.

Freeslot. Заголовок загружаемых ресурсов.

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

Первыми идут стейты

S_BOUNCY_STND
S_BOUNCY_RUN1
S_BOUNCY_RUN2

Названия стейтов начинаются с S_. Чуть позже разберем их подробнее.

Далее идут спрайты.

SPR_UCUP

Для того чтобы использовать спрайт с именем UCUP, необходимо добавить к нему префикс SPR_, в итоге получится SPR_UCUP. Также, у спрайтов, как и в DECORATE, используется первые 4 буквы названия изображения, 5-я буква задает имя кадра, а 6-я угол поворота.

Наглядная таблица, с указанием числа и угла поворота. Источник: https://wiki.srb2.org/wiki/Sprite

Спрайты, как и в ZDoom, должны располагаться между маркерами S_START и S_END, если это wad.

И в папке Sprites (или любой его под-папке), если это pk3.

И указываем название объекта (противника). Названия объектов имеют префикс MT_.

MT_BOUNCYBALL

Подробнее про Freeslot, на вики.

Стейты.

Далее идут 3 стейта:

  • S_BOUNCY_STND — стейт покоя, противник не видит игрока.
  • S_BOUNCY_RUN1 — прыжок в сторону игрока.
  • S_BOUNCY_RUN2 — подготовка к следующей атаке.

Разберем код стейта S_BOUNCY_STND:

State S_BOUNCY_STND #начало блока стейта S_BOUNCY_STND 
SpriteName = UCUP #Имя спрайта (вернее первые 4 буквы)
SpriteFrame = A #Имя кадра (UCUPAx, где x-угол поворота)
Duration = 5 #Время до следующего стейта в тиках (35 тиков = 1 секунда)
Next = S_BOUNCY_STND #Имя следующего стейта
Action = A_Look #Действие (или функция, кому как удобнее), которое выполнит противник
Var1 = 0 #Аргумент 1, функции A_Look
Var2 = 0 #Аргумент 2, функции A_Look

В комментариях я подробно рассписал каждую строчку.

Обратите внимание на строку

Action = A_Look #Действие (или функция, кому как удобнее), которое выполнит противник

В одной этой строке, заключена вся логика стейта. Здесь вызывается действие A_Look, которое ищет игрока в области видимости.

Все действия, начинаются с префикса A_, как в DECORATE. Полный список функций (действий), доступен вики. Также, есть возможность и свои действия, на языке Lua.

Остальные стейты, имеют ту же структуру.

Стейт S_BOUNCY_RUN1, вызывает функцию A_BunnyHop, который принимает 2 аргумента:

  • Силу прыжка вверх
  • Силу движения вперед (в нашем случае вперед, направлен на игрока)

И, через 5 тиков, переходит на стейт S_BOUNCY_RUN2.

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

Т.е. идет бесконечный цикл.

Далее, разберем создание объекта.

Создание объекта.

В комментариях, я рассписал значение строк.

Object MT_BOUNCYBALL #Начало блока MT_BOUNCYBALL 
MapThingNum = 1337 #id обьекта в редакторе ZoneBuilder
SpawnState = S_BOUNCY_STND #Начальный стейт
SpawnHealth = 1 #Количество хп обьекта
SeeState = S_BOUNCY_RUN2 #Стейт, на который нужно перейти, если противник увидит игрока
SeeSound = sfx_None #Звук, при обнаружении противника (в данном случае, его отсутствие)
ReactionTime = 32 #Время реакции
AttackSound = sfx_None #Звук атаки (отсутствует)
PainState = S_NULL #Стейт боли (отсутствует)
PainChance = 200 #Шанс попадания в стейт боли
PainSound = sfx_None #Звук боли (отсутствует)
MeleeState = S_NULL #Стейт рукопашного боя (отсутствует)
MissileState = S_NULL #Стейт выстрела снарядом (отсутствует)
DeathState = S_XPLD1 #Стейт смерти
XDeathState = S_NULL #Стейт смерти, при получении огромного количества урона
DeathSound = sfx_pop #Звук смерти
Speed = 3 #Скорость передвижения противника (3 FRACUNIT)
Radius = 20*FRACUNIT #радиус
Height = 20*FRACUNIT #высота
DispOffset = 0 #Используется тогда, когда хотите нарисовать 1 спрайт перед другим.
Mass = 100 #Масса
Damage = 0 #Урон
ActiveSound = sfx_None #Звук активации (отсутствует)
Flags = MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE #флаги = это противник, он может взаимодействовать с игроком, игрок может его покалечить.
RaiseState = S_NULL #Стейт возрождения (отсутствует)

Подробнее о флагах здесь.

Добавляем обьект на карту.

Теперь, в Zone Builder, установите свой объект на карте.

И запустите. В итоге, получилось следующее.

Итоговый результат.