Найкращий спосіб зберігання змінних для всіх ігор


23

У мене є екран параметрів для таких речей, як складність, дозвіл, повноекранний режим тощо, але я намагаюся знайти «найкращий» спосіб зберігання / отримання цих змінних під час виконання.

Наразі я реалізував Constantsклас, який містить усі GameOptionперерахунки, але як я вибираю за замовчуванням всі ці параметри? Крім того, як мені отримати наразі вибраний перелік?

Що стосується роздільної здатності, я конкретно вирішив зберегти значення, але не знаю, як отримати значення за замовчуванням або наразі збережені значення. Будь-який напрямок був би чудовим; Спасибі! :)

namespace V1.test.RPG
{
  public class GameOptions
  {
    public enum Difficulty { EASY, MEDIUM, HARD }
    public enum Sound { ON, QUIET, OFF }
    public enum Music { ON, QUIET, OFF }
    public enum ResolutionWidth
    {
        SMALL      = 1280,
        MEDIUM     = 1366,
        LARGE      = 1920,
        WIDESCREEN = 2560
    }
    public enum ResolutionHeight
    {
        SMALL      = 800,
        MEDIUM     = 768,
        LARGE      = 1080,
        WIDESCREEN = 1080
    }
    public Boolean fullScreen = false;
  }
}

NB: Я запитав у SO, і вони вказали мені на це місце. Там є коментар, але я хотів би почути різні способи цього / найбільш використовувані способи.


1
Ви запитали в потрібному місці; хто б вас послав сюди, помилився. Я відповів на питання все одно, щоб допомогти вам, але це не специфічне питання щодо розробки ігор, це загальне питання програмування.
поштовх

Я просто читав нитку SO; Мені подобається відповідь Скотта Чемберліна.
поштовх

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

Дотичний до актуального питання щодо глобальних, будь ласка, не припускайте, що там є фіксований набір рішень.
Ларс Віклунд

Відповіді:


32

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

CVars:
Після того як ваш проект зростає, ви можете поглянути на CVAR . CVAR - це "розумна змінна", так би мовити, яку ви можете змінювати під час роботи через консоль, термінал або інтерфейс користувача. CVAR, як правило, реалізуються з точки зору об'єкта, який містить основне значення. Тоді об'єкт може відслідковувати значення, а також зберігати / завантажувати його у / з файлу. Ви можете зберігати об’єкти CVAR на карті, щоб отримати до них ім’я або інший унікальний ідентифікатор.

Щоб проілюструвати концепцію трохи далі, наступний псевдокод - простий приклад типу CVAR, який містить intзначення:

// just some flags to exemplify:
enum CVarFlags {
    CVAR_PERSISTENT, // saved to file once app exits
    CVAR_VOLATILE    // never saved to file
};

class CVar {
public:
    // the constructor registers this variable with the global list of CVars
    CVar(string name, int value, int defaultValue, int flags);

    int getValue();
    void setValue(int v);
    void reset(); // reset to the default value

    // etcetera...

private:
    int flags; // flags like: save-to-file, etc.
    int value; // the actual value
    int defaultValue; // the default value to reset the variable to
};

// global list of all CVars:
map<string, CVar> g_cvars;

Глобальний доступ:
У наведеному вище прикладі я припускав, що конструктор CVarзавжди реєструє змінну за допомогою глобальної cvarsкарти; це досить корисно, оскільки дозволяє оголосити змінну так:

CVar my_var = new CVar("my_var", 0, 42, CVAR_PERSISTENT);

Ця змінна автоматично стає доступною на глобальній карті, і ви можете отримати доступ до неї з будь-якого місця, індексуючи карту з назвою змінної:

CVar v = g_cvars.find("my_var");

Наполегливість:
Коли гра вимикається, повторіть карту та збережіть CVAR_PERSISTENTу файлі всі змінні, позначені як . Наступного разу, коли гра розпочнеться, перезавантажте їх.


Судова практика: Для більш конкретного прикладу надійної системи CVAR ознайомтеся з реалізацією, представленою в Doom 3 .


4

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

public enum Sound
{
    ON,
    QUIET,
    OFF
}

public Sound soundValue;

У цьому прикладі тепер можна встановити soundValueзначення ON, QUIET або OFF.


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


1

рішення гламперта дуже повно, але я додам свій особистий досвід.

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

Клас змінних внутрішньо зберігає карту від рядка до рядка (поки що всі мої змінні є лише рядками) і доступ до нього здійснюється через getters та setters.

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

Щоб уникнути цього, я наклав наступну семантику: за допомогою setметоду викидається виняток, якщо змінна з цим іменем вже є у словнику, іget видаляє змінну зі словника перед поверненням.

Два додаткові методи забезпечують те, що ви очікували, setAndOverwriteіgetAndKeep . Сенс семантики інших методів полягає в тому, що ви можете легко помітити помилки типу "цей метод повинен ініціалізувати цю змінну, але інший метод робив це раніше".

Для ініціалізації словника початкові змінні зберігаються у файлі json, а потім читаються при запуску гри.

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

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