Como posso escrever um sistema Save / Load para o meu jogo?

17

Estou tentando descobrir uma maneira de escrever um sistema de salvar / carregar para o meu jogo em C ++. A partir de agora, estou fazendo tudo isso usando sinalizadores binários. Alguém tem uma idéia de como fazer isso de outra maneira? Não me importo de usar binário, mas quero conhecer minhas opções. Eu também quero algo em que seria fácil verificar o status de apenas um evento completo ou incompleto para decidir certas coisas (muitos dos itens do sistema neste jogo dependem do que o jogador fez ou não fez ao longo do jogo).

sonicbhoc
fonte
1
Na verdade, depois de analisar, talvez seja melhor eu ficar com o Python neste projeto. Estou usando o Panda3D como um mecanismo de jogo, e a versão python é mais polida. Isso, e eu provavelmente poderia me desenvolver mais rapidamente em python. Além disso, o python possui uma classe de serialização chamada pickle, que me poupa o trabalho de codificar uma.
sonicbhoc

Respostas:

5

Serialização seria o caminho a percorrer e, quanto à verificação de status, você poderia ter lógica no método de desserialização para fazer isso.

ThatsGobbles
fonte
Estou lendo sobre isso aqui ( parashift.com/c++-faq-lite/serialization.html ) e parece muito interessante. Eu realmente nunca lidei com serialização, então será uma boa experiência de aprendizado para mim. Obrigado!
sonicbhoc 27/09/10
Sem problemas! Também estou trabalhando com serialização (embora em c #) para o meu jogo. Boa sorte!
precisa saber é o seguinte
4
lembre-se: se você serializar, armazene sempre um número de versão primeiro e leia-o novamente primeiro. Dessa forma, você pode lidar com as alterações mais recentes no formato do jogo saveg, fornecendo (algumas) compatibilidade com versões anteriores.
LearnCocos2D
4
Durante o desenvolvimento, eu também recomendo fortemente que você escreva os arquivos em um formato legível por humanos. Talvez algo como JSON ou XML. É muito mais fácil ver se tudo o que você precisa foi salvo e também muito mais fácil ajustar os dados em um arquivo já gravado (para testar ou consertar coisas depois de gravar um arquivo no disco).
bummzack
5

Estudei um pouco o código-fonte DOOM. Vou te contar como é feito lá.

D_DoomMain contém todas as funções de abrir / salvar / carregar, além de várias outras coisas. Como se diz no começo do arquivo,

// DESCRIPTION:
//      DOOM main program (D_DoomMain) and game loop (D_DoomLoop),
//      plus functions to determine game mode (shareware, registered),
//      parse command line parameters, configure game parameters (turbo),
//      and call the startup functions.

Basicamente, o arquivo inteiro está cheio de M_CheckParms do início ao fim. É disso que o D_DoomLoop consiste. É um loop enorme (algo como 1000-2000 linhas de comprimento).

Como sua pergunta é 'Como posso escrever?' Vou apenas colar alguns bits de código que se referem a gamesaves, do D_DoomMain:

Aqui estão as instruções em que esse material é usado, no final do loop.

   p = M_CheckParm ("-loadgame");
   if (p && p < myargc-1)
   {
       if (M_CheckParm("-cdrom"))
           sprintf(file, "c:\\doomdata\\"SAVEGAMENAME"%c.dsg",myargv[p+1][0]);
       else
           sprintf(file, SAVEGAMENAME"%c.dsg",myargv[p+1][0]);
       G_LoadGame (file);
   }


   if ( gameaction != ga_loadgame )
   {
       if (autostart || netgame)
           G_InitNew (startskill, startepisode, startmap);
       else
           D_StartTitle ();                // start up intro loop

   }

   D_DoomLoop ();  // never returns

Aqui está a função que acessa as strings, que você encontra espalhadas por todo o código:

void M_ReadSaveStrings(void)
{
   int             handle;
   int             count;
   int             i;
   char    name[256];

   for (i = 0;i < load_end;i++)
   {
       if (M_CheckParm("-cdrom"))
           sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",i);
       else
           sprintf(name,SAVEGAMENAME"%d.dsg",i);

       handle = open (name, O_RDONLY | 0, 0666);
       if (handle == -1)
       {
           strcpy(&savegamestrings[i][0],EMPTYSTRING);
           LoadMenu[i].status = 0;
           continue;
       }
       count = read (handle, &savegamestrings[i], SAVESTRINGSIZE);
       close (handle);
       LoadMenu[i].status = 1;
   }
}

Você também tem um arquivo chamado p_savegame.c com coisas que salvam todos os dados associados ao usuário (quais armas você possui, onde está em qual nível etc.).

E, finalmente, você tem o arquivo que carrega os dados do jogo salvo em um cenário de jogo, sem dúvida o mais complexo de todos, porque também carrega todo o resto. Esse é chamado p_setup.c e está localizado no mesmo diretório.

Funcionou bem para mim cattudo isso em um buffer de texto e pipeesse texto sendmailem meu próprio endereço de email. Dessa forma, eu posso lê-lo em momentos estranhos do dia e usar 'find' quando quiser procurar coisas como 'como o DOOM carrega um jogo'. O código está bem comentado.

ixtmixilix
fonte
3

Você pode serializar a classe ou os dados em um arquivo simples e depois lê-los novamente quando carregar.

Ólafur Waage
fonte
Devido a um firewall corporativo, não consegui acessar esses links. Desculpe.
sonicbhoc 27/09/10
4
Se sua empresa o impede de ler coisas, você precisa trabalhar, elas são idiotas.
o0 '.
2
Bem, este não é o meu trabalho ainda. : P (e talvez "corporate" não era a melhor palavra ... é um firewall na minha escola)
sonicbhoc
-1

Marquei a sugestão de usar XML / JSON para estruturar os jogos salvos. Dessa forma, você está muito preparado para criar as salvaguardas baseadas na "nuvem". Ou pelo menos, você terá uma estrutura que poderá usar para projetos futuros que possam envolver a web. Contanto que os arquivos não sejam armazenados de uma maneira que seja muito fácil de ler, eles deverão oferecer muitos benefícios. Como métricas! Hooray

Phil
fonte
1
O armazenamento em nuvem significa que você está armazenando as economias on-line. Você pode fazer isso com qualquer formato de arquivo.
Eu sei disso. Mas, para fins de comunicação, pode ser uma boa ideia estruturá-lo com algo fácil de transferir.
Phil
Se o seu jogo não é compatível com a sua própria poupança de formato de arquivo, você tem problemas muito maiores do que "a facilidade de transferência"
Gurgadurgen
As gravações XML e JSON seriam muito fáceis de adulterar (= fraude). Como desenvolvedor, você pode ou não concordar com isso.
Trang Oul