Eu tenho um jogo que gera um mapa de nível aleatório no início do nível. Eu quero implementar alguma maneira de salvar e carregar o nível.
Eu estava pensando que talvez o XML fosse uma boa opção para salvar todas as variáveis, então seria fácil criar algo que possa analisar esse XML e gerar exatamente o mesmo nível.
Mas XML provavelmente é um exagero para minhas necessidades. Lembro-me de antigamente com o antigo console da Sega que não tinha a capacidade de salvar seu jogo (acho que o jogo Worms também o fez), que eles dariam a você um monte de personagens que você poderia escrever. Se você digitar essa sequência mais tarde, ela carregará o nível exato.
Uma "string de nível" seria uma boa opção? Seria algum tipo de conversão "base60"? Como eu implementaria isso?
fonte
Qualquer que seja o formato usado para seus jogos salvos, pelo amor de Deus, digite um número de versão. Você poderá ter cargas compatíveis com versões anteriores ao ramificar o número da versão ou poderá reconhecer com segurança os salvamentos antigos demais. carregar.
Você vai se arrepender se não o fizer.
fonte
JSON é bom, mas YAML é melhor. :) http://www.yaml.org/ e http://code.google.com/p/yaml-cpp/ para uma das implementações mais agradáveis de usar.
YAML é um superconjunto de JSON que adiciona suporte a alguns recursos interessantes, principalmente:
fonte
Se você deseja serializar todos os dados no jogo, eu recomendaria o JSON como seu formato de arquivo; é por isso que é mais fácil usar o XML e o suporte é muito bom em vários idiomas.
Eu usei essa biblioteca para C ++ e funciona muito bem.
http://jsoncpp.sourceforge.net/
fonte
O XML é uma boa opção se você não estiver limitado pelo tamanho e for suportado nativamente (por exemplo, no .NET e Flash), mas se desejar um formato mais fino, poderá criar seu próprio formato e analisador com bastante facilidade. Eu normalmente uso 1 caractere, por exemplo. vírgula para separar cada objeto. Para decodificar a sequência, faça uma divisão por vírgula. Agora, cada objeto precisa de propriedades diferentes, portanto, separe-as com um caractere diferente, por exemplo, ponto-e-vírgula, e use outro caractere para separar os nomes das propriedades dos valores das propriedades, por exemplo. Cólon. Tudo isso pode ser decodificado facilmente sem regex apenas usando string.split. Aqui está um exemplo:
você pode economizar ainda mais espaço mantendo os nomes das propriedades com até 1 caractere, por exemplo, h para saúde. Por exemplo.
Compare com a alternativa JSON:
Além disso, se você quiser diminuir o tamanho dos seus números, poderá codificá-los usando o conjunto completo de caracteres UTF16 imprimíveis. Esse tópico me inspirou a perguntar uma pergunta no Stack Overflow sobre a quantidade de dados que você poderia compactar em um caractere na tela . A resposta parece estar acima de 40.000 valores para um número inteiro, se você não se importa de ter brail, Kanji e peças de xadrez: ♔♕♖♗♘♙♚♛♜♝♞♟
Para obter uma redução adicional de tamanho, você pode usar a ordem de leitura / gravação para determinar qual valor é qual; portanto, os dois primeiros caracteres representam o id, os próximos dois são a posição x, os próximos dois são y, o ângulo e a saúde etc. Então:
poderia armazenar todas as mesmas informações que os outros exemplos.
As grades de mosaico podem ser armazenadas como apenas uma string, com cada caractere representando um tipo diferente de mosaico, por exemplo:
onde eu poderia significar lava, 9 significa grama etc.
fonte
Se você está codificando .Net, o XML é super fácil de usar, pois você pode serializar / desserializar sua classe de nível para dentro / fora do XML com apenas algumas linhas e, em seguida, tudo em uma classe bem gerenciada.
O TheMap seria uma variável do tipo Mapa na qual você carrega todos os seus dados.
Supondo que você já tenha uma classe Map criada, isso salvaria seu mapa em XML:
Isso carregaria esse XML de volta na sua classe de mapa, para ser usado novamente no código.
A partir deste ponto, seu arquivo XML agora é carregado em sua classe para facilitar o uso.
Quanto ao seu problema de "String de nível", o que foi declarado antes funcionaria muito bem, você poderia usar o número de Seed como "String de nível".
Caso contrário, você pode pré-gerar quantos mapas diferentes quiser e salvá-los todos com uma "String de nível" e depois usá-lo para abrir o mapa apropriado.
fonte
Eu usaria um
struct
dispositivo simples ou semelhante (dependendo do seu idioma) para armazenar todo o estado do jogo em um local central. Se você deseja a proteção de setters / getters, pode envolver a estrutura em aclass
.Se você preferir , use campos de bits ou simplesmente faça você mesmo a manipulação de bits usando operadores bit a bit.
Esteja ciente de que, em alguns idiomas, as regras para preenchimento e empacotamento de estruturas podem ser um pouco complicadas - mas também pode não ser muito importante para o seu caso, se você tiver um ou dois bytes de preenchimento.
Você também pode usar um
#pragma
(como#pragma pack(1)
) ou um__attribute__
para compactar de perto a estrutura, eliminando o preenchimento. Isso pode ou não funcionar, dependendo do seu compilador e arquitetura de destino.Observe que o uso de campos de bits e pragmas ou atributos de pacotes pode reduzir a portabilidade. Nas arquiteturas de hardware, a resistência do campo struct (ordem dos bytes) também pode ser alterada. Portanto, você pode evitar isso se estiver tentando portabilidade.
(Por exemplo, Pac-Man, essa estrutura pode conter ingenuamente um ID de mapa ou semente de mapa, uma posição x e y de Pac-Man, quatro posições x e y fantasmas e um campo de bits grande para a presença ou ausência de 32 a 64 pellets, qualquer que seja o máximo.)
Depois de ter sua estrutura, passe-a para algo como uma função xxencode :
Escrever esta função é um pouco propenso a erros; você precisa mudar e combinar bytes conforme necessário para obter, por exemplo, 6 bits de cada vez, depois converter em um caractere apropriado. Eu pessoalmente tentaria caçar o código de outra pessoa, a menos que estivesse fazendo isso por "diversão" (e provavelmente desejaria uma suíte de testes).
Nunca subestime o poder da velha escola
struct
nos lugares certos. Nós usamos muito isso para jogos GBA e DS aqui.fonte
XML é bom para documentos estruturados arbitrariamente (os elementos podem aparecer em diferentes níveis da árvore) ou para incorporação em formato externo (como colocar svg em uma página xhtml). Se você não possui esses requisitos, é um formato realmente ineficiente e é preferível algo mais simples como csv ou json.
fonte