Почему «основной» игровой цикл необходим для разработки игры? - PullRequest
46 голосов
/ 02 апреля 2010

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

Какова цель основного игрового цикла?

Ответы [ 11 ]

80 голосов
/ 03 апреля 2010

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

Но вы все равно не захотите структурировать игру таким образом.

То, что делает цикл наиболее привлекательным решением, заключается в том, что ваш цикл становится тем, что в программировании в реальном времени называется «циклическим исполнителем». Идея состоит в том, что вы можете сделать относительные скорости выполнения различных действий системы детерминированными по отношению друг к другу. Общая скорость цикла может контролироваться таймером, и этот таймер может в конечном итоге быть прерыванием, но в современных ОС вы, скорее всего, увидите это прерывание в виде кода, который ожидает семафор (или некоторый другой механизм синхронизации), как часть вашего "основного цикла".

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

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

При таком цикле вы должны следить за тем, чтобы не тратить больше времени на обработку каждого прохода, чем на самом деле в реальном времени. Если вы пытаетесь выполнить цикл с частотой 100 Гц, лучше, чтобы обработка всего цикла была завершена менее чем за 10 мсек, в противном случае ваша система будет работать с перебоями. В программировании в реальном времени это называется превышением ваших временных рамок. Хорошая система позволит вам отслеживать, насколько вы близки к обгону, а затем вы сможете уменьшить нагрузку на обработку, как считаете нужным.

16 голосов
/ 02 апреля 2010

Прослушиватель событий также зависит от некоторого цикла вызова, видите ли вы это или нет. Кто еще собирается звонить слушателю?

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

7 голосов
/ 02 апреля 2010

Игровой цикл (упрощенно выглядит следующим образом)

initialise
do
     input
     update
     render
loop
clean up

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

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

Если бы вы обновлялись только при вводе пользователем, игра реагировала бы только тогда, когда пользователь вводил данные. Другие игровые компоненты, такие как игровые объекты A.I, не будут реагировать сами по себе. Поэтому цикл - это самый простой и лучший способ обновления игры.

6 голосов
/ 02 апреля 2010

Это неправда, что для всех видов игр необходим специальный цикл основной игры.

Экшн-играм необходим такой цикл из-за частых обновлений объектов и точности ввода игры.

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

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

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

3 голосов
/ 03 апреля 2010

На практике, как указывали другие люди, необходим цикл.

Однако ваша идея теоретически обоснована. Вам не нужно цикл . Вам нужно основанных на событиях операций.

На простом уровне вы можете концептуализировать процессор, чтобы иметь несколько таймеров;

  • каждый стреляет по переднему фронту 60 Гц и вызывает блит-код.
  • Другой может быть тиканье на частоте 60 кГц и рендеринг последних обновлений объектов в игровом мире в буфер блиттера.
  • Другой может быть тиканье на частоте 10 кГц и принимать данные от пользователя. (довольно высокое разрешение, смеется)
  • Другой может быть игра «Сердцебиение» и такты на 60 МГц; ИИ и физика могут работать в одно мгновение.

Конечно, эти таймеры можно настроить.

Практически, то, что произошло бы, это то, что вы были бы (несколько элидированы) так:

void int_handler1();
//...
int main() 
{ 
  //install interrupt handlers
  //configure settings
  while(1);
}
2 голосов
/ 02 апреля 2010

Игра должна запускаться в режиме реального времени , поэтому она лучше всего работает, если она работает на одном процессоре / ядре непрерывно. Приложение, управляемое событиями, обычно передает ЦП другому потоку, когда в очереди нет событий. Там может быть значительное ожидание, прежде чем процессор переключится обратно на ваш процесс. В игре это означало бы короткие ларьки и нервную анимацию.

2 голосов
/ 02 апреля 2010

Основной цикл вызывает прослушиватель событий. Если вам повезло иметь управляемую событиями операционную систему или оконный менеджер, там находится цикл обработки событий. В противном случае вы пишете основной цикл, чтобы обеспечить «несоответствие импеданса» между интерфейсами системных вызовов, основанными на вводе-выводе, poll или select, и традиционным приложением, управляемым событиями.

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

2 голосов
/ 02 апреля 2010

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

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

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

schedule(updateEvent, 33ms)

function updateEvent:
    for monster in game:
        monster.update()
    render()

против

while 1:
    for monster in game:
        monster.update()
    wait(33ms)
    render()

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...