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

Coroutines для игрового дизайна?

Я слышал, что сопрограммы - хороший способ структурирования игр (например, PEP 342: "Корутины - естественный способ выражения многих алгоритмы, такие как симуляции, игры..." ), но мне нелегко обернуть голову вокруг того, как это будет сделано.

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

Есть ли простой пример игры, написанной с использованием сопрограмм? Или может кто-нибудь предложить эскиз того, как это можно сделать?

4b9b3361

Ответ 1

Один из способов coroutines, который можно использовать в играх, - это легкие потоки в актерской модели, например, Kamaelia.

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

Все объекты будут одновременно выполнять свою собственную работу с сообщениями, отправленными друг другу, когда происходят взаимодействия.

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

Ответ 2

Coroutines позволяют создавать большие количества очень легких "микропотоков" с кооперативной многозадачностью (т.е. микропотоки, которые намеренно разрешают запуск других микропотоков). Читайте в статье Dave Beazley статьи по этому вопросу.

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

Поисковый запрос "coroutine game programming" в Google, похоже, вызывает интересные результаты.

Ответ 3

Самый известный случай сопрограмм - это, вероятно, старая графическая точка и приключенческие игры, где они использовались для script роликов и других анимированных последовательностей в игре. Пример простого кода будет выглядеть так:

# script_file.scr
bob.walkto(jane)
bob.lookat(jane)
bob.say("How are you?")
wait(2)
jane.say("Fine")
...

Вся эта последовательность не может быть записана как обычный код, так как вы хотите, чтобы bob выполнил анимацию своей анимации после того, как вы сделали bob.walkto(jane) вместо того, чтобы прыгать прямо на следующую строку. Для анимации гуляния, которую вы играете, вам, однако, нужно отдать управление игровому движку, и именно здесь вступают в игру сопрограммы.

Вся эта последовательность выполняется как сопрограмма, означающая, что у вас есть возможность приостановить и возобновить ее по своему усмотрению. Команда, подобная bob.walkto(jane), таким образом сообщает объекту bob стороны движка своей целью, а затем приостанавливает сопрограмму, ожидая вызова пробуждения, когда bob достиг своей цели.

На стороне двигателя все может выглядеть так (псевдо-код):

class Script:
    def __init__(self, filename):
        self.coroutine  = Coroutine(filename)
        self.is_wokenup = True

    def wakeup(self):
        self.is_wokenup = False;

    def update():
        if self.is_wokenup:
          coroutine.run()            


class Character:
   def walkto(self, target, script):
       self.script = script
       self.target = target

   def update(self):
       if target:
           move_one_step_closer_to(self.target)
           if close_enough_to(self.target):
               self.script.wakeup()

               self.target = None
               self.script = None

objects = [Character("bob"), Character("jane")]
scripts = [Script("script_file.scr")]

while True:
    for obj in objects:
        obj.update()

    for scr in scripts:
        scr.update()
Тем не менее, несмотря на то, что сопрограммы делают кодирование этих последовательностей очень простым, не все реализации, которые вы найдете в них, будут построены с учетом сериализации, поэтому сохранение игры станет довольно сложной проблемой, если вы сильно используете сопрограммы.

Этот пример также является самым основным случаем сопрограммы в игре, сами сопрограммы могут использоваться и для множества других задач и алгоритмов.

Ответ 5

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

Таким образом, на практике их довольно сложно получить, поэтому языки, такие как UnrealScript, которые используют некоторое подобие сопрограмм, вытесняют большую часть полезной логики из-за атомных событий. Некоторые люди получают от них хорошую полезность, например. люди EVE Online, но им пришлось в значительной степени архитектовать всю свою систему вокруг концепции. (И то, как они обрабатывают конфликты по общим ресурсам, недостаточно хорошо документировано.)