Come puoi mettere tutte le immagini di un gioco in 1 file?


67

Ho appena finito un gioco di ruolo di base scritto in SFML C ++, ho fatto molti sforzi nel gioco e vorrei distribuirlo, tuttavia ho riscontrato un piccolo problema.

Il problema è che ho ben oltre 200 immagini e file di mappe (sono file .txt che contengono codici di mappe) tutti nella stessa cartella dell'eseguibile, quando guardo nella cartella, mi viene da piangere un po 'vedendo così tante risorse, non ho mai visto un gioco che ti mostra tutte le risorse direttamente, invece credo che racchiudano le risorse in un determinato file.

Bene, questo è quello che sto cercando di ottenere: spero di racchiudere tutte le immagini in 1 file (forse anche i file .txt), quindi poter leggere da quel file o aggiungerlo facilmente.



Ho visto il codice in cui tutte le immagini erano racchiuse in una stringa nel codice. Ma ciò è stato fatto a causa di requisiti. (Era una competizione Java da 64 KB)
Omar Kooheji,

Mi dispiace è stata una competizione java 4Kb. Non uno da 64 KB.
Omar Kooheji,

Risposte:


62

I programmatori di giochi hanno fatto affidamento su uno dei due metodi principali di archiviazione dei dati:

  • memorizzare ogni file di dati come file separato
  • memorizzare ogni file di dati in un formato di archivio personalizzato

Lo svantaggio della prima soluzione è il problema di spazio su disco sprecato, nonché il problema delle installazioni più lente.

La seconda soluzione prevede le sue insidie, la prima è che devi scrivere tutta la tua immagine / suono / ecc. routine di caricamento che utilizzano un'API personalizzata per accedere ai dati archiviati. Un ulteriore svantaggio è che devi scrivere la tua utility di archiviazione per costruire gli archivi in ​​primo luogo.

A meno che non caricherai sempre tutti i file dall'archivio, TAR / GZ potrebbe non essere un'ottima idea, perché non puoi estrarre file specifici di cui hai bisogno. Questo è il motivo per cui molti giochi usano archivi ZIP, che ti permettono di estrarre singoli file come richiesto (un buon esempio è Quake 3, i cui file PK3 non sono altro che file ZIP con una diversa estensione).

EDIT: "Nascondi" la struttura delle cartelle di gioco e "Mantieni" solo gli eseguibili

Un'altra soluzione viene spesso utilizzata per "nascondere" i file di gioco nella struttura delle cartelle. Conserva solo i file eseguibili e forse un file Leggimi nella directory principale e sposta i file di gioco in una sottocartella denominata "dati" o altri relativi.

EDIT: Gamedev Tuts Plus ha una bella risorsa

EDIT: libarchico

Una potenziale soluzione libarchiva, che è una libreria di archiviazione che gestirà l'estrazione di file da un archivio come un file ZIP. Permette persino di assegnare il file estratto a un puntatore FILE standard, il che renderebbe potenzialmente più semplice l'interfacciamento con qualsiasi altra libreria.

EDIT: file in formato ZIP con estensione alternativa

Qui, mi piace il commento di @Joachim Sauer

L'utilizzo di file in formato ZIP con estensioni alternative ha una grande tradizione anche al di fuori dei giochi: lo fa Java , lo fa OpenDocument Format (alias OpenOffice / LibreOffice) , anche Office Open XML (alias il "nuovo" formato Microsoft Office) lo fa .


2
Sì, Thief / SystemShock2 ha usato anche i file .zip rinominati in qualcos'altro. In Java puoi usare qualcosa come TrueZip per accedere ai file in zip come se fossero file in cartelle, immagino ci siano librerie simili per C ++.
Nick,

18
L'utilizzo di file in formato ZIP con estensioni alternative ha una grande tradizione anche al di fuori dei giochi: lo fa Java , lo fa OpenDocument Format (alias OpenOffice / LibreOffice) , anche Office Open XML (alias il "nuovo" formato Microsoft Office) lo fa , ...
Joachim Sauer il

5
@Svish. A seconda della piattaforma, la quantità di spazio su disco occupata da molti file di piccole dimensioni può essere notevolmente maggiore della quantità occupata da un file di grandi dimensioni, anche se quel file di grandi dimensioni non è affatto compresso ( .tarad esempio). Ha a che fare con il modo in cui i dati vengono archiviati fisicamente sul disco.
TRiG il

1
Ah, è vero. Non dovrebbe essere molto, a meno che non ce ne siano molti , ma in tal caso può davvero accumularsi. Posso immaginare che l'installazione e la disinstallazione abbiano un successo anche con molti piccoli file.
Svish,

2
Leggermente correlato al commento di Kylotan, ecco un post di Jonathan Blow sul blog di sviluppo di The Witness sull'uso degli archivi e su come interagiscono con il meccanismo di patching di Steam. "The Witness racchiude la maggior parte dei suoi dati in un singolo file da 2 gigabyte archiviato nel formato .zip. Prima di caricare la versione iniziale su Steam, ho preso una precauzione per ridurre al minimo le dimensioni delle patch, o almeno così [...] (Immagina che i file siano memorizzati in ordine casuale: probabilmente ogni patch coinvolge tutti i giocatori che scaricano di nuovo l'intero gioco!) "
Eric

39

Un'altra soluzione spesso utilizzata per "nascondere" i file di gioco è la struttura delle cartelle. Conserva solo i tuoi eseguibili e forse un file Leggimi nella directory principale e sposta i file di gioco in una "cartella" sottocartella. Non penso che sia molto raro farlo. Molti giochi che conosco archiviano i loro contenuti in questo modo.


8
+1 Se lo spazio su disco o la protezione non rappresentano un problema, questa è la soluzione più semplice.
Laurent Couvidou,

1
+1 perché l'altro ragazzo ha detto +1. Non può essere sbagliato, eh? (Scherzi a parte, ottima risposta.)
jcora

Questa, secondo me, è la scelta ideale. Se il filesystem non è in grado di gestirlo in modo efficiente, il filesystem è rotto e dovresti appoggiarti al creatore del sistema operativo per migliorarlo.
Onnipotente il

3
@Omnifarious Questo non è sempre vero, ad esempio quando si legge da un disco ottico, anche con un filesystem perfetto, è comune comprimere i file in ordine di caricamento per evitare ricerche eccessive (la velocità può effettivamente essere abbastanza sorprendente). Ma questa è una storia totalmente diversa per i dischi rigidi, e tendo a pensare che l'OP sia in questo caso.
Laurent Couvidou,

3
@ Mr.Beast Ti sei perso il punto. Sto parlando di dischi ottici. Ho lavorato per uno studio in cui è stato il lavoro a tempo pieno di un singolo programmatore per assicurarsi che i file fossero impacchettati nel modo più efficiente possibile su un DVD, per ottenere il miglior tempo di caricamento possibile. Sono sicuro che sarebbe felice di sapere che avrebbe potuto fare affidamento solo sul file system del DVD;)
Laurent Couvidou,

22

Mi piace molto PhysFS per questo. Ti consente di accedere a cartelle o archivi zip con lo stesso codice. Funziona bene per tutte le fasi della vita di un gioco.

  1. Durante lo sviluppo : accedere alle risorse direttamente da una gerarchia di cartelle. In questo modo gli archivi compressi non sono di ostacolo e puoi iterare rapidamente.
  2. Implementazione iniziale : comprimere le risorse per una facile implementazione / installazioni rapide. Nessun codice deve cambiare. Basta puntare PhysFS sulla zip anziché sulla cartella.
  3. Aggiornamenti / Modding : PhysFS può caricare più archivi zip in cui le risorse dell'una sovrascrivono sull'altra. Gli aggiornamenti possono essere semplici come una nuova zip con solo i file modificati. Allo stesso modo per il modding.

aggiornare:

Ho usato il tutorial incluso con la documentazione sorgente e doxygen per imparare PhysFS. L'API è davvero abbastanza semplice, passerai più tempo a imparare a caricare immagini in SFML tramite buffer di memoria anziché tramite percorso del file.


4
Sto usando PhysFS per il mio progetto attuale e lo adoro. Non ho sempre bisogno di rigenerare il mio file di archivio dei contenuti; Posso semplicemente rilasciare una versione aggiornata nel percorso di ricerca e BAM! Funziona.
Zack The Human,

Dopo alcune risposte ho deciso che andrò con PhysFS. Ti andrebbe di consigliarti un bel tutorial? :)
Bugster,

12

Suggerirei di utilizzare un file ZIP. È un formato onnipresente e troverai librerie già pronte che ti consentono di caricare file da un file ZIP. Una rapida ricerca su Google ha persino rivelato un caricatore zip per sfml .


3

Bene, potresti imbrogliare come hanno detto :) Puoi creare un foglio di sprite dalle immagini, non è necessario comprimerlo al giorno d'oggi a meno che non risparmi un sacco di spazio. Dopo aver creato un foglio sprite o più fogli sprite dalle immagini, puoi semplicemente rinominare le loro estensioni. La maggior parte dei giocatori non si preoccuperà di controllare e perché non lasciare questa opzione agli artisti che potrebbero voler modificare il gioco in futuro? In questo modo possono anche creare un foglio sprite, rinominare la sua estensione e iniziare a rotolare.

Con i file di testo, suggerirei umilmente di convertire quei dati in forma binaria. Sono abbastanza sicuro che troverai un modo semplice per farlo. Ad esempio, se usi solo AZ, az e 0-9, puoi usare 6 bit per rappresentare ogni personaggio, che proteggerà in qualche modo il tuo materiale protetto da copyright, impedirà anche ad altri di modificare le mappe .. Se vuoi, puoi sempre aggiungere un convertitore di mappe. La compressione è del tutto ragionevole per il testo.


La conversione in binario è un buon consiglio ma non per la protezione: sarà solo più facile da analizzare e più veloce da caricare. Lo suggerirei come fase di pre-elaborazione, ma sarà fuori tema per la domanda.
Massimo

Bene, immagino che, se vuole proteggerlo in modo più efficace, potrebbe provare a crittografarlo in RSA o in un algoritmo simile (non è necessario). Dubito che qualcuno farà un uso non autorizzato dei file delle mappe da un gioco indipendente se si trova all'interno di un file binario. Non sembra che valga la pena investire il tempo a capire il nostro parsing. I file di testo sono completamente vulnerabili e come hai suggerito qualcosa di inefficace per l'archiviazione dei dati.
Wolfdawn,

3
Sui dischi rigidi, il caricamento di un singolo file zip è più rapido di molti file di piccole dimensioni perché sono presenti ricerche casuali meno costose sul disco fisico. Un binario per un piccolo gioco può essere mappato in memoria e funzionare "magicamente", non è richiesto quasi alcun analisi.
Liosan,

@Liosan Avresti potuto interpretare male quello che volevo dire o ti ho frainteso .. Ho detto che il binario è meglio per l'archiviazione dei dati e che è improbabile che altri progettisti di giochi vogliano imparare come analizzare il codice della mappa binaria, a meno che non sia documentato e incoraggiato per il modding scopi. Pertanto offre una protezione rudimentale sui file di testo.
Wolfdawn,

2

Non si tratta solo del numero di risorse o di spazio su disco.
Con molti file di trama diversi, poiché si utilizza SFML, che esegue il rendering con OpenGL, ogni volta che si esegue il rendering di una trama, OpenGL deve associare la trama successiva alla scheda video (controllare glBindTexture ()), ed è un compito davvero costoso.
Con questo in mente puoi capire perché i giochi di solito mettono un certo numero di sprite nella stessa trama, i cosiddetti fogli di calcolo, in base ai tuoi menu / livelli / mappe del gioco.
Il risultato è un enorme guadagno in termini di prestazioni, dal momento che stai eseguendo un rendering di molti sprite con la stessa chiamata texture bind.


Dopo aver ottenuto diversi riferimenti alla creazione di un foglio di calcolo ho preso in considerazione alcuni refactoring per ridurre il conteggio delle immagini. Grazie
Bugster,

2

Personalmente vorrei seguire il percorso del file binario personalizzato per questo. Questo è qualcosa che faccio da solo tutto il tempo ora, non è così difficile come potrebbe sembrare e fornisce anche un livello di offuscamento per i file delle risorse di gioco. Ho scritto un piccolo articolo introduttivo di Gamedev su questo non molto tempo fa se sei interessato:

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

Le schede Sprite sono un argomento completamente diverso ma sono la norma per la maggior parte dei giochi :)


1

Un altro metodo che puoi usare:

La versione gratuita di XnView fornisce una funzione chiamata " Strip of Images" (MAIUSC + A), che consente di creare sprite-collections.

Ciò riduce al minimo l'accesso ai file ed è particolarmente importante per le applicazioni / i giochi Web per ridurre al minimo il numero di HTTP-roundtrips.

L'accesso alle singole immagini viene quindi concesso tramite mappe coordinate (ad esempio definizioni css).


0

Per prima cosa devi scrivere tutta la tua immagine / suono / ecc. routine di caricamento che utilizzano un'API personalizzata per accedere ai dati archiviati. Un ulteriore svantaggio è che devi scrivere la tua utility di archiviazione per costruire gli archivi in ​​primo luogo. A meno che non caricherai sempre tutti i file dall'archivio, TAR / GZ potrebbe non essere un'ottima idea, perché non puoi estrarre file specifici di cui hai bisogno. Questo è il motivo per cui molti giochi usano archivi ZIP, che ti permettono di estrarre singoli file come richiesto (un buon esempio è Quake 3, i cui file PK3 non sono altro che file ZIP con una diversa estensione). http://zpp-library.sourceforge.net/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.