Perita

Aseprite and HeapsAtlas

Recently, i have been trying to draw a very simple tileset for a grid-based game i started this year. I write the game in Haxe with Heaps, and draw the tiles in Aseprite. My first issue was how to use the tileset with Heaps’s Atlas class.

I draw each tile in a separate .aseprite file, mostly because i am going to animate some of them and animating the whole tileset is impractical, but this is not a problem because i can use Aseprite’s command-line interface to generate a single PNG file with all the individual tiles packed in:

aseprite --batch *.aseprite --sheet-pack --sheet tileset.png

It generates something like the following image.

Example of a tileset generated by Aseprite

For now, every tile is a static 16 × 16 pixel image, but even so Aseprite most likely will place the tiles on the PNG in a non-predictable position, meaning that i can not know in advance the X and Y coordinates of any tile in the PNG.

To help with that, Aseprite also writes out a JSON-formatted file that has the names, coordinates, and sizes of each tile in the PNG:

{ "frames": {
   "floor.aseprite": {
    "frame": { "x": 0, "y": 64, "w": 16, "h": 16 },
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": { "x": 0, "y": 0, "w": 16, "h": 16 },
    "sourceSize": { "w": 16, "h": 16 },
    "duration": 100
   },
   "floor-brokenA.aseprite": {
    "frame": { "x": 96, "y": 32, "w": 16, "h": 16 },
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": { "x": 0, "y": 0, "w": 16, "h": 16 },
    "sourceSize": { "w": 16, "h": 16 },
    "duration": 100
   },
   …
   "wallF.aseprite": {
    "frame": { "x": 64, "y": 32, "w": 16, "h": 16 },
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": { "x": 0, "y": 0, "w": 16, "h": 16 },
    "sourceSize": { "w": 16, "h": 16 },
    "duration": 100
   }
 },
 "meta": {
  "app": "http://www.aseprite.org/",
  "version": "1.2.21-x64",
  "image": "tileset.png",
  "format": "RGBA8888",
  "size": { "w": 112, "h": 96 },
  "scale": "1"
 }
}

Apparently, this format is a kind of de facto standard for spritesheets and Aseprite’s author is not sure where it came from, possibly from TexturePacker. Heaps’s Atlas, on the other hand, uses a text file format based on libGDX, also used by Spine, and can not directly read Aseprite’s JSON files.

I did not find any tool to convert from Aseprite’s JSON to libGDX’s atlas format, so i wrote one that serves my purposes. By default, it reads the file from its standard input because, without the --data parameter, Aseprite writes the JSON to its standard ouput, therefore i can create both the PNG and the .atlas files in a single line:

aseprite --batch *.aseprite --sheet-pack --sheet tileset.png | jsontoatlas tileset.atlas