Сопрограммы для игрового дизайна? - PullRequest
16 голосов
/ 08 августа 2009

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

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

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

Ответы [ 5 ]

9 голосов
/ 08 августа 2009

Сопрограммы позволяют создавать большие объемы очень легких «микропотоков» с помощью совместной многозадачности (то есть микропотоки умышленно подвешиваются, чтобы позволить другим микропотокам работать). Читайте в статье Дейва Бизли на эту тему.

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

Поиск "сопрограммных игр" в Google, похоже, дает интересные результаты.

8 голосов
/ 09 августа 2009

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

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

Вся эта последовательность не может быть написана как обычный код, так как вы хотите, чтобы Боб выполнял анимацию ходьбы после того, как вы сделали 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()

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

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

7 голосов
/ 08 августа 2009

Одним из способов использования сопрограмм в играх является легкая нить в актероподобной модели, как в Камаэлия .

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

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

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

2 голосов
/ 08 августа 2009

Две ссылки, которые могут вас заинтересовать:

http://aigamedev.com/open/articles/coroutine-state-machine/

http://www.dabeaz.com/coroutines/ (поиск 'задача' на этой странице и PDF)

1 голос
/ 10 августа 2009

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

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

...