Как поделиться / повторно использовать скрипт Lua для нескольких объектов? - PullRequest
3 голосов
/ 04 ноября 2011

Я нахожусь на этапе проектирования / скелетного кодирования моей игры на C ++ с использованием сценариев Lua, но я столкнулся с проблемой проектирования:

В игре будет много копий однотипных сущностей, поведение которых контролируется одним и тем же сценарием. Есть ли простой способ поделиться сценарием между сущностями одного типа в одном lua_state? Я только смог найти этот вопрос, заданный пару раз в Интернете; Я прочитал смешанные отзывы о том, стоит ли загружать один и тот же скрипт в разных lua_state, а не подробные отзывы об альтернативах.

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

Это два решения, о которых я подумал. Я не новичок в программировании или в концепциях C или OO, но я все еще учусь, когда дело доходит до Lua и особенно Lua / C API. Я думаю, что мои идеи верны, но я даже не уверен, как бы я их реализовал.

  1. Реализация ОО в скрипте Lua, чтобы каждая сущность была представлена ​​объектом Lua; вся логика Lua будет действовать на объект. Это также будет иметь выгоду (или «выгоду») от возможности изменения глобальной среды чем-либо одним объектом.

  2. Инкапсулируйте каждый объект в его собственном окружении, используя setfenv, и скопируйте ссылки всех функций из глобального пространства. Насколько я понимаю, env - это просто таблица, отличная от глобальной, используемой по умолчанию, но я изучил setfenv, но не знаю, как бы это сделать.

1 Ответ

4 голосов
/ 04 ноября 2011

1 и 2 - это просто разные стороны одной медали, более или менее. Это просто вопрос, куда уходит объект. В типе 1 объект является явной частью сценария Lua. Это означает, что скрипт решает, как он хочет настроить свои объекты.

В типе 2 объектом является среда. Это все еще таблица Lua, но созданная для нее внешним кодом. Сценарий не может вырваться за пределы этого объекта, кроме как способами, которые допускает внешний код.

Для меня проще всего реализовать тип 1 с помощью Luabind . У меня был бы объект AI в виде класса C ++, из которого Lua могла бы получить производные. Запуск «основного сценария» для этого ИИ создаст экземпляр этого класса. Вы должны передать параметры скрипта, такие как имя объекта, которым он управляет, может быть, ссылка, которую он может использовать для управления им и т. Д.

Тип 2 довольно прост. Сначала вы создаете новую среду, создавая пустую таблицу и заполняя ее глобальными переменными, к которым у пользователя должен быть доступ. Это могут быть такие вещи, как разговор с игровым состоянием (поиск других объектов на сцене и т. Д.), Способы перемещения рассматриваемой сущности и т. Д. Существуют метатические приемы, которые вы можете использовать, чтобы сделать эти значения неизменными и постоянными, чтобы пользователь не мог изменить их позже.

Затем вы загружаете скрипт с помощью lua_loadstring или lua_loadfile. Это помещает функцию в стек Lua, которая представляет этот скрипт Lua. Затем вы применяете эту таблицу в качестве среды этой функции сценария с lua_setfenv. Затем вы можете запустить этот скрипт, передавая любые переменные, которые вы пожелаете (имя объекта и т. Д.).

...