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:
{-# 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:
-- 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
:
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!