Найти тему
ZDG

Как работают игры: Главный цикл

Небольшой итог. Я написал уже 20 выпусков, в которых рассказал с самого начала, что такое данные, как они хранятся и как их обрабатывать. Если вы что-то пропустили, можете начать читать с самого начала. Позже я сведу все эти материалы в один список. А в этом выпуске я расскажу, как работает типичная игра, благо знаний для этого должно быть уже достаточно.

Итак, любая игра – это один цикл. Чем вы занимаетесь, когда играете? В каждый момент времени вы смотрите на экран с отображённой на нем игровой ситуацией. Вы оцениваете эту ситуацию, принимаете решение и даёте какую-то команду. Игра принимает эту команду, обрабатывает свои внутренние данные и рисует следующую ситуацию. Дальше вы опять её оцениваете, и всё повторяется. То есть вы действуете в цикле, и игра работает в цикле.

Всю работу программы можно разбить на такие этапы:

1. Старт

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

2. Отображение информации

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

3. Ожидание ввода

Игра ждёт, когда вы нажмёте клавишу на клавиатуре или кликнете мышью или сделаете что-нибудь ещё. Ожидание не обязательно должно останавливать игру. Если вы ничего не ввели, то игра может или ждать в полном останове, или просто работать дальше. Очевидно, когда вы играете в шахматы или Color Lines, игровая ситуация не меняется, пока вы не сделали ход. А когда играете в Tetris, фигура продолжает падать, не ожидая вас.

4. Обработка состояния

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

5. Принятие решения

После обработки состояния игра принимает решение: годится ли текущее состояние для того, чтобы продолжать играть? Если годится, тогда игра снова отправляется в пункт 2. А если нет, то цикл прекращается.

6. Конец игровой активности

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

Пункты с 2 по 5 образуют главный игровой цикл, где и происходит 90% всех манипуляций с памятью и состояниями объектов.

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

1. Старт

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

2. Отображение информации

Просто напечатаем на экране здоровье игрока и здоровье каждого монстра.

3. Ожидание ввода

Пусть игрок просто нажимает на клавишу с цифрой от 1 до 5, чтобы указать, какого монстра он хочет ударить.

4. Обработка состояния

После того, как игрок выбрал, какого монстра ударить, нужно найти в памяти, где хранится здоровье выбранного монстра, и уменьшить его. Если оно достигло 0, монстр умирает.

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

5. Принятие решения

Игру можно продолжать, пока жив игрок и пока жив хоть один монстр. Если это так, то переходим на пункт 2, и цикл повторяется.

6. Конец игровой активности

Здесь мы можем написать на экране GAME OVER или YOU WIN, смотря как у игрока сложились дела.

Я даже не буду писать код для этой игры. Вместо этого я написал простую, но уже настоящую игру "Robots" на чистом JavaScript и ещё на Python для сравнения (я никогда раньше не писал на Python). В ходе разработки этой игры я расскажу про ещё одно крайне важное понятие программирования – функции. А также разберемся, как работает пользовательский ввод и вывод информации на экран.

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

Также отмечу, что в пункте 4 все монстры должны ударить игрока в ответ. А значит, потребуется перебрать всех имеющихся монстров по очереди, то есть организовать цикл, который будет находиться внутри основного цикла. Можно ли поместить цикл в цикл? Сколько угодно! Вам ничего не мешает иметь цикл внутри цикла внутри цикла внутри цикла... Каждый цикл имеет своё тело и своё условие окончания, так что они совершенно не зависят друг от друга. Но внешний цикл может продолжиться только тогда, когда закончится внутренний цикл. Иначе говоря, из пункта 4 в пункт 5 мы перейдем только после того, как все монстры в своем цикле ударят игрока.

Читайте дальше: