Как сделать намного более простую версию UT kismet (C ++ и Lua) - PullRequest
1 голос
/ 05 января 2011

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

В основном у меня есть редактор 2D-уровней. Я могу помещать сущности в мир, добавлять плитки, столкновения и т. Д. Я хочу, чтобы у меня была возможность создавать простые сценарии визуально. Например, если у меня есть рычаг и дверь, я хочу выбрать уровень, выбрать его событие «onactivate» и связать его с действием «close» двери.

Редактор загружает XML с возможными сущностями и тем, какие действия публикует каждый, в случае рычага (активировать / деактивировать) и двери (открыть / закрыть).

Теперь сложная часть. Мне нужно перевести это в работающий код. Я думал о некоторых решениях, но все кажется мне неуклюжим. Например, для события рычага / двери я мог бы автоматически генерировать код в функции lua с именем Lever1_onactivate_Door1_open (), который зарегистрирует LuaListener в сигнале слушателя экземпляра Lever1 для события onactivate (в C ++), и позволит его вызывать позже, когда onEnter для триггера срабатывает.

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

Спасибо заранее, Maleira.

1 Ответ

0 голосов
/ 05 января 2011

В таких играх, как Doom, это примерно выполняется следующим образом: при нажатии клавиши Use [func: P_UseLines] ближайшая стена, к которой она будет применяться, ищется [func: P_UseTraverse] и,при условии, что вы находитесь в диапазоне и имеете правильный угол поворота, вызывается действие (называемое «специальным»), связанное со строкой в ​​ [func: P_ActivateLine] , которое в конце концов отображает ее в существующую функцию.

Другими словами, простой поиск в массиве указателей функций :

/* Premise */
struct line_t {
    ...
    int special;
    ...
};
struct line_t *line = activation_line;

/* Function call from p_spec.cpp */
LineSpecials[line->special](line, ...);

LineSpecials будет массивом указателей функций:

int LS_Door_Open(struct line_t *, ...)
{
     ...
}

typedef int (*lnSpecFunc)(struct line_t *, ...);
lnSpecFunc LineSpecials[256] = {
    ...
    /* 13 */ LS_Door_Open,
    ...
};
...