Альтернатива системі державних ігор?


30

Наскільки я можу сказати, у більшості ігор є якась "система ігор", яка перемикається між різними станами гри; це можуть бути такі речі, як "Intro", "MainMenu", "CharacterSelect", "Loading" та "Game".

З одного боку, цілком має сенс розділити їх на державну систему. Зрештою, вони розрізнені і в іншому випадку повинні бути у великій заяві перемикача, яка, очевидно, безладна; і вони, безумовно, добре представлені державною системою. Але в той же час я дивлюся на стан "Гра" і замислююся, чи є щось не так у цьому підході до державної системи. Бо це як слон у кімнаті; це ВЕЛИЧЕЗНО і очевидно, але ніхто не ставить під сумнів ігровий підхід до системи.

Мені здається дурним, що "Гра" ставиться на тому ж рівні, що і "Головне меню". Але не існує способу розірвати стан "гри".

Чи найкраща дорога система ігор? Чи є якась інша, краща техніка управління, ну, «ігровий стан»? Чи добре мати вступний стан, який малює фільм і слухає для введення, а потім стан завантаження, який перетворюється на диспетчер ресурсів, а потім стан гри, який робить практично все ? Це теж не здається вам незбалансованим? Я щось пропускаю?

Відповіді:


30

Я думаю, що ти тут просто сперечаєшся на семантиці. Він називається Game State, оскільки він веде себе як Кінцева машина машини , з кінцевою кількістю станів і переходів між ними. "Гра" в "Системі ігрових станів" позначає загальну систему, а "Завантаження", "Основне меню" тощо є станами гри. Це легко можна назвати "сценами" або "екранами" або "рівнями". Його справедлива семантика.

Я не впевнений, що строгий FSM вже застосовується. У своїх реалізаціях я називаю "Екрани" і дозволяю їх складати - тобто. екрани можна малювати вгорі інших екранів, контролюючи, оновлені чи намальовані екрани під ними. Таким чином, я можу мати кілька екранів активних одночасно із автономною логікою та кодом, характерними для цього екрана, не турбуючись про будь-який інший екран.

Наприклад, екран паузи можна відкрити вгорі мого основного екрана гри, який забороняє оновлення, але дозволяє малювати під собою. Екран інвентаря символів може дозволяти як малювати, так і оновлювати - тому гра продовжує грати, поки ви працюєте в інвентарі.


саме так слід робити. Екрани повинні мати можливість містити кілька інших екранів у дерев яній архітектурі. Отже, ваша програма містить ігровий екран, який містить екран меню пауз, який містить екран налаштувань аудіо та екран налаштувань гри. тощо
Iain

1
Я хотів би побачити для цього приклад вихідного коду! (Переважно в C ++ / C # / Java)
Золомон,

1
На жаль, на даний момент у мене є лише виробничий код, але є аналогічна концепція у зразку ігрового стану XNA: creators.xna.com/en-GB/samples/gamestatemanagement
DrDeth

7

Звичайно, стан ігор було б величезним, але немає причин, що сам стан гри не може містити стан машини для управління своїми даними. Ієрархічні машини стану корисні.


4

Мені завжди подобається думати про кожну «державу» як про «сцену». Тож вступне відео - це сцена, просто статична. Кредити - це сцена. У меню - це сцена. Єдина відмінність між ними - рівень інтерактивності та логіки гри.


3

В мене теж є проблеми.

Скажімо, у вас є Гра.

Замість того, щоб перетворювати "Гра" на зразок "Завантаження", "Головне меню" тощо. - ІМО краще дозволити грі мати декілька станів:

"Завантаження" - "показ меню" - "призупинено" тощо.

Гра все ще працює, але коли вона відображає головне меню, вона перебуває в режимі "Показати меню".

І коли гра не перебуває в якомусь конкретному стані, вона просто працює.

Це має набагато більше сенсу, принаймні для мене. :)


Я згоден. Ніхто не хоче виходити з Державного Ігра лише для того, щоб увійти до Паузи . З іншого боку: Це все-таки державна система .. просто вкладена :)
bummzack

2

Програма в Інтернеті (в традиційному розумінні Інтернету, тобто постійно працює і відповідає на вхід, а не в сенсі, підключеному до Інтернету), як правило, складається з 3 речей:

  • збирання та обробка вводу
  • оновлення логіки
  • вихід

Взагалі ці 3 пов’язані між собою та змінюються водночас. Наприклад, під час відображення екрана заставки ви можете зіставити всі ваші клавіші на команду "Закрити екран", і оновлення може зникати повільно, а вихідний сигнал відображає цю графіку. Але під час гри, всі клавіші можуть відображати різні команди, і оновлення змінює властивості багатьох ігрових об'єктів.

Якщо ви розглядаєте його таким чином, має сенс відокремити вступ від створення персонажів та власне гри: у кожного є свій набір правил введення, оновлення та виведення. Вони майже як автономні програми, які поділяються деякими даними та кодом бібліотеки. Зважаючи на це, зазвичай має сенс мати лише один Ігровий стан, оскільки геймплей є досить однорідним протягом усього часу.

Звичайно, якщо у вас дійсно є окремі типи гри (наприклад, приклад RPG - карта світу, карта міста, Cutscene, Combat) з різними введеннями, оновленнями та виведеннями, немає ніяких причин, щоб у вас не було декількох станів там теж замість всього 1 ігрового стану. Але це залежить від вашої гри.


1

Я дивлюся на це інакше. "Меню", "HighScores", "кредити" або щось таке, що можна побачити, можна вважати просто іншим рівнем, і тоді цей стан не обов'язково легший, ніж ваш "ігровий" (у стані гри, як правило, є більше сутностей, і різні, але врешті-решт, це просто інший рівень, коли сутності виявляють більш передбачувану поведінку, а "карти", як правило, менш складні).
Здійснення цього перемикання у вашому мисленні безумовно виводить вас із синдрому "нудного меню".


Я збирався сказати те саме ... Усі мої меню, екрани, що б там не було, - це просто інший рівень.
швидкісник

1

У своїй грі я маю:

Диспетчер виконання , який ініціалізує додаток (гру), завантажує ресурси, вивільняє ресурси при виході програми тощо. Він ініціалізує Application Engine, GameViewEngine, GameLogicEngine.

Менеджер ігрових держав , який знаходиться в GameLogicEngine, і відповідає за контроль речей, пов’язаних з основним циклом гри: виявлення зіткнень, розрахунок фізики, читання на клавіатурі, математичні операції тощо ...

Спочатку я мав тенденцію мати лише одного ігрового менеджера, який був частиною мого GameLogicEngine. Однак у мене виникли деякі труднощі з контролем над інтіалізацією основних підсистем (GameLogic, ApplicationEngine, ...). Це можна було зробити, але це було більш безладним, іммо.

Зараз мені речі виглядають більш прозорими, і я задоволений дизайном.


0

Перейменуйте стан "Гра" на щось на зразок "Геймплей". Тоді ваша логіка здається кращою; Ви перестаєте грати, щоб перейти до меню: ви виходите зі стану гри, щоб перейти до стану MainMenu.

Крім того, я вважаю, що такі речі, як пауза, яка вимагає, щоб гра була в тому ж стані, що і коли ви призупинили гру, не повинні бути окремими станами. Стани дитини та гніздування, можливо? У геймплеї є меню пауз.


0

Я думаю, що є хороший метод, який називається стек гри-стан. Я не бачив жодних паперів чи статей про це, але він поширюється трохи голосом. По суті, найвищий ігровий стан на стеку викликається першим, і він повинен робити все, що завгодно, із введенням / рендерінгом тощо.

У моєму двигуні ігрові стани - це фактично лише списки ігрових утворень. Потім у мене є об'єкти, які працюють як меню. У моєму меню або призупинено гру (не оновлюючи наступний елемент на стеку), але дозвольте іншим станам (-ям) підштовхнути свої моделі до візуалізації, щоб моє пауза-меню (яке не охоплювало весь екран) все ще відображає гру ззаду.

Я сподіваюся, що це дає уявлення про дещо іншу систему, яка не базується на стані-машині.


0

Чи добре мати вступний стан, який малює фільм і слухає для введення, а потім стан завантаження, який замикається на менеджер ресурсів, а потім стан гри, який робить практично все? Це теж не здається вам незбалансованим? Я щось пропускаю?

Це зовсім чудово. Або, принаймні, це поліпшення в порівнянні з "великим потворним перемикачем залежно від того, в якому стані це гра".

Я хотів би зазначити, що в більшості ігор вам вже знадобиться кінцева державна машина, щоб мати справу з простим AI сутності. Типовим прикладом є вороги, які перебувають у стані бездіяльності, нападу або вмирання.

Якщо у вас є достатньо абстрагована машина з кінцевим станом, ви можете повторно використовувати її як для об’єкта гри, так і для вашого AI; раптом ви не вкладаєте багато зусиль у стан гри - натомість ви повторно використовуєте код, який ви все одно використовували.

Безсоромний самовідвід: я реалізував таку машину Кінцевого стану в моїй бібліотеці ігор Lua, MiddleClass (конкретно, надбудова під назвою MindState). Ось як ви робите з ним Game State .


0

Інший підхід до цього полягає у використанні концепції зі світу функціонального програмування під назвою Discriminated Union . Хоча вони зазвичай зустрічаються на мовах FP, ви можете імітувати їх за допомогою класів .

В основному, дискримінаційний союз - це тип, який завжди є одним із nвипадків, і збережені дані можуть змінюватись у кожному конкретному випадку.

Наприклад:

type GameState =
  | Menu of MenuState
  | Playing of SimulationState

Тут наш GameStateтип може бути Menuабо Playing. Якщо вона є Menu, то вона буде містити MenuStateоб’єкт. Якщо вона є Playing, то вона буде містити SimulationStateоб’єкт.

Для оновлення ми б matchввімкнули стан і відповідно викликали іншу функцію:

let update gameTime = 
  let nextState = 
    match gameState with
    | Menu menuState -> updateMenu gameTime menuState
    | Playing simulationState -> updateSimulation gameTime simulationState

  // Mutate the current state
  gameState <- nextState

І аналогічно для надання:

let render gameTime = 
  let nextState = 
    match gameState with
    | Menu menuState -> renderMenu menuState
    | Playing simulationState -> renderSimulation simulationState

Однією з переваг такого підходу є те, що ви можете обробляти речі в різних штатах (наприклад, ресурси) легше без глобальних мереж або проходячи навколо "службових" об'єктів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.