Using sprite sheets in Cocos2d and Tiled (part 1)

In today’s post I’m going to enter in more detail in a very useful topic for game development: Sprite Sheets. I introduced this topic in two of my previous post, but did not enter in detail. I received some feedback pointing out that there is some interest on sprite sheets and how to use them in conjunction with Texture Packer and Cocos2d. In addition, I’m also going to explain how to use sprite sheets as your source library for creating maps on Tiled. This will probably be a large post, so I’m going to split it into two parts.

Super Mario World Sprite Sheet

Super Mario World Sprite Sheet

What is a Sprite Sheet and why we should use them in all our games

A sprite sheet or texture atlas (for a 2D game) is a large image or texture that contains smaller images or textures that correspond to all the different sprites that our game uses. A picture is worth a thousand words, so you can see an example below.

Vegeta Sprite Sheet

Vegeta Sprite Sheet

As you can see, we have a large image composed of smaller images of Vegeta in the different poses that the character can adopt along the game. Obviously, you could have each of these small images in a single file and it would not imply a significant difference in terms of software design and coding. However, the performance would decrease drastically. This is the main reason (and probably the only one) for using sprite sheets in your games: improve performance. The reason for that is out of scope. For more information about why sprite sheets improve performance in games take a look at this wikipedia article.

Sprite sheets with Texture Packer

Ok, now that we know what are sprite sheets and why we should use them let’s start to work with them. First, we need to create all the assets that our game will use. Use your favorite asset creation tools for that purpose. I like to work with Adobe Illustrator and Photoshop, so I used this binomial to create all the assets for New Sokoban. On the image below you can see the sprite PNG files used in the current version of New Sokoban.

Sprite PNG files for New Sokoban

Sprite PNG files for New Sokoban

Now, we can launch Texture Packer and see what we could do with it. It is possible to create the sprite sheet manually using some Photoshop-like tool. However, there are some tricky issues related to sprite sheet creation that are difficult to deal with manually. In general, it is better, in terms of performance, that the sprite sheet had a size that is a power of two. Texture Packer takes care of that. Moreover, every platform and 2D engine has its own issues related to memory and texture management. Texture Packer offers support for cocos2d and iOS devices, so if our game uses cocos2d and/or if it is intended to be published on an iOS platform, it is almost mandatory to use a tool like Texture Packer.

Texture Packer User Interface

Texture Packer User Interface

As you can see on the image above, Texture Packer UI is very simple. You have a central area where you see the final sprite sheet, the list of properties for the sprite sheet on the left and the individual sprites on the right.

For a detailed description of how to use every single feature of the tool, refer to the official documentation on the Download section of the official Texture Packer website. However, I would like to highlight a few of them:

  • Autosize. Check this feature to make Texture Packer calculate the optimal sprite sheet size. It will take unto account all the tricky issues I talked about earlier.
  • Max. with / Max height. Take this binomial into account because some devices have texture size limitations, specially earlier ones.
  • Allow free sizes. Uncheck this if you want to let Texture Packer Autosize feature work freely.
  • Border / Shape padding. Adds some padding at the border of the sprite sheet and in-between the sprites respectively. Adding padding makes the sprite sheet more visually understandable for humans and could avoid artifacts caused by miss-selecting sprite edge pixels by the 2D engine or the hardware. However, it is quite tricky because sometimes you will need to do just the opposite to avoid this artifacts. It depends on each situation.
  • Extrude. This is a very important one if you use cocos2d as your 2D engine. It seems that cocos2d has a little issue when rendering sprite sheets and in some situations mixes the edge pixels of similar adjacent sprites. Using an extrude value of 1 solves the problem.
  • Data format. As you already now, I use cocos2d engine for New Sokoban development. So, selecting the “cocos2d” option for this feature is the best :)

When we have set all needed configuration options we can go to File/Publish. This command will generate to files: a .plist file with the sprite sheet metadata that we will use to load the sprites on our game using cocos2d and the .png file with the sprite sheet itself.

Sprite sheet used in New Sokoban for the board tile sprites

Sprite sheet used in New Sokoban for the board tile sprites

Use our sprite sheet in our cocos2d game

Now, that we have the sprite sheet and the corresponding metadata file, we can load it into our cocos2d game. Doing so is terribly easy.

First, add the two Texture Packer files (.plist and .png) to your Xcode project.

Then, we need to load the sprite sheet metadata and the sprite sheet itself to cocos2d cache:

[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:
    @"NewSokoban.plist"];

Next, we create a Batch Node object that acts as the sprite sheet and add it into our cocos2d scene:

CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode
    batchNodeWithFile:@"NewSokoban.png"];
[self addChild:spriteSheet];

Finally, we need to create the actual sprite object and we should add it to the sprite sheet object for better performance. The name of the sprite frame is the original name that the PNG file had. This information is automatically included into the .plist file by Texture Packer. Remember that you don’t need to add the individual PNG files to your project.

CCSprite *sprite = [CCSprite spriteWithSpriteFrameName:@"NewSokoban_02.png"];
sprite.position = ccp(240, 160);
[spriteSheet addChild:sprite];

Conclusion

And that’s it! We have created our sprite sheet using Texture Packer and added it into our Cocos2d game. On the next part of this article, I’m going to explain how to use sprite sheets as sprite libraries to create maps in Tiled. See this post for an introduction :) And here you have a mental note to conclude:

Mental note: always use sprite sheets in your games. It’s mandatory. It is very easy to work with them using tools like Texture Packer and a 2D engine like Cocos2D. And the benefits in terms of performance are huge.

One thought on “Using sprite sheets in Cocos2d and Tiled (part 1)

  1. Pingback: Using sprite sheets in Cocos2d and Tiled (part 1) | Indie Dev Stories « OmNomRobot

Leave a Reply