Eu tenho uma tela de opções para coisas como dificuldade, resolução, tela cheia, etc., mas estou lutando para encontrar a "melhor" maneira de armazenar / obter essas variáveis em tempo de execução.
Atualmente, implementei uma Constants
classe que contém todas as GameOption
enumerações, mas como escolho um padrão para todas essas opções? Além disso, como obtenho a enumeração atualmente selecionada?
Em relação à resolução, especificamente, decidi armazenar os valores, mas não tenho certeza de como obter os valores padrão ou atualmente armazenados. Qualquer direção seria ótima; obrigado! :)
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: perguntei na SO e eles me indicaram esse lugar. Há um comentário lá, mas eu gostaria de ouvir maneiras diferentes de fazê-lo / as formas mais usadas.
Respostas:
Planejando crescer:
constantes constantes codificadas são adequadas para pequenos projetos, mas, eventualmente, à medida que seu software cresce, você deseja alterar essas configurações sem precisar recompilar tudo. Há muitas vezes que você deseja alterar as configurações enquanto o jogo está rodando e não é possível fazer isso com constantes codificadas.
CVars:
Depois que seu projeto cresce, você pode dar uma olhada nos CVARs . Um CVAR é uma "variável inteligente", por assim dizer, que você pode modificar durante o tempo de execução por meio de um console, terminal ou interface do usuário. Os CVARs geralmente são implementados em termos de um objeto que envolve um valor subjacente. O objeto pode, então, acompanhar o valor e salvá-lo / carregá-lo no / do arquivo. Você pode armazenar os objetos CVAR em um mapa para acessá-los com um nome ou outro identificador exclusivo.
Para ilustrar um pouco mais o conceito, o pseudocódigo a seguir é um exemplo simples de um tipo CVAR que envolve um
int
valor:Acesso global:
no exemplo acima, assumi que o construtor de
CVar
sempre registra a variável nocvars
mapa global ; isso é bastante útil, pois permite que você declare uma variável assim:Essa variável é disponibilizada automaticamente no mapa global e você pode acessá-la de qualquer outro lugar indexando o mapa com o nome da variável:
Persistência:
Quando o jogo está sendo encerrado, itere o mapa e salve todas as variáveis marcadas como
CVAR_PERSISTENT
, em um arquivo. Na próxima vez que o jogo começar, recarregue-os.Jurisprudência:
Para obter um exemplo mais específico de um sistema CVAR robusto, confira a implementação apresentada no Doom 3 .
fonte
Bem, primeiro, uma enumeração define quais podem ser os valores , não quais são . Portanto, você ainda precisa declarar outra variável depois de declarar o enum. Por exemplo:
Neste exemplo, agora você pode definir
soundValue
ON, QUIET ou OFF.Em seguida, você ainda precisará estruturar seu código para que outras partes do código possam acessar esse objeto "configurações". Não sei se você também precisa de ajuda com essa parte, mas os padrões comuns para resolver esse problema incluem singletons (aqueles que são mal vistos hoje em dia) ou localizadores de serviço ou injeção de dependência.
fonte
A solução glampert é muito completa, mas adicionarei minha experiência pessoal.
Encontrei esse mesmo problema e minha solução foi usar uma classe estática de variáveis.
A classe Variables internamente mantém um mapa de string para string (até agora todas as minhas variáveis são apenas strings) e é acessada por meio de getters e setters.
O ponto é que o acesso a variáveis globais pode introduzir todo tipo de erros sutis, pois partes totalmente não relacionadas do código interferem repentinamente.
Para evitar isso, impus a seguinte semântica: o uso do
set
método lança uma exceção se uma variável com esse nome já existir no dicionário eget
exclui a variável do dicionário antes de devolvê-lo.Dois métodos adicionais fornecem o que você esperaria,
setAndOverwrite
egetAndKeep
. O objetivo da semântica dos outros métodos é que você pode identificar facilmente erros do tipo "esse método deve inicializar essa variável, mas outro método já o fez antes".Para inicializar o dicionário, as variáveis iniciais são armazenadas em um arquivo json e lidas quando o jogo é iniciado.
Infelizmente, ainda não me afastei muito do jogo, portanto não posso testemunhar a robustez dessa abordagem. Ainda assim, talvez possa fornecer algo interessante sobre os CVARs.
fonte