Подтвердить что ты не робот

Lua и С++: разделение обязанностей

Пожалуйста, помогите классифицировать способы организации кода игры С++/Lua и отделить их обязанности. Каковы наиболее удобные способы, которыми вы пользуетесь?

Например, Lua может использоваться для инициализации только объектов С++ или на каждой итерации цикла игры. Он может использоваться только для игровой логики или для графики. Некоторые игровые движки обеспечивают полный контроль над всеми подтипами из скриптов! Мне действительно не нравится этот подход (никакого разделения вообще).

Можно ли реализовать все игровые объекты (npc, locations) как таблицы Lua без объектов С++? Или лучше их зеркалировать (таблицы Lua для управления объектами С++)? Или что-то еще?

Спасибо.

Изменить. Моя классификация: Lua и С++: разделение обязанностей.

Продолжение темы: Lua, игровое состояние и игровой цикл

4b9b3361

Ответ 1

Мой подход заключался в том, чтобы максимально ограничить возможности Lua. Я никогда не обнаружил необходимости в "основной" или другой такой функции, которая вызывается каждый раз при рендеринге сцены (или более). Однако некоторые двигатели Lua (например, LOVE) делают это. Я предпочитаю определять объекты с дополнительными функциями обратного вызова для общих событий, которые могут потребоваться для ответа на объект, такие как столкновение, щелчок мышью, ввод или выход из игрового мира и т.д.

Конечный результат является очень декларативным, почти конфигурационным файлом для объектов. У меня есть функция для создания классов или типов объектов, а другая для создания объектов на основе этих типов. Затем объекты имеют набор методов, которые можно вызвать при реагировании на различные события. Все эти методы Lua относятся к методам C/С++, которые, в свою очередь, изменяют частные свойства объекта. Ниже приведен пример объекта bucket, который может захватывать объекты шара:

define {
    name='ball';
    texture=png('images/orb.png');
    model='active';
    shape='circle';
    radius=16;
    mass=1.0; 
    elastic=.7;
    friction=.4; 
}

define {
    name='bucket';
    model='active';
    mass=1;
    shape='rect';
    width=60;
    height=52;
    texture=png('images/bucket.png');
    elastic=.5;
    friction=.4; 
    oncontact = function(self, data)
        if data.subject:type() == 'ball' then
            local a = data.subject:angleTo(self:getxy())
            if a < 130 and a > 50 then
                --update score etc..
            end
        end
    end;
}

Я бы не воспринимал это как "один истинный способ" для реализации вашего скриптового API. Одной из красавиц Lua является то, что он поддерживает множество различных типов API. Это то, что я нашел, хорошо работает для игр, которые я делаю - игры на основе 2D-физики.

Ответ 2

Я предлагаю эту классификацию:

  • Экстремальный вариант: скрипты Lua управляют всем (игровая логика, графика, AI и т.д.). Более того: script работает как хост-программа, владеет игровым циклом. Некоторые двигатели делают такую ​​вещь. Ba-ad вещь: никакого разделения обязанностей вообще и безопасности script.

  • Сценарии Lua поддерживают логику игры и обработку игровой логики. Вероятно, скрипты вызываются на каждой итерации цикла игры.

  • Сценарии Lua редко используются для инициализаций, конфигураций, обратных вызовов. Хост-программа обеспечивает (связывает) очень минималистический интерфейс для скриптов. Таким образом, скрипты построены из таких хорошо продуманных и предоставленных блоков.

Ответ 3

Начните с малого. Разрешить доступ к игровым объектам, чтобы вы могли выполнять скрипты на уровне карты/уровня. Поведение, которое согласовано между картами/уровнями, возможно, не требует создания сценариев.

Также предоставляйте доступ только к общему интерфейсу ваших объектов.