Предисловие
Все те, кто играл в Brutal Doom, знают, что там есть система фаталити. То-есть, убийство от разных монстров, воспроизводит разную анимацию смерти. Нечто подобное, мы сегодня и реализуем.
Создаем камеру.
Камерой может стать любой актор (декорация, монстр, ракета). Серьзено, поэкспериментируйте, попробуйте создать монстра, привязать к нему tid, и использовать этот tid в ChangeCamera. Наблюдать игру от лица монстра, довольно таки забавно.
Нашей камерой будет, простейший невидимый актор. Пропишите следующий код к себе в DECORATE.
Actor ChaseCam
{
Height 16
Radius 8
+NOGRAVITY
+NOBLOCKMAP
States
{
Spawn:
TNT1 A -1
stop
}
}
Теперь напишем скрипт, который переместит камеру за спину игрока, и активирует её.
Разбираемся в скрипте.
Для начала, напишем скрипт камеры. Данная камера, будет направлена на игрока, через неё мы, как раз, и будем лицезреть жестокое убийство.
script "FatalityCamera" (void) {
Thing_Stop(0);
SetPlayerProperty(0, 1, PROP_TOTALLYFROZEN);
int angle = GetActorAngle(0);
int radius = 128;
int x = GetActorX(0);
int y = GetActorY(0);
int z = GetActorZ(0) + 41.0;
while (!Spawn("ChaseCam", x - cos(angle)*radius, y - sin(angle)*radius, z, 1337, angle >> 8)) {
radius -= 8 >> 16;
}
ChangeCamera(1337, 0, 0);
}
Разберем, подробно, данный скрипт.
Подготавливаемся
Thing_Stop(0);
Сбрасываем скорость у игрока
SetPlayerProperty(0, 1, PROP_TOTALLYFROZEN);
Замораживаем игрока, что-бы он не поворачивал камеру, не стрелял, и не двигался.
int angle = GetActorAngle(0);
Получаем угол, на который повернут игрок (yaw), в дальнейшем, он нам понадобится в расчете координат камеры.
int radius = 128;
Задаем расстояние, на котором будет размещена камера, относительно игрока.
int x = GetActorX(0);
int y = GetActorY(0);
int z = GetActorZ(0) + 41.0;
Получаем координаты x, y, z игрока. Координату z я поднял, что-бы она, не лежала на полу.
Спавним камеру
while (!Spawn("ChaseCam", x - cos(angle)*radius, y - sin(angle)*radius, z, 1337, angle >> 8)) {
radius -= 8 >> 16;
}
За спавн камеры, отвечает комманда Spawn, синтаксис у неё следующий:
Spawn("название_актора", x, y, z, tid, угол)
- название_актора — задает название актора в DECORATE.
- x, y, z — задают расположение в 3D пространстве.
- tid — tid нового актора.
- угол — задает угол актора.
Также, данная функция, возвращает количество созданных акторов (1 — актор заспавнился, 0 — актор, не заспавнился). Это важно, потому-что комманда Spawn, спавнит не везде, а только, внутри карты.
Таким образом, цикл будет продолжаться до тех пор, пока камера не заспавнится.
while (!Spawn("ChaseCam", x - cos(angle)*radius, y - sin(angle)*radius, z, 1337, angle >> 8)) {
Пошли дальше разбирать. Для удобства, я продублирую синтаксис комманды Spawn.
Spawn("название_актора", ???, ???, ???, tid, угол)
- название_актора — ChaseCam (наша камера).
- tid — 1337 (tid камеры)
- угол — угол игрока, сконвертированный в нужный формат angle >> 8
Остановимся подробнее на конвертации угла. Изначально, GetActorAngle возвращает угол игрока (значение от 0.0 до 1.0), то-есть дробное значение. Так вот, в ACS не существует дробных значений, а число 1.0, на самом деле является целочисленным числом 65536 или (2^16). Просто, в голове, нужно держать сдедующее правило 1.0 = 65536.
Функция Spawn, в качестве угла, принимает значение от 0 до 255 (2^8). По этой причине, мы воспользовались битовым сдвигом angle >> 8, на 8 ячеек вправо (>>). Кстати, операция битового сдвига эквивалента делению на 2 в степени «количество ячеек«.
То-есть, angle >> 8, можно представить как angle / 2^8. Тогда как angle << 8, можно представить как angle * 2^8
Дальше, разберем координаты x, y.
x - cos(angle)*radius
y - sin(angle)*radius
Используя данные формулы, мы получаем координаты x,y, в зависимости от поворота игрока, на расстоянии в radius. Кстати, нечто подобное, мы уже использовали для построения круга, в уроке ACS. Управляем частицами (SpawnParticle).
Идем дальше.
while (!Spawn("ChaseCam", x - cos(angle)*radius, y - sin(angle)*radius, z, 1337, angle >> 8)) {
radius -= 8 >> 16;
}
radius -= 8 >> 16;
Если не получилось заспавнить камеру, то пробуем заспавнить поближе.
Последнее что осталось, переключиться на созданную камеру.
ChangeCamera(1337, 0, 0);
Готово. В итоге, получили скрипт, который спавнит камеру за нашей спиной. Теперь камера готова, осталось добавить Fatality, чем мы и займемся в следующем уроке.