Lua и C ++: разделение обязанностей - PullRequest
11 голосов
/ 20 апреля 2010

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

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

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

Спасибо.

Редактировать. Моя классификация: Lua и C ++: разделение обязанностей .

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

Ответы [ 3 ]

4 голосов
/ 21 апреля 2010

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

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

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 голосов
/ 21 апреля 2010

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

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

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

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

1 голос
/ 21 апреля 2010

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

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

...