packages feed

anitomata-aseprite-0.1.0.0: README.md

# [anitomata-aseprite][]

[![Version badge][]][version]

## Synopsis

`anitomata-aseprite` provides a preprocessor - `aseprite2haskell` - that
converts an Aseprite texture atlas JSON file into `anitomata` Haskell code.

## Usage

Imagine this fragment of directory structure for a game:

```
my-game
├── my-game.cabal
└── library
    └── MyGame
        └── Codegen
            ├── Atlas.hs
            └── Atlas.json
```

`Atlas.json` contains the JSON texture atlas exported using the Aseprite CLI.
`Atlas.hs` contains just this line:

```haskell
{-# OPTIONS_GHC -F -pgmF aseprite2haskell #-}
```

This makes GHC invoke the `aseprite2haskell` preprocessor so that the
`MyGame.Codegen.Atlas` module will contain `AnimSlice` and `AnimBuilder` values
for all tags in the Aseprite texture atlas JSON. You will have one `AnimSlice`
per each Aseprite-tagged sequence of frames and one `AnimBuilder` wrapping that
`AnimSlice`. The generated code will look something like this:

```haskell
-- Auto-generated - do not manually modify!
{-# LANGUAGE ImportQualifiedPost #-}
module Atlas where

import Prelude
import Anitomata
import Data.Vector.Unboxed qualified as U

owlet_walk :: AnimBuilder
owlet_walk = fromAnimSlice owlet_walk_slice

owlet_walk_slice :: AnimSlice
owlet_walk_slice =
  AnimSlice
    { animSliceDir = AnimDirForward
    , animSliceFrameDurs = U.slice 0 6 durations
    , animSliceFrames = U.slice 0 6 frames
    }

owlet_run :: AnimBuilder
owlet_run = fromAnimSlice owlet_run_slice

owlet_run_slice :: AnimSlice
owlet_run_slice =
  AnimSlice
    { animSliceDir = AnimDirForward
    , animSliceFrameDurs = U.slice 6 6 durations
    , animSliceFrames = U.slice 6 6 frames
    }

-- ... more builders and slices ...

frames :: U.Vector AnimFrame
frames = -- ... vector of frames ...

durations :: U.Vector Double
durations = -- ... vector of durations ...
```

Be sure to include your texture atlas JSON file in your package description's
`extra-source-files`. Note that if you rewrite your JSON file via re-exporting
from the Aseprite CLI (or just change the JSON file in general), you might need
to clean your game project for the updates to be picked up in your game.

## Texture atlas format

Currently, the preprocessor is not very flexible in regards to the JSON format
exported out of Aseprite. You **must** export your texture atlas using these
flags at a minimum:

```
path/to/aseprite \
  --batch \
  --list-tags \
  --filename-format '{title}|{tag}|{frame}' \
  --tagname-format '{title}|{tag}' \
  --sheet-pack \
  --format 'json-array' \
  --sheet "path/to/atlas.png" \
  --data "path/to/Atlas.json" \
  path/to/spritesheets/*.aseprite
```

`--list-tags`, `--filename-format`, `--tagname-format`, and `--format` are
critical. If you do not use these flags as shown above, `aseprite2haskell` will
not be able to parse your JSON.

Also note that you **must** tag every frame in your Aseprite file. The tags map
to `AnimSlice` values in `anitomata`, so be sure to tag every minimal sequence
of frames comprising a logical chunk of animation (e.g. the frames for a "walk"
animation could have a tag named "walk"). This restriction may be lifted in the
future, but for now, all frames must be tagged. Tagging in Aseprite is also how
you control the `AnimDirection` of your `AnimSlice` values and the repeat count
of your `AnimBuilder` values.

Here's an example of a spritesheet appropriately tagged for use with
`aseprite2haskell`:

![Aseprite tags](./images/aseprite-tags.png)

## Goals

Defining animation slices is tedious and error prone. The main goal of
`anitomata-aseprite` is to automate away that pain. Currently, only the
preprocessor is provided. This is great for rapidly integrating animations into
a game, but some games may require dynamic loading of animations rather than
using generated code. `anitomata-aseprite` has a secondary goal of providing an
`aeson` parser to read animations in at runtime, but this code hasn't been
written yet. If you need this functionality, please consider contributing!

[anitomata-aseprite]: <https://git.sr.ht/~jship/anitomata>
[Version badge]: <https://img.shields.io/hackage/v/anitomata-aseprite?color=brightgreen&label=version&logo=haskell>
[version]: <https://hackage.haskell.org/package/anitomata-aseprite>