По сути, в каждой игре, которую я сделал до сих пор, у меня всегда есть переменная, такая как «current_state», которая может быть «game», «titlecreen», «gameoverscreen» и т. Д.
И тогда в моей функции обновления у меня есть огромное:
if current_state == "game"
game stuf
...
else if current_state == "titlescreen"
...
Однако я не чувствую, что это профессиональный / чистый способ обработки состояний. Любые идеи о том, как сделать это лучше? Или это стандартный способ?
lua
architecture
love2d
Дэвид Гомес
источник
источник
Ответы:
Поскольку вы говорите об экранах, я чувствую, что лучше всего разделить всю эту логику на разные экраны. Что я обычно делаю:
Определите интерфейс, называемый экраном, и используйте несколько экранов для его реализации. Например, LoadScreen, MainMenuScreen, GameScreen, GameOverScreen, HighScoreScreen и т. Д. В вашей игре вы помещаете переменную, которая содержит текущий экран. Каждый цикл вы вызываете screen.update () и визуализируете текущий экран. Это сэкономит вам много «если это состояние сделает это», так как ваше состояние определяется текущим экраном.
Это очень хорошо разделит вашу логику.
Пример кода:
Или, в зависимости от вашей игровой настройки, у вас может быть бесконечный цикл в качестве игры.
источник
Если вы уже используете Middleclass, есть отличная библиотека конечных автоматов, которая называется Statefull . Он прост в использовании и поддерживает те же идеи, которые предлагал Матсеманн.
источник
Если ваша
current_state
переменная является строкой, то в Lua это действительно просто:источник
Что я делаю примерно так:
У меня есть структура данных ориентированного ациклического графа , которая, по сути, представляет собой просто набор узлов, которые указывают друг на друга. Каждый узел представляет игровую систему. например, пользовательский интерфейс, мир, вход, рендеринг. И каждый узел указывает на другие узлы, которые идут до или после него. После того, как все узлы на месте, легко сгладить их в простой список. Настройка DAG - это первое, что я делаю при запуске игры. Каждый раз, когда я хочу добавить новую систему, скажем, AI, я могу просто написать этот код, а затем рассказать моей игре, от чего он зависит и что должно зависеть от него.
Мой основной игровой цикл идет после этого и просто запускает каждую систему по порядку. Сначала обрабатывается ввод, затем обновления мира, затем другие вещи ... Пользовательский интерфейс близок к концу, и рендеринг является последним. Когда игра только начинается, мира, физики и ИИ не существует, поэтому эти шаги, по сути, пропускаются, и отображается только титульный экран. Когда вы запускаете игру должным образом, пользовательский интерфейс отправляет сообщение мировой системе для включения, и он просто заботится о себе. Управление состоянием игры просто означает включение и выключение различных систем. Каждая система имеет свой собственный набор информации о состоянии, который обрабатывается более или менее независимо от всех других (это не совсемна самом деле, многие системы работают с одним и тем же набором данных - например, система пользовательского интерфейса берет данные из мира для отображения информации. Система ИИ также должна просматривать и отправлять сообщения объектам в мире).
источник
Вот как я организую свои штаты в Lua + Love2d. Это позволяет избежать длинных операторов if / then.
Сначала я создаю базовый класс, который содержит методы update (dt) и render (). Вы также можете назначить ему методы обработки событий, например onKeyDown (key). Я называю этот класс Stage, но любой объект, который реализует методы, будет работать. Затем я создаю экземпляр этого класса для каждого игрового состояния, реализуя необходимые методы. Затем я создаю таблицу ключ / значение с именем состояния и экземпляром состояния. Затем следите за currentState в глобальной области видимости, чтобы состояния могли изменить его при выполнении определенного условия.
источник
Ну, хотя это не очень хорошо, нормально обрабатывать состояния таким образом, ИМО. Вы можете сделать его намного чище, используя функции для каждого состояния, например:
или что-то другое мешает в этом подходе (я имею в виду, кроме того, что метод обновления очень длинный)?
источник