A command-line tool for packing spritesheets and a library for unpacking them
The above is a spritesheet generated by this tool for Snake. Snake is a real game that uses this tool for managing sprites. Proof that this tool is practical.
This tool can be used to pack images into a spritesheet and produce an atlas describing the spritesheet. The job of the tool is described in a YAML based config file. You can see an example of a config file to get an idea of what can be specified. Once you have a spritesheet and an atlas, you can use the unpacker to load the spritesheet and the atlas into you application.
- A tool for packing images from a folder into a spritesheet
- The images are identified in the atlas as the file names of the images without the extensions
- A separation can be specified between the sprites
- A white pixel can be specified. This is a single pixel or area of pixels on the spritesheet that are white
- A library for reading the atlas
- A really nice C++ interface
- Loads both the atlas and the image
See ROAD_MAP.md for a list of planned features.
- Download the repo
- Install homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- Install yaml-cpp
brew install yaml-cpp
- Open the Xcode project and build it (⌘ + B)
- To check that the tool was installed correctly
- Go back to the terminal and type
packer
- Go back to the terminal and type
- To check that the library was installed correctly
- Open Finder
- Press (⌘ + ⇧ + G) and type
/usr/local/
- In
lib
you should findlibUnpacker.dylib
and ininclude/Unpacker
you should findtypes.hpp
image.hpp
unpacker.hpp
You can look in image.hpp and unpacker.hpp for the relevent headers.
Here is a complete example for loading a spritesheet called my images.png
and an atlas called my images.atlas
.
#include <Unpacker/unpacker.hpp>
int main(int, const char **) {
Spritesheet myImages;
try {
//Spritesheet is move only so this is a move-assign
myImages = makeSpritesheet("my images.atlas", "my images.png");
} catch (AtlasReadError &e) {
std::cout << e.what() << '\n';
return 1;
}
if (myImages.hasWhitepixel()) {
const VecPx whitepx = myImages.getWhitepixel();
std::cout << "Whitepixel is (" << whitepx.x << ", " << whitepx.y << ")\n";
} else {
//getWhitepixel will return Spritesheet::NO_WHITEPIXEL if there isn't one
std::cout << "There is no whitepixel\n";
}
try {
const RectPx mySprite = myImages.getSprite("my sprite");
std::cout << "Position of \"my sprite\" is (" << mySprite.x << ", " << mySprite.y << ")\n";
std::cout << "Size of \"my sprite\" is (" << mySprite.w << ", " << mySprite.h << ")\n";
} catch (SpriteNotFound &e) {
std::cout << "There is no sprite called \"my sprite\"\n";
}
const Image &image = myImages.getImage();
std::cout << "Size is (" << image.width() << ", " << image.height() << ")\n";
//this is usually width * bytes per pixel
std::cout << "Pitch is " << image.pitch() << '\n';
//this is usually 4
std::cout << "Bytes per pixel is " << static_cast<CoordPx>(image.format()) << '\n';
//data points to the top left pixel of the image (0, 0).
//Add pitch to the pointer to get (0, 1)
std::cout << "Pointer to pixel data is " << image.data() << '\n';
return 0;
}
Check out CONTRIBUTING.md to see what you can do. Then see if there's an item in the ROAD_MAP.md that you can complete.