Насколько я могу судить, большинство игр имеют своего рода «систему состояний игры», которая переключается между различными состояниями игры; это могут быть такие вещи, как «Intro», «MainMenu», «CharacterSelect», «Loading» и «Game».
С одной стороны, имеет смысл разделить их на государственную систему. В конце концов, они несопоставимы и в противном случае должны были бы быть в большом выражении switch, что, очевидно, является грязным; и они, безусловно, хорошо представлены государственной системой. Но в то же время я смотрю на состояние «Игра» и задаюсь вопросом, есть ли что-то не так с этим подходом системы состояний. Потому что это как слон в комнате; это ОГРОМНО и очевидно, но никто не ставит под сомнение подход к системе игровых состояний.
Мне кажется глупым, что «Игра» ставится на один уровень с «Главным меню». Тем не менее, нет способа разрушить состояние «игры».
Является ли система состояний игры лучшим способом? Есть ли какая-то другая, лучшая техника для управления "игровым состоянием"? Разве это нормально иметь начальное состояние, которое рисует фильм и слушает ввод, а затем состояние загрузки, которое зацикливается на менеджере ресурсов, и затем состояние игры, которое делает практически все ? Вам это тоже не кажется неуравновешенным? Я что-то пропустил?
источник
Конечно, состояние Game будет огромным, но нет никаких причин, по которым само состояние Game не может содержать конечный автомат для управления своими данными. Иерархические конечные автоматы полезны.
источник
Мне всегда нравится думать о каждом "государстве" как о "сцене". Итак, вступительное видео - это сцена, просто статичная. Кредиты сцена. Меню это сцена. Единственная разница между ними - уровень интерактивности и игровой логики.
источник
У меня тоже проблемы с этим, на самом деле.
Допустим, у вас есть игра.
Вместо того , чтобы «Игра» это состояние как «Загрузка», «Главное меню» и т.д. - IMO, лучше пусть Игра имеет несколько состояний:
«Загрузка» - «Показ меню» - «Приостановлено» и т. Д.
Игра все еще работает, но когда она показывает главное меню, она будет в режиме «показывать меню».
И когда Game не находится в каком-либо конкретном состоянии, он просто запущен.
Это имеет гораздо больше смысла, по крайней мере для меня. :)
источник
Онлайн-программа (в традиционном смысле онлайн, то есть постоянно работающая и реагирующая на ввод, а не связанная с Интернетом) обычно состоит из 3 вещей:
Вообще говоря, эти 3 взаимосвязаны и изменяются одновременно. Например, при отображении заставки вы можете сопоставить все свои клавиши с командой «закрыть экран», и обновление может постепенно затухать в графике с выводом, просто показывающим эту графику. Но при игре в игру все ключи могут отображаться на разные команды, и обновление меняет свойства многих игровых объектов.
Когда вы смотрите на это таким образом, имеет смысл отделить вступление от создания персонажа и от самой игры: у каждого есть свой набор правил ввода, обновления и вывода. Они почти как автономные программы, которые делятся некоторыми данными и библиотечным кодом. И, учитывая это, обычно имеет смысл иметь только одно игровое состояние, так как игровой процесс довольно однороден во всем.
Конечно, если у вас действительно есть отдельные типы игрового процесса (например, пример RPG - Карта мира, Карта города, Катсцена, Битва), с различными входами, обновлениями и выходом, нет причины, по которой вы не могли бы иметь несколько состояний тоже вместо 1 состояния игры. Но это зависит от вашей игры.
источник
Я смотрю на это с другой стороны. «Меню», «HighScores», «кредиты» или то, что вы сказали, можно рассматривать как просто еще один уровень, и тогда это состояние не обязательно будет легче, чем ваше «игровое» состояние (в игровом состоянии, как правило, больше сущностей, и разные, но, в конце концов, это просто еще один уровень, на котором сущности демонстрируют более предсказуемое поведение, а «карты», как правило, менее сложны).
Такое переключение мышления определенно выводит вас из синдрома «скучного меню».
источник
В моей игре у меня есть:
Менеджер выполнения , который инициализирует приложение (игру), загружает ресурсы, освобождает ресурсы при выходе из приложения и т. Д. Он инициализирует Application Engine, GameViewEngine, GameLogicEngine.
Game State Manager , который находится в GameLogicEngine и отвечает за управление вещами, относящимися к основному циклу игры: обнаружение столкновений, вычисление физики, чтение с клавиатуры, математические операции и т. Д.
Изначально у меня был, как правило, только один Game State Manager, который был частью моего GameLogicEngine. Однако у меня возникли некоторые трудности с управлением инициализацией основных подсистем (GameLogic, ApplicationEngine, ...). Это могло быть сделано, но это было более грязно, IMO.
Теперь все выглядит более прозрачным для меня, и я доволен дизайном.
источник
Переименуйте состояние «Game» во что-то вроде «Gameplay». Тогда ваша логика кажется лучше; Вы прекращаете играть, чтобы перейти в меню: вы выходите из состояния Gameplay, чтобы перейти в состояние MainMenu.
Кроме того, я думаю, что такие вещи, как пауза, которая требует, чтобы игра находилась в том же состоянии, что и при приостановке игры, не должны быть отдельными состояниями. Дочерние состояния и гнездование, возможно? В игровом процессе есть меню паузы.
источник
Я думаю, что есть хороший метод, называемый стеком состояний игры. Я не видел ни статей, ни статей об этом, но он немного распространялся голосом. По сути, самое верхнее игровое состояние в стеке вызывается первым и получает возможность делать все, что захочет, с вводом / рендерингом и т. Д. Самое верхнее игровое состояние - единственное, которому разрешено выдвигать или выдавать состояния.
В моем движке игровые состояния - это просто списки игровых сущностей. Тогда у меня есть объекты, которые работают как меню. Мои состояния меню либо приостанавливают игру (не обновляя следующий элемент в стеке), но позволяют другим состояниям передавать свои модели в средство визуализации, чтобы мое меню паузы (которое не покрывает весь экран) по-прежнему имеет рендеринг игры в спину.
Я надеюсь, что это дает представление о немного другой системе, которая не основана на автомате.
источник
Это прекрасно. Или, по крайней мере, это улучшение по сравнению с «большим уродливым переключателем в зависимости от состояния игры».
Я хотел бы отметить, что в большинстве игр вам уже понадобится конечный автомат, чтобы иметь дело с простым искусственным интеллектом. Типичным примером являются враги, которые находятся в состоянии ожидания, атакуют или умирают.
Если у вас достаточно абстрагированный конечный автомат, вы можете повторно использовать его как для игрового объекта, так и для своего AI; внезапно вы не «вкладываете» много усилий в игровое состояние - вместо этого вы снова используете код, который вы использовали в любом случае.
Получается бесстыдная самостоятельная вставка: я реализовал такой конечный автомат в моей игровой библиотеке Lua MiddleClass (конкретно, надстройка под названием MindState). Вот как вы делаете это с Game State .
источник
Другой подход к этому - использовать концепцию из мира функционального программирования, называемую « Дискриминационный союз» . Хотя они обычно встречаются на языках FP, вы можете эмулировать их, используя классы .
По сути, Дискриминационный Союз - это тип, который всегда является одним из
n
случаев, и хранимые данные могут варьироваться в зависимости от каждого случая.Например:
Здесь наш
GameState
тип может быть либоMenu
илиPlaying
. Если это такMenu
, то он будет содержатьMenuState
объект. Если это такPlaying
, то он будет содержатьSimulationState
объект.Чтобы обновить, мы бы
match
о состоянии и вызвали другую функцию соответственно:И аналогично для рендеринга:
Одним из преимуществ этого подхода является то, что вы можете легче обрабатывать вещи в разных состояниях (например, в ресурсах) без глобализаций или обхода «служебных» объектов.
источник