Предисловие
На просторах сети, я нашел движок платформера под ZDoom, написанный Nash‘ем (ссылка). Код движка я слегка доработал, и теперь, им можно пользоваться.
Создание уровня.
Для начала, скачайте движок с MEGA.
Затем, откройте zplatformer.pk3 и вытащите карту (map01.wad) из папки maps

Откройте в Doom Builder карту(map01.wad), в качестве ресурса, подключите zplatformer.pk3

В этом уровне нет ничего нового, за исключением, двигающийся платформы. Разберем её.
Создание двигающийся платформы.
Двигающийся платформа, по сути, это 3D пол у которого передвигается, одновременно, пол и потолок.
3D полы я разбирал здесь
Сначала, откройте Script Editor. В нем мы видим следующий код.
#include "zcommon.acs"
script 1 ENTER {
int state = 1;
int speed = 20;
int height = 50.0;
while(1) {
FloorAndCeiling_LowerByValue(10,speed,50);
TagWait(10);
FloorAndCeiling_RaiseByValue(10,speed,50);
TagWait(10);
Delay(1);
}
}
За передвижение платформы отвечает FloorAndCeiling_LowerByValue, у которого следующий синтаксис.
FloorAndCeiling_LowerByValue(tid, скорость, высота)
Таким образом, в этой строке:
FloorAndCeiling_LowerByValue(10,speed,50);
Платформа (пол и потолок 3D пола) с тидом 10, переместится вниз на 50 мап-пикселей, со скоростью 20 мап-пикселей в секунду.
Далее, ждем завершения передвижения.
TagWait(10);
Перемещаем платформу вверх. И снова ждем перемещения платформы.
FloorAndCeiling_RaiseByValue(10,speed,50);
TagWait(10);
В конце, добавляем Delay(1), чтобы скрипт не вылетел, в любом случае.

Внутренности движка.
В zplatformer.pk3, в папке zscript есть следующие скрипты:
- SideScrollerPlayer.zc — скрипт игрока, здесь можно прописать физику игрока.
- SideScrollerPlayerStates.zc — код, отвечающий за переключение стейтов игрока.
- SideScrollerCamera.zc — код камеры, не трогаем.
- SideScrollerHandler.zc — правильный спавн камеры, не трогаем.
- SideScrollerHUD.zc — HUD, графический интерфейс.
В скрипте SideScrollerPlayer.zc я запретил перемещать камеру вверх/вниз.
Pitch = 0;
И запретил игроку поворачиваться во время атаки.
bool is_firing = weapn != null && player.attackdown && weapn.CheckAmmo (Weapon.PrimaryFire, true);
if (sideInput < 0)
{
if(!is_firing){
dir = DIR_Left;
}
normalizedSideInput = -moveSpeed;
}
else if (sideInput > 0)
{
if(!is_firing){
dir = DIR_Right;
}
normalizedSideInput = moveSpeed;
}
В скрипте SideScrollerPlayerStates.zc для добавления стейта нужно:
- Добавить новый элемент в enum EAnimationStates, до TOTAL_PLAYER_STATES
- Вставить в массив stateName название стейта, в том порядке в котором добавил элемент в enum EAnimationStates
- Прописать условие при котором вызывается стейт, если условие истина, то присваиваем переменной StateToPlay число стейта взятое с enum (например ANIMSTATE_WALKING)
- Пропишите сам стейт, в блоке states.
Возьмем в пример стейт Fire.
- В EAnimationStates я создал элемент ANIMSTATE_FIRE, после ANIMSTATE_CROUCHING
enum EAnimationStates
{
ANIMSTATE_SPAWN,
ANIMSTATE_STAND,
ANIMSTATE_WALKING,
ANIMSTATE_JUMPING,
ANIMSTATE_CROUCHING,
ANIMSTATE_FIRE,
ANIMSTATE_DEAD,
TOTAL_PLAYER_STATES
}
Добавил название стейта (Fire) в массив stateName, после Crounching
stateName[4] = "Crouching";
stateName[5] = "Fire";
3. Прописал условие активации стейта.
//Fire
if (weapn != null && player.attackdown && weapn.CheckAmmo (Weapon.PrimaryFire, true))
{
StateToPlay = ANIMSTATE_FIRE;
}
4. И прописал сам стейт, в блоке States.
Fire:
VKIL GH 2;
Loop;
Далее, на очереди идет SideScrollerHUD.zc, но его код подробно разбирался здесь, поэтому пропустим.
Таким образом, вы можете изменить поведение игрока в SideScrollerPlayer.zc, добавить ему анимацию в SideScrollerPlayerStates.zc, а интерфейс прописать в SideScrollerHUD.zc.
Итоговый результат.
