Comment compresser l'animation image par image du jeu au minimum sur le disque

19

Je développe un jeu comme Age of empire (bâtiments sur la carte) et pour chaque bâtiment, j'ai une feuille de sprite pour son animation. J'utilise l'animation image par image pour animer le bâtiment (je ne connais pas d'autre méthode de toute façon). Je remarque que mon dossier de ressources devient extrêmement volumineux en raison des images que je mets dedans.

Comment des jeux comme CoC et Age of Empires gardent-ils leur taille apk inférieure à 50 mg? Suis-je en train de manquer quelque chose en ce qui concerne le développement de jeux

Je vous remercie

EDIT: Plus d'informations sur le problème auquel je suis confronté

J'ai BEAUCOUP d'animations d'objets dessinables. J'ai choisi cette voie parce que c'était la plus rapide et qu'elle donnait les résultats que je voulais. Fondamentalement, chaque bâtiment est une animation dessinable dans laquelle son fichier xml fait référence à 8 dessins (8 images = 8 fichiers). Tous sont au format PNG en raison de la transparence. Puisque j'ai plus de 200 images, la taille de l'apk est de 120 Mo (et je n'ai pas encore fini de copier la moitié des fichiers). C'est ce qui invite, il doit y avoir un moyen de le résoudre. Veuillez aider un collègue développeur

Serpent
la source
La compression d'images ou la séparation du contenu du jeu de l'apk pourrait être ce que vous recherchez.
János Turánszki
Vous voulez dire des fichiers d'extension? Le problème que les fichiers d'extension n'ont pas les différents dossiers dessinables de densité. C'est ce que font les jeux? Je fais une animation image par image (image complète du bâtiment). Ou suis-je totalement sur la mauvaise voie
Snake
Juste au cas où, j'ai essayé d'être utile et de mettre une réponse liée à l'économie d'espace pour vos images. Cependant, votre question est confuse: il n'est pas clair si vous voulez vraiment connaître des techniques comme celles liées à "comment des jeux comme CoC et Age of Empires gardent-ils leur taille apk inférieure à 50 mg?" ou si vous souhaitez simplement vérifier s'il existe moins de moyens d'animation gourmands en espace disque (comme le suggère votre titre). Veuillez clarifier, afin que je puisse supprimer ma réponse si tel est le cas et aussi pour obtenir des réponses plus précises.
2015
@MAnd J'ai modifié ma réponse pour réfléchir davantage au problème
Snake
2
Pour Age of Empires, c'est probablement une combinaison de basse résolution (IIRC il a été conçu pour 640x480) et d'images indexées (pas full RGB).
user253751

Réponses:

24

Votre question ne permet pas de savoir si vous voulez vraiment connaître les techniques qui permettent aux jeux d'économiser de l'espace disque même lorsque vous avez de grandes quantités de fichiers images / ressources lourds (c'est ce qui est dans le corps de la question), ou si vous voulez juste savoir si il y a moins de façons gourmandes en espace disque de faire de l'animation pour vos bâtiments (c'est ce que sous-entend le titre de votre question).

Donc, je vais mettre cette réponse ici en essayant d'être utile pour économiser de l'espace lorsque vous avez beaucoup d'images. Si vous souhaitez uniquement connaître les techniques d'animation qui pourraient vous permettre d'économiser de l'espace disque, veuillez me le faire savoir, je pourrais supprimer la réponse.


Cela dit, dans une situation similaire, deux solutions que j'ai vues (et utilisées une fois) en termes d'économie d'espace sur le disque étaient:

1) pour concaténer des images individuelles au sein d'une même image. Parfois, cela peut être utile. Donc, au lieu d'enregistrer 4 fichiers distincts pour chacun des carrés de couleur suivants, je les enregistre côte à côte dans la même image (et je ne les divise que via le code du jeu):

entrez la description de l'image ici

Dans cet exemple, l'enregistrement de chacun dans 4 fichiers PNG différents équivaut à 1255 octets, tandis que le fichier unique avec tous les éléments concaténés fait 451 octets. Bien sûr, combien cela pourrait aider au cas par cas et vous devriez tester pour voir si cela peut vous être utile en fonction de vos images.

2) pour compresser le dossier des ressources. Cela peut souvent être très utile pour économiser de l'espace disque. Ensuite, lorsque le jeu est en cours, vous décompressez ou tirez l'image souhaitée du fichier compressé - selon le format de compression que vous utilisez. Voir cette réponse passée qui est devenue un wiki de ce site: /gamedev//a/37649/72423

Mais gardez également à l'esprit que chaque type de compression peut être plus ou moins avantageux selon le type de fichier image que vous utilisez : Évitez la double compression des ressources

Pour plus de détails sur la compression: état de l'art en compression d'image?


Enfin, vous pourriez également être intéressé à réfléchir aux types d'images à utiliser pour chaque situation: Quel format d'image est plus économe en mémoire: PNG, JPEG ou GIF?

MAnd
la source
Merci pour l'information. Il est étrange que vous ayez pu réduire la taille du fichier de moitié en mettant les choses dans un seul fichier. J'ai pensé qu'en fin de compte, c'est le même nombre de pixels et l'espace utilisé. J'ai édité ma question pour une meilleure réponse
Snake
@Snake Donc, d'après l'édition que vous avez faite, je pense que ma réponse peut en effet être utile. La concaténation d'images + la compression peuvent réduire considérablement la taille de votre dossier. Les deux techniques sont régulièrement utilisées dans certains types de jeux. Concernant la concaténation, c'est toujours une astuce surprenante. Essayez-le vous-même: mettez côte à côte les images d'une séquence d'une animation et comparez la taille finale avec la somme des images individuelles. Ensuite, vous pouvez voir si cela vous aide dans votre cas. Quant à la compression, pour PNGs il a tendance à être moins efficace, mais vaut la peine de la taille de la coupe de votre dossier final
Mand
@Snake une observation, cependant: la concaténation ne vaut parfois pas ou augmente même légèrement la taille finale. Mais souvent, il peut fournir une réduction souhaitable. Tout dépend de vos images
Mand
Je me souviens d'avoir essayé les deux techniques et la réduction était inférieure à 10%. Je sais que la compression n'a pas d'importance avec PNG mais je vais essayer la concaténation. C'est pourquoi j'ai demandé comment les autres jeux le font, car ils ont évidemment beaucoup plus de graphiques que le mien
Snake
Vous ne devriez pas pouvoir compresser un dossier plein d'images. Les images doivent déjà être compressées et ne doivent pas avoir beaucoup de séquences reproductibles. S'ils le faisaient, cette couche supplémentaire de compression ferait partie du codec d'image ...
corsiKa
9

Je vous propose d'essayer TexturePacker

  • vous pouvez simplement faire glisser et déposer toutes vos images et les emballer
  • vous pouvez appliquer une compression différente - par exemple, utiliser des fichiers PNG indexés qui consomment beaucoup moins de mémoire - jusqu'à 70% de moins par rapport à un fichier PNG standard
  • vous pouvez créer un fichier de données contenant le nom + la position de chacun de vos bâtiments
  • la version gratuite pourrait déjà suffire pour créer les feuilles de sprite pour vous

Utilisez-vous un framework de développement de jeux comme AndEngine, Cocos2d-x ou LibGdx? => Aucun

Avez-vous besoin de toutes vos images chargées en même temps? Il semble que vous rencontrerez d'énormes problèmes de RAM sur les appareils cibles.


Mise à jour: Snake m'a envoyé des images. Comme promis, ils ne seront pas rendus publics ici, j'ai donc créé moi-même de l'art pour montrer comment réduire l'utilisation de la mémoire.

Dans l'image d'origine, seule une partie de l'image se déplaçait. J'ai placé un oiseau sur une maison pour le démontrer:

entrez la description de l'image ici

Fondamentalement, l'animation complète dans une feuille est un gros gaspillage de mémoire. Vous devez diviser les parties statiques et mobiles:

Statique:

entrez la description de l'image ici

Anim01:

entrez la description de l'image ici

Anim02:

entrez la description de l'image ici

Gardez la position d'origine de l'oiseau dans les images . C'est pourquoi il y a tellement d'espace vide au-dessus. Vous en avez besoin pour aligner l'animation.

Faites maintenant glisser les images sur TexturePacker et sélectionnez les paramètres suivants

  • Format de données: hachage JSON (ou XML si vous préférez)
  • TrimMode: Trim (cela crée des rectangles)
  • Format de pixel: INDEXÉ 8 bits - pour créer des fichiers PNG 8 bits (environ 70% de mémoire en moins)
  • Autoriser la rotation: faux
  • Entrez un nom de fichier pour les données

TexturePacker emballant les images

Le résultat est que vous obtenez maintenant 2 fichiers: la feuille de sprite et un fichier de description 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}
},

Les parties importantes sont frame et spriteSourceSize .

Le cadre vous donne l'emplacement du sprite d'origine dans la feuille de sprite.

spriteSourceSize vous donne le décalage pour dessiner l'image - les parties de l'image qui sont laissées de côté à cause du découpage:

Une routine de dessin de pseudo-code simple ressemble à ceci:

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

Vous devrez peut-être ajuster le calcul du décalage en fonction du point de pivot / origine dans votre système graphique. La routine ci-dessus suppose un système de coordonnées dont l'origine est en haut à gauche.

Puis dessinez simplement la maison en 2 passes:

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

Vous n'avez pas à vous soucier des décalages - car les images sont déjà alignées.

Andreas Löw
la source
+1 pour l'observation sur l'utilisation de la RAM, que d'autres ignorent
Dan Hulme
@Andreas, je vais vérifier cela. Je vous remercie. Ne te moque pas de moi mais je n'utilise pas de moteur. Cela se fait principalement avec de l'animation et des dessins et cela fonctionne comme un charme. Je ne charge pas toutes les images dans la mémoire, sinon cela plantera. Il charge juste les images requises pour l'affichage pour le moment .. pensez-vous que la suggestion ci-dessus fonctionnerait avec le SDK Android standard?
Snake
1
Oui, il sera. TexturePacker dispose de 2 modes de découpage des sprites: les rectangles et les polygones. Si vous utilisez des images isométriques, vous pourriez obtenir un gros avantage des maillages polygonaux en termes d'emballage. La question est de savoir si vous pourriez dessiner des triangles texturés - ou des rectangles avec un masque. Si ce n'est pas le cas, vous pouvez toujours utiliser les rectangles. Vous pouvez m'envoyer certaines de vos images si vous souhaitez utiliser dropbox et envoyer un lien vers -> support sur codeandweb. com. Je ne les partagerai pas - je suis simplement intéressé de voir ce que nous pouvons faire pour améliorer l'emballage.
Andreas Löw
@ AndreasLöw Je suis vraiment désolé, je n'ai pas reçu de notification de votre commentaire. Je l'ai juste vu. J'apprécierai beaucoup l'aide. Je vais vous envoyer quelque chose et peut-être pourriez-vous nous éclairer sur ce que je devrais faire. ..kinda se coincer avec quelque chose que j'ai peu d'expérience et peut-être que vous pouvez faire la lumière. Je vous contacterai bientôt
Snake
7

Voici quelques pointeurs que vous pouvez utiliser

  1. Essayez de vous assurer que toutes vos images d'arrière-plan et non transparentes ne sont pas au format PNG
  2. Essayez d'avoir toutes les animations en boucle, c.-à-d. Si l'animation est 1, 2, 3, 4, 5, 6 essayez de le faire comme 1, 2, 3, 4, 3, 2, où ces nombres sont le numéro d'image de l'animation, ça aide beaucoup
  3. si de nombreuses images sont identiques et que seule la couleur diffère (généralement les boutons de l'interface utilisateur, les animations de particules m, les pièces de jeu), essayez de prendre une image blanche et de changer sa couleur dynamiquement
  4. Essayez de créer votre .apk avec uniquement les images qui sont extrêmement importantes, puis chargez tout à partir d'un serveur et conservez la mémoire du téléphone

J'espère que ces pointeurs vous aideront

PS Je ne donne qu'une idée généralisée car je ne connais pas le contenu exact de votre jeu et vos excuses si ces pointeurs ne sont pas utiles

Kumar Saurabh
la source
Vous pouvez également: 1) compresser toutes vos images 2) utiliser des tuiles aussi souvent que possible 3) concaténer des images ensemble dans une image plus grande et l'utiliser comme carte uv pour la texturation
Anthony Raimondo
Ce sont d'excellentes suggestions. Je vous remercie. Je pense que le point le plus important est 4. Cependant, si c'est le cas, comment puis-je les mettre dans les différents dossiers dessinables et les référencer comme R.drawable.image1? C'est là que je suis confus
Snake
4

De nombreux jeux ne conservent pas leurs ressources graphiques dans le .apk; ils n'incluent que les "bases" comme les graphiques de l'interface utilisateur et le code du jeu et téléchargent le reste des ressources une fois le jeu installé. Cela est particulièrement vrai pour les jeux qui utilisent différentes ressources graphiques en fonction de la résolution de votre écran pour éviter que le .apk contienne à la fois des ressources basse et haute résolution.

Vous devriez regarder à la fois les options d'optimisation fournies par les autres répondeurs, ainsi que si vous devrez finalement servir les graphiques de votre jeu séparément du .apk lui-même.

Sandalfoot
la source
Je n'ai aucun problème à obtenir les graphiques du serveur (ou même des fichiers d'extension), mais comment les mettre dans un dossier dessinable afin de pouvoir les référencer par R.drawable.x Étant donné que la plupart de mes (beaucoup de) xml les référencent à l'aide de R .drawable
Snake
AFAIK, tu ne peux pas. Une solution de contournement consiste à conserver une table de hachage des noms de fichiers de ressources liés aux ID de ressources et à utiliser AssetManager pour récupérer les fichiers en fonction de ces ID, mais vous devrez peut-être retravailler vos fichiers .xml si vous suivez cette route.
Sandalfoot
4

Je suis venu sur ce site à la recherche d'une question similaire et il y a en effet quelques bonnes ressources pointées à la fois dans les réponses à votre question et dans d'autres questions.

Vous devriez probablement jeter un œil à l'animation 2D: des modèles 3D animés ou des sprites avec des cadres d'animation? pour un débat sur différents types d'animation. Cela m'a aidé à optimiser mon jeu. De plus, vous ne nous dites pas quelle API vous utilisez ni quel moteur vous utilisez. Cela seul peut faire toute la différence: animation PNG image par image Android

En plus de cela, gardez à l'esprit que si vous suivez la voie de compression, il peut y avoir des différences importantes entre la façon dont vous compressez. Plus précisément, il existe quelques différences entre les types de compression et il existe un débat spécialisé sur la voie la plus appropriée pour les appareils mobiles. Surtout si vous tenez compte du fait que pour les mobiles, l'utilisation de la RAM et les pertes de CPU pour le chargement sont également primordiales. Voir: http://www.gamasutra.com/blogs/AlexandruVoica/20130419/190833/Why_efficiency_is_key_in_texture_compression_standards_for_mobile_graphics.php?print=1

Bennton
la source
Merci Bennton, je suis en fait nouveau dans le développement de jeux. J'ai développé de nombreuses applications basées sur les outils / la productivité. Mais aucun avec des jeux. Je fais donc mon premier match et je n'utilise pas de moteur. J'utilise juste AnimationDrawables et les choses fonctionnent très bien. C'est juste la taille de l'apk qui devient incontrôlable
Snake
Bennton, le dernier lien que vous avez suggéré est particulièrement intéressant. Merci beaucoup d'avoir partagé ça! Assurez-vous de jeter un œil à la dernière de ma réponse, qui touche également le problème de la compression différente pour différents types de fichiers. En fait, il semble y avoir des types de compression qui fonctionnent mieux avec des types d'image déjà compressés comme PNG, ou mieux avec des types d'image non compressés. L'expérimentation pour chaque cas est toujours la meilleure façon de vérifier ce qui fonctionne le mieux pour chaque situation.
2015