У меня есть экран опций для таких вещей, как сложность, разрешение, полноэкранный режим и т. Д., Но я изо всех сил пытаюсь найти «лучший» способ хранения / получения этих переменных во время выполнения.
В настоящее время я реализовал Constants
класс, который содержит все GameOption
перечисления, но как выбрать значение по умолчанию для всех этих параметров? Кроме того, как я могу получить текущий выбранный enum?
Что касается разрешения, в частности, я решил сохранить значения, но я не уверен, как получить значения по умолчанию или сохраненные в настоящий момент значения. Любое направление было бы замечательно; Благодарность! :)
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, и они указали мне на это место. Там есть комментарий, но я хотел бы услышать разные способы сделать это / наиболее часто используемые способы.
Ответы:
Планирование роста:
жестко запрограммированные константы хороши для небольших проектов, но, в конечном счете, по мере увеличения размера вашего программного обеспечения вы захотите изменить эти параметры без необходимости перекомпилировать все. Много раз вы захотите изменить настройки во время игры, и вы не сможете сделать это с помощью жестко запрограммированных констант.
CVars:
Как только ваш проект вырастет, вы можете захотеть взглянуть на CVAR . CVAR - это, так сказать, «умная переменная», которую вы можете изменить во время выполнения через консоль, терминал или пользовательский интерфейс. CVAR обычно реализуются в терминах объекта, который оборачивает базовое значение. Затем объект может отслеживать значение, а также сохранять / загружать его в / из файла. Вы можете сохранить объекты CVAR на карте, чтобы получить к ним доступ с помощью имени или другого уникального идентификатора.
Чтобы проиллюстрировать эту концепцию немного ниже, следующий псевдокод представляет собой простой пример типа CVAR, который переносит
int
значение:Глобальный доступ:
в приведенном выше примере я предположил, что конструктор
CVar
всегда регистрирует переменную в глобальнойcvars
карте; это очень полезно, так как позволяет вам объявить переменную следующим образом:Эта переменная автоматически становится доступной в глобальной карте, и вы можете получить к ней доступ из любого места, проиндексировав карту с именем переменной:
Постоянство:
когда игра закрывается, выполните итерацию карты и сохраните все переменные, отмеченные как
CVAR_PERSISTENT
, в файл. При следующем запуске игры перезагрузите их.Прецедентное право:
для более конкретного примера надежной системы CVAR ознакомьтесь с реализацией, описанной в Doom 3 .
источник
Ну первый от перечисления определяет , какие значения могут быть , а не то , что значения являются . Таким образом, вам все еще нужно объявить другую переменную после того, как вы объявили enum. Например:
В этом примере теперь вы можете
soundValue
выбрать ON, QUIET или OFF.Тогда вам все еще нужно структурировать свой код так, чтобы другие части кода могли получить доступ к этому объекту «настроек». Я не знаю, нужна ли вам помощь с этой частью, но общие шаблоны для решения этой проблемы включают одиночные (которые в наши дни хмурились) или сервисные локаторы или внедрение зависимостей.
источник
Решение Glampert очень полно, но я добавлю свой личный опыт.
Я столкнулся с этой же проблемой, и я решил использовать статический класс Variables.
Класс Variables внутренне хранит карту от строки к строке (пока все мои переменные являются только строками) и доступен через методы получения и установки.
Дело в том, что получение доступа к глобальным переменным может привести ко всем видам тонких ошибок, поскольку совершенно не связанные части кода внезапно мешают друг другу.
Чтобы избежать этого, я применил следующую семантику: использование
set
метода выдает исключение, если переменная с таким именем уже существует в словаре, иget
удаляет переменную из словаря перед ее возвратом.Два дополнительных метода обеспечивают то, что вы ожидаете,
setAndOverwrite
иgetAndKeep
. Смысл семантики других методов в том, что вы можете легко обнаружить ошибки типа «этот метод должен инициализировать эту переменную, но другой метод делал это раньше».Чтобы инициализировать словарь, исходные переменные сохраняются в файле json, а затем читаются при запуске игры.
К сожалению, я еще не слишком далеко продвинулся в своей игре, поэтому не могу засвидетельствовать надежность этого подхода. Тем не менее, может быть, он может предоставить что-то интересное поверх CVAR.
источник