I’m happy to announce the initial release of anitomata
, a pure implementation of 2D sprite animation intended for use in gamedev.
An intro and additional resources are available here.
I’m happy to announce the initial release of anitomata
, a pure implementation of 2D sprite animation intended for use in gamedev.
An intro and additional resources are available here.
This looks sick! Congrats on the release. Can’t wait to use it in April for the next Ludum Dare
Ludum Dare in Haskell? this is the future I’m here for ^^
I don’t agree with the library structure, consider a different approach:
A 2D animation is sequence of durations, each bound to some frame data. We can assume that animation starts at 0, the offset of each frame is unique and that all durations have a common divisor (e.g. 1/60 in a 60fps animation).
Frames can be referenced as a multiple of the divisor, therefore the entire library is reduceable to
data Animation =
Animation
{ duration :: Time
, divisor :: Time
, frames :: IntMap Frame -- ^ indexed by divisor multiples
}
build :: Config -> [RawFrame] -> Either Error Animation
-- | The time delta is enough knowledge to find the current divisor multiple,
-- then IntMap.lookupLE finds the frame.
frame
:: Time -- ^ animation started at
-> Time -- ^ current time
-> Animation
-> Frame
There are no moving parts in this approach and the functions can be customized however needed.
Admittedly this definition is small enough to not even require a library, anyone could just handroll this.
This misses — e.g. — looped animations.
Congrats on release jship!
A looped animation assumes that relevant current time is mod time_delta duration
, whereas a non-looping one checks time_delta < duration
and defaults to the last frame. Everything else is identical otherwise.
I think you’re missing the Semigroup
instance for Animation
, which is a big selling point of the library!
Please feel free to package up your own implementation - anitomata
is not at all meant to be the only method for sprite animation in Haskell.
Its internal approach of building animations as lazy sequences of strict, reusable chunks is a point in the design space I find satisfying, and wrapping it up using a minimal Semigroup
-based DSL has been pleasant in my gamedev experiments so far.
That looks great @jship , thanks for sharing! I’m presently using varying for animation, have you considered using it?
For example, how to change the anitomata duration dynamically to implement the system presented in this Giving Personality to Procedural Animations using Math video? For what it’s worth, here is my implementation with varying: AnimationFractal.secondOrder.
Thank you - I hadn’t explored varying
. I think applying it to the animation duration is a very interesting idea. It looks like varying
's Spline
in particular could simplify adding more sophisticated duration overrides. The overrides in anitomata
's initial release are very simple, but in the future I’d love to make things like cubic ease-in/ease-out available too.