# [anitomata][] [![Version badge][]][version] ## Synopsis `anitomata` is a pure implementation of 2D sprite animation intended for use in gamedev. In this example, `anim` is an animation for an NPC celebrating a victory. The animation sequence plays the NPC's `idle` animation two times then the `jump` animation one time, and the entire sequence is looped indefinitely: ```haskell import Anitomata import qualified Data.Vector.Unboxed as U anim :: Anim anim = buildAnim AnimDurationDefault $ repeatAnim AnimRepeatForever $ repeatAnim (AnimRepeatCount 1) idle <> jump idle :: AnimBuilder idle = fromAnimSlice idleSlice jump :: AnimBuilder jump = fromAnimSlice jumpSlice idleSlice :: AnimSlice idleSlice = AnimSlice { animSliceDir = AnimDirBackward , animSliceFrameDurs = U.replicate 4 0.1 -- Each frame is 100ms , animSliceFrames = U.fromListN 4 [{- ... AnimFrame values ... -}] } jumpSlice :: AnimSlice jumpSlice = AnimSlice { animSliceDir = AnimDirForward -- Second frame is 500ms, rest are 100ms , animSliceFrameDurs = U.generate 8 $ \i -> if i == 1 then 0.5 else 0.1 , animSliceFrames = U.fromListN 8 [{- ... AnimFrame values ... -}] } ``` `AnimSlice` is the smallest building block of an animation. Slices are a minimal sequence of frames that capture a logical chunk of animation. Slices are converted to `AnimBuilder` values and then the builders can be combined using the `Semigroup` interface. Values of the core animation type - `Anim` - are created from builders. A game can play an animation by stepping it using `stepAnim` each simulation frame, passing the time elapsed since the last step: ```haskell stepAnim :: Double -> Anim -> SteppedAnim data SteppedAnim = SteppedAnim { steppedAnimStatus :: AnimStatus , steppedAnimValue :: Anim } ``` An animation can be rendered using `animFrame` in conjunction with a spritesheet that is managed separately by the game. `animFrame` provides the current frame of the animation: ```haskell animFrame :: Anim -> AnimFrame ``` Note that the types in the library are more general than what is shown above. For example, there is no requirement of using `Double` as a duration type, unboxed `Vector` as the vector type, etc. The animation building blocks can be defined manually, but this is tedious and error-prone. Instead, the base slices and builders are typically defined automatically by feeding a design file - e.g. output from Aseprite - into a code generator or parsing some translated representation of a design file. Packages providing this functionality may be found by visiting the project's [homepage](https://sr.ht/~jship/anitomata/) or by searching Hackage (all official packages of the `anitomata` project are named `anitomata-*`). For additional detail on the library, please see the [Haddocks][] and the [announcement post][]. [anitomata]: [Version badge]: [version]: [Haddocks]: [announcement post]: