Estoy codificando mi final para un curso de Programación de videojuegos, y quiero saber cómo crear un archivo guardado para mi juego, para que un usuario pueda jugar y luego volver más tarde. Alguna idea de cómo se hace esto, todo lo que he hecho antes ha sido programas de ejecución única.
c++
savegame
serialization
Tucker Morgan
fuente
fuente
Respuestas:
Necesita usar la serialización para guardar sus variables en la memoria de su disco duro. Hay muchos tipos de serialización, en .NET XML es un formato común, aunque hay serializadores binarios y JSON disponibles. No soy un gran programador de C ++, pero una búsqueda rápida arrojó un ejemplo de serialización en C ++:
Hay bibliotecas que ofrecen funcionalidades de serialización. Algunos se mencionan en otras respuestas.
Las variables que le interesarán probablemente estarán relacionadas con el estado del juego. Por ejemplo, probablemente querrá saber este tipo de información
Realmente no le importará qué texturas se están utilizando (a menos que su jugador pueda cambiar su apariencia, ese es un caso especial), porque generalmente son las mismas. Debes concentrarte en guardar datos importantes del estado del juego.
Cuando comienzas tu juego, comienzas normalmente para un "nuevo" juego (esto carga tus texturas, modelos, etc.) pero en el momento apropiado cargas los valores de tu archivo guardado de nuevo en el objeto de estado del juego reemplazando el nuevo "predeterminado" estado del juego Luego permites que el jugador continúe jugando.
Lo he simplificado enormemente aquí, pero debes tener una idea general. Si tiene una pregunta más específica, haga una nueva pregunta aquí y podemos intentar ayudarlo.
fuente
Por lo general, esto es específico de tu juego. Estoy seguro de que hasta ahora has aprendido a escribir y leer archivos en tus clases. La idea básica es:
Lo que escribes depende de ti, depende de tu juego. Una forma de escribir es escribir las variables que desea en un orden específico como una secuencia de bytes. Luego, al cargar, léalos en su programa en el mismo orden.
Por ejemplo (en pseudocódigo rápido):
fuente
Probablemente hay una gran cantidad de formas de hacer esto, pero la más simple que siempre encontré y he usado tanto personal como profesionalmente es hacer una estructura que contenga todos los valores que quiero guardar.
Luego simplemente escribo / descargo los datos hacia y desde un archivo usando los valores básicos de File IO. InventoryCount es el número de estructuras de elementos que se guardan después de la estructura principal SaveGameData en el archivo, así que sé cuántas de ellas leer después de recuperar esos datos. La clave aquí es que cuando quiero guardar algo nuevo, a menos que sea una lista de elementos o similares, todo lo que tengo que hacer es agregar un valor a la estructura en algún lugar. Si se trata de una lista de elementos, entonces tendré que agregar un pase de lectura como ya he implicado para los objetos Elemento, un contador en el encabezado principal y luego las entradas.
Esto tiene el inconveniente de hacer que las diferentes versiones de un archivo guardado sean incompatibles entre sí sin un manejo especial (incluso si solo se trata de valores predeterminados para cada entrada en la estructura principal). Pero en general, esto hace que el sistema sea fácil de extender simplemente agregando un nuevo valor de datos y poniéndole un valor cuando sea necesario.
Una vez más, hay varias maneras de hacer esto y esto podría conducir más a C que a C ++, ¡pero ha hecho el trabajo!
fuente
Primero debe decidir qué datos deben guardarse. Por ejemplo, esta podría ser la ubicación del personaje, su puntaje y la cantidad de monedas. Por supuesto, su juego probablemente será mucho más complejo, por lo que deberá guardar datos adicionales, como el número de nivel y la lista de enemigos.
A continuación, escriba el código para guardar esto en un archivo (use ofstream). Un formato relativamente simple que puede usar es el siguiente:
Y entonces el archivo se vería así:
Lo que significaría que estaba en la posición (14, 96) con una puntuación de 4200 y 100 monedas.
También necesita escribir código para cargar este archivo (use ifstream).
Se puede salvar a los enemigos incluyendo su posición en el archivo. Podemos usar este formato:
Primero
number_of_enemies
se lee y luego cada posición se lee con un bucle simple.fuente
Una adición / sugerencia sería agregar un nivel de encriptación a su serialización para que los usuarios no puedan editar sus valores de texto a "9999999999999999999". Una buena razón para hacerlo sería evitar desbordamientos de enteros (por ejemplo).
fuente
Creo que su mejor apuesta es boost :: serialization porque es fácil de propagar en su jerarquía. Solo necesita llamar a la función guardar / cargar del objeto superior y todas sus clases se crean fácilmente.
Ver: http://www.boost.org/doc/libs/1_49_0/libs/serialization/doc/index.html
fuente
Para completar, quiero mencionar una biblioteca de serialización de c ++, que personalmente uso y que aún no mencioné: cereal .
Es fácil de usar y tiene una sintaxis agradable y limpia para la serialización. También ofrece múltiples tipos de formatos en los que puede guardar (XML, Json, Binario (incluida una versión portátil que respeta la resistencia)). Admite herencia y es solo de encabezado,
fuente
Su juego comprometerá las estructuras de datos (¿con suerte?) Que necesita transformar en bytes (serializar) para que pueda almacenarlos. En el futuro, puede volver a cargar esos bytes y transformarlos nuevamente en su estructura original (deserialización). En C ++ no es tan complicado ya que la reflexión es muy limitada. Pero aún así, algunas bibliotecas pueden ayudarlo aquí. Escribí un artículo al respecto: https://rubentorresbonet.wordpress.com/2014/08/25/an-overview-of-data-serialization-techniques-in-c/ Básicamente, sugeriría que eche un vistazo a biblioteca de cereales si puede apuntar a compiladores de C ++ 11. No es necesario crear archivos intermedios como con protobuf, por lo que ahorrará algo de tiempo allí si desea resultados rápidos. También puede elegir entre binario y JSON, por lo que puede ayudar bastante a depurar aquí.
Además de eso, si la seguridad es una preocupación, es posible que desee cifrar / descifrar los datos que está almacenando, especialmente si está utilizando formatos legibles por humanos como JSON. Algoritmos como AES son útiles aquí.
fuente
Debe usar
fstream
para archivos de entrada / salida. La sintaxis es simple EX:O
Otras acciones son posibles en su archivo: append , binary , trunc , etc. Debería usar la misma sintaxis que la anterior, en su lugar, ponemos std :: ios: :( flags), por ejemplo:
ios::out
para operación de salidaios::in
para operación de entradaios::binary
para operación binaria (byte sin formato) IO, en lugar de basada en caracteresios::app
para comenzar a escribir al final del archivoios::trunc
porque si el archivo ya existe, reemplace, elimine el contenido anterior y reemplácelo por uno nuevoios::ate
- posicione el puntero de archivo "al final" para entrada / salidaEx:
Aquí hay un ejemplo más completo pero simple.
fuente
goto
s, te lincharán en el lugar público. No usesgoto
s.