Cómo comprimir la animación cuadro por cuadro del juego al mínimo en el disco

19

Estoy desarrollando un juego como Age of Empire (edificios en el mapa) y para cada edificio tengo una hoja de sprites para su animación. Estoy usando animación cuadro por cuadro para animar el edificio (de todos modos, no conozco ningún otro método). Me doy cuenta de que mi carpeta de recursos se está volviendo extremadamente grande debido a las imágenes que estoy poniendo en ella.

¿Cómo los juegos como CoC y Age of Empires mantienen su tamaño de apk por debajo de 50 Mg? ¿Me estoy perdiendo algo aquí cuando se trata del desarrollo del juego?

Gracias

EDITAR: más información sobre el problema que estoy enfrentando

Tengo MUCHAS animaciones de objetos dibujables. Elegí este camino porque era el más rápido y producía los resultados que quería. Básicamente, cada edificio es una animación dibujable en la que su archivo xml se refiere a 8 elementos dibujables (8 imágenes = 8 archivos). Todos ellos son PNG debido a la transparencia. Como tengo más de 200 imágenes, el tamaño del apk es de 120 MB (y todavía no he terminado de copiar la mitad de los archivos). Eso es lo rápido, tiene que haber una manera de resolverlo. Por favor, ayuda a un compañero desarrollador

Serpiente
fuente
Comprimir imágenes o separar el contenido del juego del apk puede ser lo que estás buscando.
János Turánszki
¿Te refieres a los archivos de expansión? El problema es que los archivos de expansión no tienen las carpetas extraíbles de densidad diferente. ¿Es esto lo que hacen los juegos? Estoy haciendo animación cuadro por cuadro (imagen completa del edificio). ¿O estoy totalmente en el camino equivocado
Serpiente
Por si acaso, traté de ser de ayuda y poner una respuesta relacionada con el ahorro de espacio para sus imágenes. Sin embargo, su pregunta es confusa: no está claro si realmente desea conocer técnicas como "¿cómo los juegos como CoC y Age of Empires mantienen su tamaño de apk por debajo de 50 Mg?" o si desea verificar si hay menos formas de animación que requieren menos espacio en el disco (como sugiere su título). Por favor aclare, para que pueda eliminar mi respuesta si ese es el caso y también para que pueda obtener respuestas más precisas.
2015
@MY edité mi respuesta para reflexionar más sobre el problema
Snake
2
Para Age of Empires, es probable que sea una combinación de baja resolución (IIRC fue diseñado para 640x480) e imágenes indexadas (no RGB completo).
user253751

Respuestas:

24

No está claro por su pregunta si realmente desea conocer las técnicas que permiten que los juegos ahorren espacio en el disco, incluso cuando tiene grandes cantidades de archivos de imágenes / recursos pesados ​​(eso es lo que está en el cuerpo de la pregunta), o si solo quiere saber si hay menos formas de animación para sus edificios que requieren mucho espacio en el disco (eso es lo que implica el título de su pregunta).

Entonces, pondré esta respuesta aquí tratando de ser de ayuda en relación con el ahorro de espacio cuando tienes muchas imágenes. Si solo está interesado en conocer las técnicas de animación que podrían permitirle ahorrar espacio en el disco, avíseme para que elimine la respuesta.


Dicho esto, en una situación similar, dos soluciones que he visto (y usado una vez) en términos de ahorro de espacio en el disco fueron:

1) para concatenar imágenes individuales dentro de una misma imagen. A veces puede ser de ayuda. Entonces, en lugar de guardar 4 archivos separados para cada uno de los siguientes cuadrados de colores, los guardo uno al lado del otro dentro de la misma imagen (y solo los dividiré a través del código del juego):

ingrese la descripción de la imagen aquí

En este ejemplo, guardar cada uno en 4 archivos PNG diferentes equivale a 1255 bytes, mientras que el archivo único con todos concatenados es de 451 bytes. Por supuesto, cuánto podría ayudar depende de cada caso y debe probar para ver si eso puede ser de ayuda según sus imágenes.

2) para comprimir la carpeta de recursos. Esto a menudo puede ser muy útil para ahorrar espacio en disco. Luego, cuando el juego se está ejecutando, puedes descomprimir o extraer la imagen deseada del archivo comprimido, dependiendo del formato de compresión que uses. Vea esta respuesta anterior que se convirtió en una wiki de este sitio: /gamedev//a/37649/72423

Pero también tenga en cuenta que cada tipo de compresión puede ser más o menos ventajoso dependiendo del tipo de archivo de imagen que utilice : evite la doble compresión de los recursos

Para más detalles sobre la compresión: ¿ Estado del arte en compresión de imágenes?


Por último, también podría estar interesado en pensar qué tipos de imagen usar para cada situación: ¿Qué formato de imagen es más eficiente en la memoria: PNG, JPEG o GIF?

Mand
fuente
Gracias por la información. Es extraño que haya podido reducir el tamaño del archivo a la mitad al poner las cosas en un archivo. Pensé que al final del día, es el mismo recuento de píxeles y espacio utilizado. Edité mi pregunta para una mejor respuesta
Snake
@Snake Entonces, según la edición que hiciste, creo que mi respuesta puede ser útil. Concatenar imágenes + comprimir puede reducir el tamaño de su carpeta en una gran cantidad. Ambas técnicas se usan regularmente en algunos tipos de juegos. Sobre la concatenación, eso siempre es un truco sorprendente. Pruébelo usted mismo: coloque las imágenes de una secuencia de una animación suya lado a lado y compare el tamaño final con la suma de las imágenes individuales. Entonces puede ver si eso ayuda en su caso. En cuanto a la compresión, para PNG tiende a ser menos efectiva, pero aún así vale la pena el esfuerzo de cortar el tamaño de su carpeta final
MAnd
Sin embargo, haga una observación: la concatenación a veces no vale o incluso aumenta un poco el tamaño final. Pero a menudo puede ofrecer una reducción deseable. Todo depende de sus imágenes
MAnd
Recuerdo haber probado ambas técnicas y la reducción fue inferior al 10%. Definitivamente sé que la compresión no importa con PNG, pero intentaré la concatenación. Es por eso que pregunté cómo lo hacen otros juegos porque obviamente tienen muchos más gráficos que los míos
Snake
No deberías poder comprimir una carpeta llena de imágenes. Las imágenes ya deberían estar comprimidas y no deberían tener muchas secuencias repetibles. Si lo hicieran, esa capa adicional de compresión sería parte del códec de imagen ...
corsiKa
9

Te propondría que pruebes TexturePacker

  • simplemente puede arrastrar y soltar todas sus imágenes y empacarlas
  • puede aplicar una compresión diferente, por ejemplo, usar PNG indexados que consumen mucha menos memoria, hasta un 70% menos en comparación con un archivo PNG estándar
  • puede crear un archivo de datos que contenga el nombre + posición de cada uno de sus edificios
  • la versión gratuita ya puede ser suficiente para crear las hojas de sprites para usted

¿Utiliza un marco de desarrollo de juegos como AndEngine, Cocos2d-x o LibGdx? => Ninguno

¿Necesita cargar todas sus imágenes al mismo tiempo? Parece que te encontrarás con problemas masivos de RAM en los dispositivos de destino.


Actualización: Snake me envió algunas imágenes. Como prometí, no los haré públicos aquí, así que yo mismo creé algo de arte para demostrar cómo reducir el uso de memoria.

En la imagen original, solo una parte de la imagen se estaba moviendo. Coloqué un pájaro en una casa para demostrar esto:

ingrese la descripción de la imagen aquí

Básicamente, empaquetar la animación completa en una hoja es una gran pérdida de memoria. Debe dividir las partes estáticas y móviles:

Estático:

ingrese la descripción de la imagen aquí

Anim01:

ingrese la descripción de la imagen aquí

Anim02:

ingrese la descripción de la imagen aquí

Mantenga la posición original del pájaro en las imágenes . Por eso hay tanto espacio vacío arriba. Necesita esto para alinear la animación.

Ahora arrastre las imágenes en TexturePacker y seleccione los siguientes parámetros

  • Formato de datos: hash JSON (o XML si lo prefiere)
  • TrimMode: Trim (esto crea rectángulos)
  • Formato de píxel: 8 bits INDEXADO: para crear PNG de 8 bits (aproximadamente un 70% menos de memoria)
  • Permitir rotación: falso
  • Ingrese un nombre de archivo para los datos

TexturePacker empacando las imágenes

El resultado es que ahora obtienes 2 archivos: la hoja de sprites y un archivo de descripción 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}
},

Las partes importantes son frame y spriteSourceSize .

El marco le brinda la ubicación del sprite original en la hoja de sprite.

spriteSourceSize le ofrece el desplazamiento para dibujar la imagen, las partes de la imagen que quedan fuera debido al recorte:

Una simple rutina de dibujo de pseudocódigo se ve así:

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)
}

Es posible que deba ajustar el cálculo de desplazamiento según el punto de pivote / origen en su sistema de gráficos. La rutina anterior supone un sistema de coordenadas cuyo origen está en la parte superior izquierda.

Luego simplemente dibuja la casa en 2 pases:

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

No tiene que preocuparse por los desplazamientos, ya que las imágenes ya están alineadas.

Andreas Löw
fuente
+1 para la observación sobre el uso de RAM, que otras personas ignoran
Dan Hulme
@ Andrea lo comprobaré. Gracias. No te rías de mí pero no estoy usando un motor. Se realiza principalmente con animación y dibujos y funciona como un encanto. No cargo todas las imágenes en la memoria, de lo contrario se bloqueará. Simplemente carga las imágenes necesarias para mostrar en este momento ... ¿crees que la sugerencia anterior funcionaría con el SDK de Android estándar?
Serpiente
1
Sí lo hará TexturePacker tiene 2 modos para recortar sprites: rectángulos y polígonos. Si usa imágenes isométricas, puede obtener una gran ventaja de las mallas poligonales en términos de empaque. La pregunta es si sería capaz de dibujar triángulos con textura, o rectángulos con una máscara. Si este no es el caso, aún puede usar los rectángulos. Puede enviarme algunas de sus imágenes si desea usar Dropbox y enviar un enlace a -> soporte en codeandweb. com. No los compartiré, solo estoy interesado en ver qué podemos hacer para mejorar el embalaje.
Andreas Löw
@ AndreasLöw Lo siento mucho, no recibí notificación de tu comentario. Acabo de verlo. Apreciaré mucho la ayuda. Te enviaré algo y tal vez puedas arrojar luz sobre lo que debería. ..kinda quedar atrapado con algo en lo que tengo poca experiencia y tal vez puedas arrojar luz. Me pondré en contacto con usted pronto
Snake
7

Aquí hay algunos punteros que puedes usar

  1. Intenta asegurarte de que todas tus imágenes de fondo y no transparentes no estén en formato PNG
  2. Intente que todas las animaciones puedan reproducirse en bucle, es decir, si la animación es 1,2,3,4,5,6, intente que sea como 1,2,3,4,3,2,1 donde estos números son el número de fotograma de la animación, Esto ayuda mucho
  3. Si muchas imágenes son iguales y solo el color difiere (generalmente botones de interfaz de usuario, m animaciones de partículas, monedas de juego), entonces intente tomar una imagen blanca y cambiar su color dinámicamente
  4. Intente hacer su .apk solo con aquellas imágenes que son extremadamente importantes y luego cargue todo desde un servidor y guárdelo en la memoria del teléfono

Espero que estos consejos ayuden

PD : Solo doy una idea general, ya que no conozco el contenido exacto del juego y mis disculpas si estos consejos no son útiles.

Kumar Saurabh
fuente
También puede: 1) comprimir todas sus imágenes 2) usar mosaicos tan a menudo como sea posible 3) concatenar imágenes juntas en una imagen más grande y usar eso como el mapa ultravioleta para texturizar
Anthony Raimondo
Esas son buenas sugerencias. Gracias. Creo que el punto más importante es 4. Sin embargo, si ese es el caso, ¿cómo puedo colocarlos en las diferentes carpetas dibujables y hacer referencia a ellos como R.drawable.image1? Ahí es donde estoy confundido
Snake
4

Muchos juegos no mantienen sus recursos gráficos en el .apk; solo incluyen los "elementos básicos", como los gráficos de la interfaz de usuario y el código del juego, y descargan el resto de los recursos una vez que se ha instalado el juego. Esto es especialmente cierto para los juegos que usan diferentes recursos gráficos dependiendo de la resolución de su pantalla para evitar que .apk tenga que contener recursos de baja y alta resolución.

Debes mirar tanto las opciones de optimización proporcionadas por los otros respondedores, como si finalmente tendrás que servir los gráficos de tu juego por separado del .apk mismo.

Sandalfoot
fuente
No tengo problemas para obtener los gráficos del servidor (o incluso los archivos de expansión), pero ¿cómo los coloco en una carpeta dibujable para que pueda hacer referencia a ellos mediante R.drawable.x? .drawable
Snake
AFAIK, no puedes. Una solución alternativa es mantener una tabla hash de nombres de archivos de recursos vinculados a ID de recursos, y usar el AssetManager para tomar los archivos basados ​​en esas ID, pero es posible que tenga que volver a trabajar sus archivos .xml si sigue esta ruta.
Sandalfoot
4

Vine a este sitio en busca de una pregunta similar y, de hecho, hay algunos buenos recursos apuntados tanto en las respuestas a su pregunta como en otras preguntas.

Probablemente deberías echar un vistazo a la animación 2D: ¿modelos 3D animados o sprites con cuadros de animación? para un debate sobre diferentes tipos de animación. Me ayudó a optimizar mi juego. Además, no nos dice qué API está utilizando o qué motor utiliza. Eso solo puede hacer una gran diferencia: animación PNG cuadro por cuadro de Android

Además de eso, tenga en cuenta que si va a ir a la ruta de compresión, puede haber diferencias importantes entre cómo se comprime. Específicamente, existen bastantes diferencias entre los tipos de compresión y existe un debate especializado sobre cuál es la ruta más apropiada para los dispositivos móviles. Especialmente si tiene en cuenta que para dispositivos móviles, el uso de RAM y el desperdicio de CPU para la carga también son primordiales. Ver: http://www.gamasutra.com/blogs/AlexandruVoica/20130419/190833/Why_efficiency_is_key_in_texture_compression_standards_for_mobile_graphics.php?print=1

Bennton
fuente
Gracias Bennton, en realidad soy nuevo en el desarrollo de juegos. Desarrollé muchas aplicaciones basadas en herramientas / productividad. Pero ninguno con juegos. Así que estoy haciendo mi primer juego y no estoy usando un motor. Estoy usando solo AnimationDrawables y las cosas funcionan muy bien. Es solo que el tamaño del apk se está yendo de las manos
Snake
Bennton, el último enlace sugerido por ti es particularmente interesante. Muchas gracias por compartir eso! Asegúrese de echar un vistazo al último de mi respuesta, que también toca el tema de la compresión diferente para diferentes tipos de archivos. En realidad, parece haber tipos de compresión que funcionan mejor con tipos de imágenes ya comprimidas como PNG, o mejor con tipos de imágenes sin comprimir. Experimentar para cada caso es siempre la mejor manera de verificar qué funciona mejor para cada situación.
2015