¿Cómo puedes poner todas las imágenes de un juego en 1 archivo?

67

Acabo de terminar un juego de rol básico escrito en C ++ SFML, he puesto mucho esfuerzo en el juego y me gustaría distribuirlo, sin embargo, me encontré con un pequeño problema.

El problema es que tengo más de 200 imágenes y archivos de mapas (son archivos .txt que contienen códigos de mapas) todos en la misma carpeta que el ejecutable, cuando miro en la carpeta, me dan ganas de llorar un poco al ver tantos recursos, nunca he visto un juego que te muestre todos los recursos directamente, en cambio creo que empaquetan los recursos en un archivo determinado.

Bueno, eso es lo que estoy tratando de lograr: espero empacar todas las imágenes en 1 archivo (tal vez también los archivos .txt) y luego poder leer desde ese archivo o agregarlo fácilmente.

Bugster
fuente
He visto código donde todas las imágenes se empaquetaron en una cadena en el código. Pero eso se hizo debido a los requisitos. (Fue una competencia Java de 64 KB)
Omar Kooheji
Lo siento, fue una competencia de 4Kb Java. No uno de 64Kb.
Omar Kooheji

Respuestas:

62

Los programadores de juegos se han basado en uno de los dos métodos principales de almacenamiento de datos:

  • almacenar cada archivo de datos como un archivo separado
  • almacenar cada archivo de datos en un formato de archivo personalizado

El inconveniente de la primera solución es el problema del espacio de disco desperdiciado, así como el problema de las instalaciones más lentas.

La segunda solución proporciona sus propias trampas, primero es que debe escribir toda su propia imagen / sonido / etc. cargar rutinas que usan una API personalizada para acceder a los datos archivados. Otro inconveniente es que, en primer lugar, debe escribir su propia utilidad de archivo para crear los archivos.

A menos que siempre cargue todos los archivos del archivo, TAR / GZ podría no ser una muy buena idea, porque no puede extraer archivos específicos ya que los necesita. Esta es la razón por la que muchos juegos usan archivos ZIP, que te permiten extraer archivos individuales según sea necesario (un buen ejemplo es Quake 3, cuyos archivos PK3 no son más que archivos ZIP con una extensión diferente).

EDITAR: "Ocultar" la estructura de carpetas del juego y "Guardar" solo los ejecutables

A menudo se usa otra solución para "ocultar" los archivos del juego en la estructura de carpetas. Mantenga solo sus archivos ejecutables y tal vez un archivo Léame en el directorio principal y mueva los archivos del juego a una subcarpeta llamada "datos" u otros relacionados.

EDITAR: Gamedev Tuts Plus tiene un buen recurso

EDITAR: libarchive

Una posible solución libarchive, que es una biblioteca de archivo que se encargará de extraer archivos de un archivo como un archivo ZIP. Incluso le permite asignar el archivo extraído a un puntero de ARCHIVO estándar, lo que haría la interfaz con cualquier otra biblioteca potencialmente más sencilla.

EDITAR: archivos de formato ZIP con extensión alternativa

Aquí, me gusta el comentario de @Joachim Sauer

El uso de archivos en formato ZIP con extensiones alternativas también tiene una gran tradición fuera de los juegos: Java lo hace , el formato OpenDocument (también conocido como el formato OpenOffice / LibreOffice) lo hace , incluso Office Open XML (también conocido como el "nuevo" formato Microsoft Office) lo hace .

Mahbubur R Aaman
fuente
2
Sí, Thief / SystemShock2 también utilizó archivos .zip renombrados como otra cosa. En Java puedes usar algo como TrueZip para acceder a archivos en zip como si fueran archivos en carpetas, imagino que hay bibliotecas similares para C ++.
Nick
18
El uso de archivos en formato ZIP con extensiones alternativas también tiene una gran tradición fuera de los juegos: Java lo hace , el formato OpenDocument (también conocido como el formato OpenOffice / LibreOffice) lo hace , incluso Office Open XML (también conocido como el "nuevo" formato Microsoft Office) lo hace , ...
Joachim Sauer
55
@Svish. Dependiendo de la plataforma, la cantidad de espacio en disco que ocupan muchos archivos pequeños puede ser considerablemente mayor que la cantidad ocupada por un archivo grande, incluso si ese archivo grande no está comprimido en absoluto ( .tarpor ejemplo). Tiene que ver con la forma en que los datos se almacenan físicamente en el disco.
TRiG
1
Ah, eso es verdad. Sin embargo, no debería ser mucho, a menos que haya muchos , pero en ese caso puede acumularse. Me imagino que la instalación y la desinstalación también se ven afectadas con muchos archivos pequeños.
Svish
2
Ligeramente relacionado con el comentario de Kylotan, aquí hay una publicación de Jonathan Blow en el blog de desarrollo de The Witness sobre el uso de archivos y cómo interactúan con el mecanismo de parcheo de Steam. "The Witness empaqueta la mayoría de sus datos en un solo archivo de 2 gigabytes almacenado en el formato .zip. Antes de cargar la versión inicial en Steam, tomé una medida de seguridad para minimizar el tamaño de los parches, o eso pensé [...] esos archivos se almacenan en orden aleatorio: ¡probablemente cada parche implique que cada jugador vuelva a descargar todo el juego! ""
Eric
39

Otra solución utilizada a menudo para "ocultar" los archivos del juego es la estructura de carpetas. Guarde solo sus ejecutables y tal vez un archivo Léame en el directorio principal y mueva los archivos del juego a una subcarpeta "datos". No creo que sea muy raro hacerlo. Muchos juegos que conozco almacenan su contenido de esa manera.

tom van green
fuente
8
+1 Si el espacio en disco o la protección no son un problema, esa es la solución más fácil.
Laurent Couvidou
1
+1 porque el otro tipo dijo +1. No puede estar equivocado, ¿eh? (Bromas aparte, gran respuesta.)
jcora
Esto, en mi opinión, es la opción ideal. Si el sistema de archivos no puede manejar eso de manera eficiente, el sistema de archivos está dañado y debería confiar en el fabricante del sistema operativo para mejorarlo.
Omnifarious
3
@Omnifarious Eso no siempre es cierto, por ejemplo, cuando se lee desde un disco óptico, incluso con un sistema de archivos perfecto, es común empacar los archivos en orden de carga para evitar una búsqueda excesiva (la velocidad puede ser bastante sorprendente). Pero esta es una historia totalmente diferente para los discos duros, y tiendo a pensar que el OP es en este caso.
Laurent Couvidou
3
@ Mr.Beast Te perdiste mi punto. Estoy hablando de discos ópticos. Trabajé para un estudio donde era un trabajo de tiempo completo de un solo programador para asegurarme de que los archivos se empaquetaran de la manera más eficiente posible en un DVD, para obtener el mejor tiempo de carga posible. Estoy seguro de que le agradaría saber que podría haber confiado en el sistema de archivos de DVD;)
Laurent Couvidou
22

Realmente me gusta PhysFS para esto. Le permite acceder a carpetas o archivos zip con el mismo código. Funciona bien para todas las etapas de la vida de un juego.

  1. Durante el desarrollo : acceda a los recursos directamente desde una jerarquía de carpetas. De esta forma, los archivos comprimidos no se interponen y puede iterar rápidamente.
  2. Implementación inicial : comprima sus recursos para una fácil implementación / instalación rápida. Ningún código necesita cambiar. Simplemente apunte PhysFS al zip en lugar de a la carpeta.
  3. Actualizaciones / Modding : PhysFS puede cargar múltiples archivos zip donde los recursos de uno anulan al otro. Las actualizaciones pueden ser tan simples como un nuevo zip con solo los archivos modificados. Del mismo modo para el modding.

actualizar:

Utilicé el tutorial incluido con la fuente y la documentación de doxygen para aprender PhysFS. La API realmente es bastante simple, pasará más tiempo aprendiendo cómo cargar imágenes en SFML a través de buffers de memoria en lugar de por ruta de archivo.

código_deft
fuente
44
Estoy usando PhysFS para mi proyecto actual y me encanta. No siempre necesito regenerar mi archivo de contenido; ¡Puedo dejar caer una versión actualizada en la ruta de búsqueda y BAM! Funciona.
Zack The Human
Después de algunas respuestas, decidí ir con physFS. ¿Te gustaría recomendar un buen tutorial? :)
Bugster
12

Sugeriría usar un archivo ZIP. Es un formato omnipresente y encontrará bibliotecas listas para usar que le permiten cargar archivos desde un archivo ZIP. Una búsqueda rápida en Google incluso reveló un cargador zip para sfml .

bummzack
fuente
3

Bueno, podrías hacer trampa como lo mencionaron :) Puedes hacer una hoja de sprite a partir de las imágenes, no hay necesidad de comprimirla hoy en día a menos que ahorre una tonelada de espacio. Después de crear una hoja de sprites o varias hojas de sprites a partir de las imágenes, simplemente puede cambiar el nombre de sus extensiones. La mayoría de los jugadores no se molestarán en comprobar y ¿por qué no dejar esa opción a los artistas que quieran modificar tu juego en el futuro? De esa manera, también pueden crear una hoja de sprite, cambiar el nombre de su extensión y comenzar a rodar.

Con los archivos de texto, sugeriría humildemente que convierta esos datos en forma binaria. Estoy bastante seguro de que encontrará una manera simple de hacerlo. Por ejemplo, si solo usa AZ, az y 0-9, puede usar 6 bits para representar cada carácter, lo que de alguna manera protegerá su material protegido por derechos de autor. también evitará que otros editen mapas. Siempre puede agregar un convertidor de mapas si lo desea. Sin embargo, la compresión es completamente razonable para el texto.

Wolfdawn
fuente
La conversión a binario es un buen consejo, pero no para protección: será más fácil analizar y cargar más rápido. Lo sugeriría como un paso de preprocesamiento, pero eso estará fuera de tema para la pregunta.
Maximus Minimus
Bueno, supongo que si quiere protegerlo de manera más efectiva, podría intentar cifrarlo en RSA o un algoritmo similar (no es necesario). Dudo que alguien haga un uso no autorizado de los archivos de mapas de un juego independiente si está dentro de un archivo binario. Simplemente no parece que valga la pena invertir el tiempo en calcular nuestro análisis. Los archivos de texto son completamente vulnerables y, como sugirió, algo ineficaz para almacenar datos.
wolfdawn
3
En los discos duros, cargar un único archivo zip es más rápido que muchos archivos pequeños porque hay búsquedas aleatorias menos costosas en el disco físico. Un binario para un juego pequeño puede mapearse en la memoria y funcionar "mágicamente", casi no requiere análisis.
Liosan
@Liosan Podrías haber malinterpretado lo que quise decir o no te he entendido bien. Dije que binario es mejor para almacenar datos y que es poco probable que otros diseñadores de juegos quieran aprender cómo analizar tu código de mapa binario, a menos que esté documentado y fomentado su modificación. propósitos Por lo tanto, ofrece una protección rudimentaria sobre los archivos de texto.
wolfdawn
2

No se trata solo de la cantidad de recursos o espacio en disco.
Con una gran cantidad de archivos de textura diferentes, ya que está utilizando SFML, que se procesa con OpenGL, cada vez que va a representar una textura, OpenGL necesita vincular la siguiente textura a la tarjeta de video (marque glBindTexture ()), y es Una tarea realmente costosa.
Con eso en mente, puedes darte cuenta de por qué los juegos generalmente ponen una serie de sprites en la misma textura, las llamadas hojas de sprites, de acuerdo con tus menús / niveles / mapas del juego.
El resultado es una gran ganancia en rendimiento, ya que está renderizando muchos sprites con la misma llamada de textura de enlace.

Edmo Freitas
fuente
Después de obtener varias referencias para hacer una hoja de sprites, he considerado algunas refactorizaciones para reducir el recuento de imágenes. Gracias
Bugster
2

Personalmente, me dirigiría a la ruta del archivo binario personalizado para esto. Esto es algo que hago todo el tiempo ahora mismo, no es tan difícil como podría parecer, y también proporciona un nivel de ofuscación para los archivos de recursos del juego. Escribí un pequeño artículo introductorio de Gamedev sobre esto no hace mucho tiempo si estás interesado:

http://gamedev.tutsplus.com/tutorials/implementation/create-custom-binary-file-formats-for-your-games-data/

Las hojas de sprites son un tema completamente diferente, pero son la norma para la mayoría de los juegos :)

Si Robertson
fuente
1

Otro método que puedes usar:

La versión gratuita de XnView proporciona una función llamada " Strip of Images" (SHIFT + A), que le permite crear sprite-collections.

Esto minimiza el acceso a los archivos y es particularmente importante para las aplicaciones web / juegos para minimizar el número de HTTP-roundtrips.

El acceso a imágenes individuales se concede a través de mapas de coordenadas (por ejemplo, definiciones css).

Lorenz Lo Sauer
fuente
0

Primero debe escribir toda su propia imagen / sonido / etc. cargar rutinas que utilizan una API personalizada para acceder a los datos archivados. Otro inconveniente es que, en primer lugar, debe escribir su propia utilidad de archivo para crear los archivos. A menos que siempre cargue todos los archivos del archivo, TAR / GZ podría no ser una muy buena idea, porque no puede extraer archivos específicos ya que los necesita. Esta es la razón por la que muchos juegos usan archivos ZIP, que le permiten extraer archivos individuales según sea necesario (un buen ejemplo es Quake 3, cuyos archivos PK3 no son más que archivos ZIP con una extensión diferente). http://zpp-library.sourceforge.net/


fuente