Tengo un juego que genera un mapa de nivel aleatorio al comienzo del nivel. Quiero implementar alguna forma de guardar y cargar el nivel.
Estaba pensando que tal vez XML sería una buena opción para guardar todas las variables, entonces sería fácil para mí construir algo que pueda analizar ese XML y generar exactamente el mismo nivel.
Pero XML es probablemente excesivo para mis necesidades. Recuerdo que en el pasado con la vieja consola Sega que no tenía la capacidad de guardar tu juego (creo que el juego de Worms también lo hizo), te daban un montón de personajes que podrías escribir. Si pinchaste esa cadena más tarde, cargaría el nivel exacto.
¿Sería una "cadena de nivel" una buena opción? ¿Sería algún tipo de conversión "base60"? ¿Cómo implementaría esto?
fuente
Independientemente del formato que utilice para guardar juegos, por amor de Dios, ingrese un número de versión. Podrá tener cargas compatibles con versiones anteriores ramificando en el número de versión, o podrá reconocer de forma segura los archivos guardados que son demasiado antiguos. cargar.
Te arrepentirás si no lo haces.
fuente
JSON es bueno, pero YAML es mejor. :) http://www.yaml.org/ y http://code.google.com/p/yaml-cpp/ para una de las implementaciones más agradables de usar.
YAML es un superconjunto de JSON que agrega soporte para algunas características agradables, en particular:
fuente
Si desea serializar todos los datos en el juego, recomendaría JSON como su formato de archivo, es por eso que es más fácil usar el XML y el soporte es muy bueno en muchos idiomas.
He usado esta biblioteca para C ++ y funciona muy bien.
http://jsoncpp.sourceforge.net/
fuente
XML es una buena opción si no está limitado por el tamaño y es compatible de forma nativa (por ejemplo, en .NET y Flash), pero si desea un formato delgado, puede crear su propio formato y analizador de manera bastante sencilla. Normalmente uso 1 carácter, por ejemplo. coma para separar cada objeto. Para decodificar la cadena, haga una división en coma. Ahora cada objeto necesita propiedades diferentes, así que sepárelos con un carácter diferente, por ejemplo, punto y coma, y use otro carácter para separar los nombres de propiedad de los valores de propiedad, por ejemplo. Colon. Todo esto se puede decodificar fácilmente sin expresiones regulares simplemente usando string.split. Aquí hay un ejemplo:
puede ahorrar aún más espacio manteniendo los nombres de propiedad en 1 carácter, por ejemplo, h para la salud. P.ej.
Compare con la alternativa JSON:
Además, si desea reducir el tamaño de sus números, puede codificarlos utilizando el conjunto completo de caracteres UTF16 imprimibles. Este hilo me inspiró a hacer una pregunta en Stack Overflow sobre la cantidad de datos que podría empaquetar en un personaje en pantalla . La respuesta parece estar en algún lugar de más de 40,000 valores para un número entero, si no te importa tener brail, kanji y piezas de ajedrez: ♔♕♖♗♘♙♚♛♜♝♞♟
Para obtener una mayor reducción de tamaño, puede usar el orden de lectura / escritura para determinar qué valor es cuál, por lo que los dos primeros caracteres representan la identificación, los dos siguientes son la posición x, los dos siguientes la y, luego el ángulo, luego la salud , etc. Entonces:
podría almacenar toda la misma información que los otros ejemplos.
Las cuadrículas de mosaico se pueden almacenar como una cadena con cada carácter que representa un tipo diferente de mosaico, por ejemplo:
donde podría decir lava, 9 hierba mala, etc.
fuente
Si está codificando en .Net, entonces XML es muy fácil de usar, ya que puede serializar / deserializar su clase de nivel dentro / fuera de XML con solo un par de líneas, y luego todo está en una clase bien administrada.
TheMap sería una variable de tipo Map en la que tiene todos sus datos cargados.
Suponiendo que ya tiene una clase Map construida, esto guardaría su mapa en XML:
Esto cargaría ese XML nuevamente en su clase de mapa, para ser usado nuevamente en el código.
A partir de este momento, su archivo XML ahora se carga en su clase para facilitar su uso.
En cuanto a su problema de "Cadena de nivel", lo que se dijo anteriormente funcionaría muy bien, podría usar el número de semilla como la "cadena de nivel".
De lo contrario, podría generar previamente la cantidad de mapas diferentes que desee, y guardarlos todos con una "Cadena de nivel" y luego usarlos para abrir el mapa adecuado.
fuente
Usaría un
struct
dispositivo simple o similar (dependiendo de su idioma) para almacenar todo el estado del juego en un lugar central. Si desea la protección de setters / getters, puede ajustar la estructura en aclass
.Si lo desea, utilice los campos de bits o simplemente manipule los bits usted mismo utilizando operadores bit a bit.
Tenga en cuenta que en algunos idiomas, las reglas para el relleno y el embalaje de la estructura pueden ser un poco complicadas, pero también puede no ser muy importante para su caso si tiene uno o dos bytes de relleno.
También puede usar un
#pragma
(como#pragma pack(1)
) o un__attribute__
para empacar la estructura, eliminando el relleno. Esto puede o no funcionar dependiendo de su compilador y arquitectura de destino.Tenga en cuenta que el uso de campos de bits y pragmas o atributos de paquete puede reducir la portabilidad. En arquitecturas de hardware, la capacidad de campo de estructura (orden de bytes) también puede cambiar. Por lo tanto, es posible que desee evitar esto si está intentando la portabilidad.
(Por ejemplo, Pac-Man, esta estructura podría contener ingenuamente una identificación de mapa o una semilla de mapa, una posición x-y de Pac-Man, cuatro posiciones x e y fantasmas, y un gran campo de bits para la presencia o ausencia de 32-64 gránulos, cualquiera que sea el máximo).
Una vez que tenga su estructura, páselo a algo así como una función xxencode :
Escribir esta función es un poco propenso a errores; necesita cambiar y combinar bytes según sea necesario para obtener, por ejemplo, 6 bits a la vez, luego traducir a un carácter apropiado. Personalmente, trataría de buscar el código de otra persona, a menos que lo hiciera por "diversión" (y probablemente querría un conjunto de pruebas para ello).
Nunca subestimes el poder de la vieja escuela
struct
en los lugares correctos. Lo hemos usado mucho para juegos de GBA y DS aquí.fuente
XML es bueno para documentos estructurados arbitrariamente (los elementos pueden aparecer en diferentes niveles del árbol) o la incrustación de formato externo (como poner svg en una página xhtml). Si no tiene esos requisitos, es un formato realmente ineficiente, y es preferible algo más simple como csv o json.
fuente