Я боролся с тем, как реализовать скрипты в моем игровом движке. У меня есть только несколько требований: это должно быть интуитивно понятно, я не хочу писать собственный язык, парсер и интерпретатор, и я не хочу использовать многопоточность. (Я уверен, что есть более простое решение; мне не нужны хлопоты из нескольких игровых логических потоков.) Вот пример сценария на Python (он же псевдокод):
def dramatic_scene(actors):
alice = actors["alice"]
bob = actors["bob"]
alice.walk_to(bob)
if bob.can_see(alice):
bob.say("Hello again!")
else:
alice.say("Excuse me, Bob?")
Этот эпический кусок повествования создает проблемы с реализацией. Я не могу просто оценить весь метод сразу, потому что walk_to
занимает время игры. Если он сразу же вернется, Алиса начнет подходить к Бобу и (в том же кадре) поздороваться (или будет встречена). Но если walk_to
это блокирующий вызов, который возвращается, когда она достигает Боба, то моя игра застревает, потому что она блокирует тот же поток выполнения, который заставил бы Алису ходить.
Я подумал о том, чтобы заставить каждую функцию ставить в очередь действие - помещать alice.walk_to(bob)
объект в очередь, которая будет отбрасываться после того, как Алиса дойдет до Боба, где бы он ни находился. Это более тонко нарушено: if
ветвь оценивается немедленно, поэтому Боб может приветствовать Алису, даже если его спина повернута к ней.
Как другие движки / люди обрабатывают сценарии без создания потоков? Я начинаю искать идеи в областях, не связанных с разработкой игр, таких как цепочки анимации jQuery. Похоже, что для такого рода проблем должны быть хорошие шаблоны.
Ответы:
То, как что-то вроде Panda делает это с помощью обратных вызовов. Вместо блокировки это было бы что-то вроде
Наличие обратного обратного вызова позволяет вам связывать события такого рода настолько глубоко, насколько вы хотите.
РЕДАКТИРОВАТЬ: пример JavaScript, так как это имеет лучший синтаксис для этого стиля:
источник
Здесь вы хотите найти термин « сопрограммы » (и обычно это ключевое слово языка или имя функции
yield
).Реализация будет зависеть в первую очередь от вашего языка. Для игры вы хотите, чтобы реализация была как можно более легкой (легче, чем нити или даже волокна). На странице Википедии (по ссылке) есть несколько ссылок на различные языковые реализации.
Я слышал, что Lua имеет встроенную поддержку сопрограмм. Как и GameMonkey.
UnrealScript реализует это с помощью так называемых «состояний» и «скрытых функций».
Если вы используете C #, вы можете посмотреть это сообщение в блоге Ника Грэйвлина.
Кроме того, идея «цепочек анимации», хотя и не одно и то же, является реальным решением той же проблемы. Ник Грэйвелин также имеет реализацию C # этого .
источник
yield return walk_to();
в своем скрипте.не собираться с резьбой - это умно.
Большинство игровых движков работают как серия модульных этапов, запоминающихся на каждом этапе. Для «прогулки к примеру» у вас обычно есть стадия ИИ, где ваши пройденные персонажи находятся в состоянии, в котором они не должны искать врагов для убийства, стадия анимации, на которой они должны запускать анимацию X, стадия физики (или этап моделирования), где обновляется их фактическая позиция и т. д.
в приведенном выше примере «Алиса» - это актер, состоящий из частей, которые живут на многих из этих этапов, поэтому блокирующий вызов actor.walk_to (или сопрограмма, которую вы вызываете next () один раз за кадр), вероятно, не будет иметь надлежащего контекста принимать много решений.
Вместо этого функция 'start_walk_to', вероятно, будет делать что-то вроде:
Затем ваш основной цикл запускает свой тик ai, тик физики, тик анимации и тик ролика, и ролик обновляет состояние каждой подсистемы в вашем движке. Система катсцены должна определенно отслеживать то, что делает каждый из ее катсцены, и система, управляемая сопрограммой, для чего-то линейного и детерминированного, такого как кат-сцена, может иметь смысл.
Причина этой модульности заключается в том, что она просто делает вещи красивыми и простыми, а для некоторых систем (таких как физика и ИИ) вам необходимо знать состояние всего и одновременно, чтобы правильно решать проблемы и поддерживать игру в согласованном состоянии. ,
надеюсь это поможет!
источник