Come comprimere il gioco fotogramma per fotogramma al minimo sul disco


19

Sto sviluppando un gioco come Age of empire (edifici sulla mappa) e per ogni edificio ho un foglio sprite per la sua animazione. Sto usando l'animazione fotogramma per fotogramma per animare l'edificio (non sono a conoscenza di altri metodi comunque). Sto notando che la mia cartella delle risorse sta diventando estremamente grande a causa delle immagini che sto inserendo.

In che modo giochi come CoC e Age of Empires mantengono le loro dimensioni dell'apk sotto i 50 Mg? Mi manca qualcosa qui quando si tratta di sviluppo del gioco

Grazie

EDIT: maggiori informazioni sul problema che sto affrontando

Ho un sacco di animazioni oggetti disegnabili. Ho scelto in questo modo perché era il più veloce e stava producendo i risultati desiderati. Fondamentalmente ogni edificio è un disegno animato in cui il suo file xml fa riferimento a 8 disegni (8 immagini = 8 file). Tutti loro sono PNG a causa della trasparenza. Dato che ho oltre 200 immagini, la dimensione dell'apk è di 120 MB (e non ho ancora finito di copiare metà dei file). Questo è ciò che richiede, ci deve essere un modo per risolverlo. Per favore assisti un collega sviluppatore


Comprimere le immagini o separare i contenuti di gioco dall'apk potrebbe essere quello che stai cercando.
János Turánszki,

Intendi i file di espansione? Il problema che i file di espansione non hanno cartelle disegnabili con densità diverse. È questo che fanno i giochi? Sto realizzando l'animazione fotogramma per fotogramma (immagine edificio completo). O sono totalmente sulla strada sbagliata
Snake,

Per ogni evenienza, ho cercato di essere di aiuto e di fornire una risposta relativa al risparmio di spazio per le tue immagini. Tuttavia, la tua domanda è confusa: non è chiaro se vuoi davvero conoscere tecniche come quelle legate a "in che modo giochi come CoC ed Age of Empires mantengono le loro dimensioni dell'apk sotto i 50 Mg?" o se desideri solo controllare se ci sono meno modi affamati di animare spazio su disco (come suggerisce il tuo titolo). Per favore chiarisci, così posso cancellare la mia risposta se è così e anche così puoi ottenere risposte più precise.
Ma

@Ma ho modificato la mia risposta per riflettere ulteriormente sul problema
Snake,

2
Per Age of Empires, è probabilmente una combinazione di bassa risoluzione (IIRC è stata progettata per 640x480) e immagini indicizzate (non RGB completo).
user253751

Risposte:


24

Non è chiaro dalla tua domanda se vuoi davvero conoscere le tecniche che consentono ai giochi di risparmiare spazio su disco anche quando hanno grandi quantità di file di immagini / risorse pesanti (questo è ciò che si trova nel corpo della domanda), o se vuoi solo sapere se ci sono meno modi affamati di spazio su disco per fare animazione per i tuoi edifici (questo è ciò che è implicito dal titolo della tua domanda).

Quindi, inserirò questa risposta qui cercando di essere di aiuto in relazione al risparmio di spazio quando si hanno molte immagini. Se sei interessato solo a conoscere le tecniche di animazione che potrebbero permetterti di risparmiare spazio su disco, per favore fatemelo sapere, potrei cancellare la risposta.


Detto questo, in una situazione simile, due soluzioni che ho visto (e usato una volta) in termini di risparmio di spazio sul disco erano:

1) concatenare singole immagini all'interno di una stessa immagine. A volte può essere di aiuto. Quindi, invece di salvare 4 file separati per ciascuno dei seguenti quadrati colorati, li salvo tutti fianco a fianco all'interno della stessa immagine (e li dividerò solo tramite il codice di gioco):

enter image description here

In questo esempio, il salvataggio di ciascuno in 4 diversi file PNG ammonta a 1255 byte, mentre il singolo file con tutti concatenati è 451 byte. Ovviamente, quanto potrebbe aiutare dipende caso per caso e dovresti testare per vedere se questo può esserti di aiuto a seconda delle tue immagini.

2) per comprimere la cartella delle risorse. Questo può spesso essere molto utile per risparmiare spazio su disco. Quindi, quando il gioco è in esecuzione, puoi decomprimere o estrarre l'immagine desiderata dal file compresso, a seconda del formato di compressione che usi. Vedi la risposta passata che è diventata una wiki di questo sito: /gamedev//a/37649/72423

Ma tieni anche presente che ogni tipo di compressione può essere più o meno vantaggioso a seconda del tipo di file immagine che usi : Evita la doppia compressione delle risorse

Per maggiori dettagli sulla compressione: lo stato dell'arte nella compressione delle immagini?


Infine, potresti anche essere interessato a pensare quali tipi di immagini utilizzare per ogni situazione: quale formato di immagine è più efficiente in termini di memoria: PNG, JPEG o GIF?


Grazie per l'informazione. È strano che tu sia riuscito a dimezzare la dimensione del file mettendo le cose in un unico file. Ho pensato alla fine della giornata, è lo stesso numero di pixel e lo stesso spazio utilizzato. Ho modificato la mia domanda per una risposta migliore
Snake

@Snake Quindi, per la modifica che hai apportato, penso che la mia risposta possa davvero essere utile. Concatenare immagini + compressione può ridurre le dimensioni della cartella di una quantità enorme. Entrambe le tecniche sono regolarmente utilizzate in alcuni tipi di giochi. Riguardo alla concatenazione, è sempre un trucco sorprendente. Provalo tu stesso: metti le immagini di una sequenza di una tua animazione fianco a fianco e confronta le dimensioni finali con la somma delle singole immagini. Quindi puoi vedere se questo aiuta nel tuo caso. Come per la compressione, per PNG tende ad essere meno efficaci, ma comunque vale la pena di dimensioni taglio della cartella finale
MAnd

@Snake un'osservazione, però: concatenare a volte non vale o addirittura aumenta un po 'le dimensioni finali. Ma spesso può offrire una riduzione desiderabile. Tutto dipende dalle vostre immagini
MAnd

Ricordo di aver provato entrambe le tecniche e la riduzione era inferiore al 10%. Conosco sicuramente la compressione non importa con PNG ma proverò la concatenazione. Ecco perché ho chiesto come lo fanno altri giochi perché ovviamente hanno molta più grafica della mia
Snake,

Non dovresti essere in grado di comprimere una cartella piena di immagini. Le immagini dovrebbero già essere compresse e non dovrebbero avere sequenze molto ripetibili. Se lo facessero, quel livello extra di compressione sarebbe parte del codec dell'immagine ...
corsiKa

9

Vorrei proporti di provare TexturePacker

  • puoi semplicemente trascinare e rilasciare tutte le tue immagini e farle impacchettare
  • puoi applicare una compressione diversa, ad esempio utilizzare PNG indicizzati che consumano molta meno memoria, fino al 70% in meno rispetto a un file PNG standard
  • puoi creare un file di dati contenente il nome + posizione di ciascuno dei tuoi edifici
  • la versione gratuita potrebbe già essere sufficiente per creare i fogli sprite per te

Usi un framework di sviluppo di giochi come AndEngine, Cocos2d-x o LibGdx? => Nessuno

Hai bisogno di caricare tutte le tue immagini contemporaneamente? Sembra che ti imbatterai in enormi problemi di RAM sui dispositivi di destinazione.


Aggiornamento: Snake mi ha inviato alcune immagini. Come promesso non li renderò pubblici qui, quindi ho creato un po 'di arte per dimostrare come ridurre l'utilizzo della memoria.

Nell'immagine originale, solo una parte dell'immagine era in movimento. Ho messo un uccello su una casa per dimostrarlo:

inserisci qui la descrizione dell'immagine

Fondamentalmente impacchettare l'animazione completa in un foglio è un grande spreco di memoria. È necessario dividere le parti statiche e mobili:

Statico:

inserisci qui la descrizione dell'immagine

Anim01:

inserisci qui la descrizione dell'immagine

Anim02:

inserisci qui la descrizione dell'immagine

Mantieni la posizione originale dell'uccello nelle immagini . Questo è il motivo per cui c'è così tanto spazio vuoto sopra. Ne hai bisogno per allineare l'animazione.

Ora trascina le immagini su TexturePacker e seleziona i seguenti parametri

  • Formato dei dati: hash JSON (o XML se lo preferisci)
  • TrimMode: Trim (questo crea rettangoli)
  • Formato pixel: INDICE 8 bit - per creare PNG a 8 bit (circa il 70% di memoria in meno)
  • Consenti rotazione: falso
  • Immettere un nome file per i dati

TexturePacker che imballa le immagini

Il risultato è che ora ottieni 2 file: il foglio sprite e un file di descrizione JSON.

"house_anim_01.png":
{
    "frame": {"x":351,"y":246,"w":110,"h":79},
    "rotated": false,
    "trimmed": true,
    "spriteSourceSize": {"x":67,"y":8,"w":110,"h":79},
    "sourceSize": {"w":400,"h":400},
    "pivot": {"x":0.5,"y":0.5}
},

Le parti importanti sono frame e spriteSourceSize .

La cornice ti dà la posizione dello sprite originale nel foglio sprite.

spriteSourceSize ti dà l'offset per il disegno dell'immagine - le parti dell'immagine che vengono lasciate fuori a causa del taglio:

Una semplice routine di disegno pseudo-codice si presenta così:

drawImage(spritename, posX, posX)
{
    data    = sheetData[spritename]
    offsetX = data.spriteSourceSize.x
    offsetY = data.spriteSourceSize.y
    frameX  = data.frame.x
    frameY  = data.frame.y
    width   = data.frame.w
    height  = data.frame.h
    screen.draw(sheetImage, posX+offsetX, posY+offsetY, width, height)
}

Potrebbe essere necessario regolare il calcolo dell'offset in base al punto di articolazione / origine nel sistema grafico. La routine sopra presuppone un sistema di coordinate la cui origine è in alto a sinistra.

Quindi disegna semplicemente la casa in 2 passaggi:

draw("background", 100, 100);
draw("anim_01", 100, 100);

Non devi preoccuparti degli offset, poiché le immagini sono già allineate.


+1 per l'osservazione sull'uso della RAM, che altre persone stanno ignorando
Dan Hulme,

@Andreas Lo controllerò. Grazie. Non ridere di me ma non sto usando un motore. È principalmente fatto con animazioni e disegni e funziona come un fascino. Non carico tutte le immagini nella memoria, nessun altro saggio si bloccherà. Carica solo le immagini necessarie per la visualizzazione al momento .. pensi che il suggerimento sopra funzionerebbe con l'SDK Android standard?
Snake,

1
Si lo farà. TexturePacker ha 2 modalità per tagliare gli sprite: rettangoli e poligoni. Se usi immagini isometriche potresti ottenere un grande vantaggio dalle mesh poligonali in termini di imballaggio. La domanda è se si sarebbe in grado di disegnare triangoli strutturati - o rettangoli con una maschera. In caso contrario, puoi comunque utilizzare i rettangoli. Puoi inviarmi alcune delle tue immagini se vuoi usare dropbox e inviare un link a -> supporto su codeandweb. com. Non li condividerò - sono solo interessato a vedere cosa possiamo fare per migliorare l'imballaggio.
Andreas Löw,

@ AndreasLöw Mi dispiace tanto, non ho ricevuto la notifica del tuo commento. L'ho appena visto. Apprezzerò molto l'aiuto. Ti invierò qualcosa e forse potresti far luce su ciò che dovrei. ..kinda rimanere bloccato con qualcosa in cui ho poca esperienza e forse puoi far luce. Ti contatterò presto
Snake il

7

Ecco alcuni puntatori che puoi usare

  1. Cerca di assicurarti che tutti i tuoi sfondi e le immagini non trasparenti non siano in formato PNG
  2. Cerca di abilitare tutti i loop di animazione, ad esempio se l'animazione è 1,2,3,4,5,6 prova a renderla simile a 1,2,3,4,3,2,1 dove questi numeri sono il numero di fotogrammi dell'animazione, aiuta molto
  3. se molte immagini sono uguali e solo il colore differisce (generalmente pulsanti dell'interfaccia utente, animazioni di particelle m, monete di gioco) quindi prova a prendere un'immagine bianca e a cambiarne il colore in modo dinamico
  4. Prova a rendere il tuo .apk solo con quelle immagini estremamente importanti, quindi carica tutto da un server e tienilo nella memoria del telefono

Spero che questi suggerimenti aiutino

PS Mi viene solo un'idea generalizzata poiché non sono a conoscenza del tuo esatto contenuto di gioco e mi scuso se questi suggerimenti non sono utili


Puoi anche: 1) comprimere tutte le tue immagini 2) usare le tessere il più spesso possibile 3) concatinare le immagini per riunirle in un'immagine più grande e usarle come mappa uv per la trama
Anthony Raimondo,

Questi sono ottimi suggerimenti. Grazie. Penso che il punto più importante sia 4. Tuttavia, in tal caso, come posso metterli nelle diverse cartelle disegnabili e fare riferimento a loro come R.drawable.image1? Ecco dove sono confuso
Snake,

4

Molti giochi non mantengono le loro risorse grafiche in .apk; includono solo le "basi" come la grafica dell'interfaccia utente e il codice del gioco e scaricano il resto delle risorse una volta che il gioco è stato installato. Ciò è particolarmente vero per i giochi che utilizzano risorse grafiche diverse a seconda della risoluzione del display per evitare che .apk debba contenere sia risorse a bassa risoluzione che ad alta risoluzione.

Dovresti esaminare entrambe le opzioni di ottimizzazione fornite dagli altri risponditori, nonché se alla fine dovrai servire la grafica del tuo gioco separatamente dallo stesso .apk.


Non ho problemi a ottenere la grafica dal server (o anche i file di espansione), ma come posso metterli in una cartella disegnabile in modo da poterli fare riferimento da R.drawable.x Dal momento che la maggior parte dei miei (molti molti) xmls fa riferimento a loro usando R .drawable
Snake

AFAIK, non puoi. Una soluzione alternativa consiste nel mantenere una tabella hash dei nomi dei file delle risorse collegati agli ID delle risorse e utilizzare AssetManager per acquisire i file in base a tali ID, ma potrebbe essere necessario rielaborare i file .xml se segui questa strada.
Sandalfoot,

4

Sono venuto su questo sito alla ricerca di una domanda simile e ci sono davvero alcune buone risorse indirizzate sia nelle risposte alla tua domanda che in altre domande.

Probabilmente dovresti dare un'occhiata all'animazione 2D: modelli 3D animati o sprite con frame di animazione? per alcuni dibattiti su diversi tipi di animazione. Mi ha aiutato a ottimizzare il mio gioco. Inoltre, non ci dici quale API stai utilizzando o quale motore utilizzi. Solo questo può fare la differenza: l' animazione PNG fotogramma per fotogramma Android

Oltre a ciò, tieni presente che se seguirai il percorso di compressione, ci possono essere differenze importanti tra le modalità di compressione. In particolare, ci sono alcune differenze tra i tipi di compressione e c'è un dibattito specializzato su quale sia il percorso più appropriato per i dispositivi mobili. Soprattutto se si tiene conto del fatto che anche per i dispositivi mobili, l'utilizzo della RAM e lo spreco di CPU per il caricamento sono fondamentali. Vedi: http://www.gamasutra.com/blogs/AlexandruVoica/20130419/190833/Why_efficiency_is_key_in_texture_compression_standards_for_mobile_graphics.php?print=1


Grazie Bennton, in realtà sono nuovo nello sviluppo del gioco. Ho sviluppato molte app basate su strumenti / produttività. Ma nessuno con i giochi. Quindi sto facendo il mio primo gioco e non sto usando un motore. Sto usando solo AnimationDrawables e le cose stanno andando alla grande. È solo la dimensione dell'apk che sta sfuggendo di mano
Snake

Bennton, l'ultimo link suggerito da te è particolarmente interessante. Mille grazie per averlo condiviso! Assicurati di dare un'occhiata all'ultimo dalla mia risposta, che tocca anche il problema della diversa compressione per diversi tipi di file. In realtà, sembrano esserci tipi di compressione che funzionano meglio con tipi di immagine già compressi come PNG, o meglio con tipi di immagine non compressi. Sperimentare per ogni caso è sempre il modo migliore per verificare ciò che funziona meglio per ogni situazione.
MAnd
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.