¿Cómo puedo escribir un sistema Guardar / Cargar para mi juego?

17

Estoy tratando de encontrar una manera de escribir un sistema de guardar / cargar para mi juego en C ++. A partir de ahora, lo estoy haciendo todo usando banderas binarias. ¿Alguien tiene idea de cómo hacerlo de otra manera? No me importa usar binarios, pero quiero saber mis opciones. También quiero algo en lo que sea fácil verificar el estado de un solo evento completo o incompleto para decidir ciertas cosas (gran parte del sistema de elementos en este juego depende de lo que el jugador haya hecho o no) a lo largo del juego).

sonicbhoc
fuente
1
En realidad, después de mirarlo, podría ser mejor para mí seguir con Python para este proyecto. Estoy usando Panda3D como motor de juego, y la versión de Python está más pulida. Eso, y probablemente podría desarrollarme más rápido en Python. Además, python tiene una clase de serialización incorporada llamada pickle, que me ahorra la molestia de codificar una.
sonicbhoc

Respuestas:

5

La serialización sería el camino a seguir, y en cuanto a la verificación del estado, podría tener lógica en el método de deserialización para hacerlo.

ThatsGobbles
fuente
Lo estoy leyendo aquí ( parashift.com/c++-faq-lite/serialization.html ) y se ve muy interesante. Realmente nunca he tratado con la serialización, por lo que será una buena experiencia de aprendizaje para mí. ¡Gracias!
sonicbhoc
¡No hay problema! También estoy trabajando con la serialización (aunque en C #) para mi juego. ¡Buena suerte!
ThatsGobbles
44
tenga en cuenta: si serializa, siempre almacene primero un número de versión y vuelva a leerlo primero. De esa manera, puede manejar los cambios importantes en el formato del juego guardado con gracia al proporcionar (algunos) compatibilidad con versiones anteriores.
LearnCocos2D
44
Durante el desarrollo, también le recomiendo que escriba los archivos en un formato legible para humanos. Tal vez algo como JSON o XML. Es mucho más fácil ver si se guardó todo lo que necesita y también es mucho más fácil modificar los datos en un archivo ya escrito (para probar o arreglar cosas después de escribir un archivo en el disco).
bummzack
5

He estudiado un poco el código fuente de DOOM. Te diré cómo se hace allí.

D_DoomMain contiene todas las funciones de abrir / guardar / cargar, así como muchas otras cosas. Como dice al principio del archivo,

// 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.

Básicamente, todo el archivo está lleno de M_CheckParms de principio a fin. En eso consiste el D_DoomLoop. Es un bucle masivo (algo así como 1000-2000 líneas de largo).

Dado que su pregunta es '¿Cómo puedo escribir?' Solo voy a pegar algunos bits de código que se refieren a los juegos guardados, de D_DoomMain:

Aquí están las declaraciones donde se usan esas cosas, al final del ciclo.

   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

Aquí está la función que accede a las cadenas, que encontrará dispersas en todo el 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;
   }
}

También tienes un archivo llamado p_savegame.c con cosas que guardarán todos los datos asociados al usuario (qué armas tienes, dónde estás en qué nivel, etc.).

Y finalmente tienes el archivo que carga los datos del juego guardado en un escenario de juego, posiblemente el más complejo de todos, porque también carga todo lo demás. Ese se llama p_setup.c, y se encuentra en el mismo directorio.

Me funcionó bien para cattodos estos en un búfer de texto y pipeese texto sendmaila mi propia dirección de correo electrónico. De esa manera puedo leerlo en los momentos extraños del día, y usar 'buscar' cuando quiero buscar cosas como 'cómo DOOM carga un juego'. El código está bien comentado.

ixtmixilix
fuente
3

Puede serializar la clase o los datos en un archivo plano y luego volver a leerlos cuando cargue.

Ólafur Waage
fuente
Debido a un firewall corporativo, no pude acceder a esos enlaces. Lo siento.
sonicbhoc
44
Si su corporación le impide leer cosas que necesita para trabajar, son idiotas en el mejor de los casos.
o0 '.
2
Bueno, este no es mi trabajo todavía. : P (y tal vez "corporativa" no era la mejor palabra ... es un firewall en mi escuela)
sonicbhoc
-1

I +1: edité la sugerencia de usar XML / JSON para estructurar los juegos guardados. De esta manera, está muy preparado para hacer que los guardados se basen en la "nube". O al menos, tendrá una estructura que podría usar para futuros proyectos que podrían involucrar a la web. Siempre que los archivos no se almacenen de una manera que sea demasiado fácil de leer, deberían brindarle muchos beneficios. Me gusta las métricas! Hurra

Phil
fuente
1
El almacenamiento en la nube solo significa que está almacenando los ahorros en línea. Puede hacerlo con cualquier formato de archivo.
Yo sé eso. Pero para fines de comunicación, puede ser una buena idea estructurarlo con algo que sea fácil de transferir.
Phil
Si su juego no es compatible con su propio formato de archivo guardado, tiene problemas mucho mayores que la "facilidad de transferencia"
Gurgadurgen
XML y JSON guardar sería muy fácil de manipular (= trampa). Como desarrollador, puede o no estar bien con eso.
Trang Oul