http://www.codeandweb.com/texturepacker/tutorials#cocos2d-x
Why and how to pack your textures for iOS/Android
Introduction
When I developed Don’t Feed the Trolls on X360 (using XNA), I did not optimize the textures files of the game : the game was very simple, the final hardware (X360) is very fast, so it was not necessary. I arranged the sprites so that I could get their coordinates in-game very easily. Every “troll” sprite for instance is the same size, so most of them are filled with transparent pixels. A lot of space is wasted. Have a look at the sprite sheet for the characters that I use on X360.
The characters texture on X360 is 2048×1024. I could easily have it into a 1024×1024 but it was a lot easier if I could have all the sprites of the same kind in a row (for example, all the bear heads are on the top row). I also made a few other sprites sheets for UI, birds, tutorial for instance.
For the first draft of my Android port, I first concentrated on the gameplay and integrate this sprite sheet as is. Of course, I quickly realized I had to spend some time to optimize as obviously, constraints on mobile and X360 are different.
Why packing your textures?
Why is proper texture packing important for games, especially on mobile? Packed textures use less pixels, and from this simple fact, the game is greatly improved in many ways:
Memory
Less pixels takes less memory. Mobile have big memory constraints and saving memory from the ressource is great. Texture ressources are often the biggest ressources.
Loading
There are less files to open, and less pixels to read, this will therefore be faster to load.
Runtime performance
When packing your textures in atlases, more sprites will share the same texture. In runtime, the GPU will then have less textures changes to make and this will therefore speed up your game. This will improve performance if you draw the sprites using the same texture in a row.
It will allow you to reduce your texture sizes. Some Android devices are performing very slowly with 2048 pixels-wide textures.
Game size
The downloadable package size will be smaller too. This is great, especially for people using 3G or with limited bandwidth that won’t download big games.
How to pack?
I first thought of packing my sprites manually but quickly searched for a tool to assist me in that tedious task. There are a few tools available to automatically pack your sprites, and I am currently usingTexturePacker, and I’m very happy with it (please note that I got a free copy of TexturePacker from the developer). It’s easy to use and has a lot of functionnalities, such as:
- Auto-refreshes the packed texture in the tool when I add images to my folders
- Export in one click
- Support cocos2d and therefore cocos2d-x which I am using (and many more formats).
- Removes useless transparent pixels around sprites
- Efficient packing
All the features are listed here.
Here is a sample of a packed sprite sheet for the Android version of Don’t Feed the Trolls made with TexturePacker:
Instead of 2048×1024, this is just 1024×1024, and most importantly, I have all my characters, the UI elements, and some background elements in the same, smallest texture!
Generic code
I did some code so that resource loading does not have to deal with packs or single sprites. That way, I can send a version without packs to the artist and he can test his ressource live. In cocos2d-x, this is very easy. You first need to load your pack(s) with CCSpriteFrameCache ::addSpriteFramesWithFile( file_name ). And then, read the ressource from the file if it’s not found in the packs. I did it like this:
CCSprite *GetSprite(const char *file_name ) { CCSprite *psprite = new CCSprite( ); psprite->autorelease(); // Search in the cache, first CCSpriteFrameCache *sfc = CCSpriteFrameCache::sharedSpriteFrameCache(); CCSpriteFrame *psf = sfc->spriteFrameByName( file_name ); if( psf != NULL ) { psprite->initWithSpriteFrame( psf ); return psprite; } CCLog("WARNING : %s not in a PACK!", file_name ); psprite->initWithFile( file_name ); return psprite; }
Conclusion
Packing your textures is very important on mobile platform, but hopefully, great tools make that task very easy and straighforward.