Then I moved to keeping frames as individual images, this allowed me to clip off the null space of images, to conserve space, but it required a separate 'data' file to keep the offsets and entries of images, also storing these tons of images in folders was a pain.
So, I finally decided to make an actual animated format, specifically for games.
![](http://www.edigames.com/anitools.jpg)
The format allows you to store costumes, actions, directions and frames all in a single file. PNG compression is used and the actual image files are stored within the .ediani file.
I've written tools for authoring/editing and viewing the .ediani format, and I've written a simple C++ library for using them in games.
I'll be using this format in my next game, and I'd like to hear what people think, because I'm going to be licensing (for very cheap) the authoring tools as well as the C++ library.
Here is a general list of features:
- Final animation is a single file, no external dependancies.
- Graphics API agnostic, uses no windows specific functionality.
- Stores Costumes, Actions, Directions and Frames; a single character in a single file.
- Editor clips transparent space and saves and applies offsets automatically, reduces required memory.
- action-level support for anchoring, place the 0,0 point where you want.
- frame-level support for flipping, and color modulation.
- no image duplication, a single unique table of files is maintained.
- Editor has features such as copy and paste, as well as group operations.
- Uses internal PNG compression for lossless, compressed images with 8 bits of transparency.
- Uses time based animation, with built-in options for looping and 'next action' linking.
- Editor support for importing files, or existing 'page table' based animations.
For now, here is the viewer and a few edianis I created,
the format is free to use and I'll be posting the specification eventually,
and the viewer is also free to use and distribute,
the ediani's bellow are free for personal use only (mainly to demonstrate).
Animation Viewer.exe
Ivy from Malathedra
Morning from Morning's Wrath (battle and peace animations included)
Ardus from Morning's Wrath
here is the interface for the C++ library for using ediani files.
(for show of simplicity)
#pragma once#include #include #include class AniLibrary;class AniController;class AniSheet;class AniFrame;class AniImage;class AniCommand;class AniCell;#define ANI_LIBRARY_NEW_IMAGE 0x100#define ANI_LIBRARY_DELETE_IMAGE 0x101#define ANI_CONTROLLER_CHANGE 0x200#define ANI_CONTROLLER_COMMAND 0x201#define ANI_COMMAND_RUN_FORWARD 0x1#define ANI_COMMAND_RUN_REVERSE 0x2#define ANI_COMMAND_JUMP_START 0x3#define ANI_COMMAND_JUMP_END 0x4#define ANI_COMMAND_CHANGE_COSTUME 0x5#define ANI_COMMAND_CHANGE_ACTION 0x6typedef void(AniControllerFunction)(AniController*,int,void*);typedef void*(AniLibraryFunction)(AniLibrary*,int,void*);struct AniNewImageInfo{ int size; void* data;};class AniLibrary{private: void* context; AniLibraryFunction* libraryFunction; std::vector images; std::map> sheets; static std::vector<unsigned char> pngBuffer; bool opened; std::string file;public: AniLibrary(void* context,AniLibraryFunction* libraryFunction,int reserve=1048576); ~AniLibrary(void); bool open(const std::string& file); void close(void); std::string getFile(void); void* getContext(void); bool getOpened(void); AniSheet* getSheet(const std::string& costume,const std::string& action);};class AniController{private: void* context; AniControllerFunction* controllerFunction; float frameIndex; //current frame index AniLibrary* library; //current library std::string costume; //current costume std::string action; //current action int directionIndex; //current direction index bool changed; //signal to resolve sheet and cell and reset state AniSheet* sheet; //current sheet AniFrame* frame; //current frame AniCell* cell; //current cellpublic: AniController(void* context,AniControllerFunction* controllerFunction); ~AniController(void); void* getContext(void); AniLibrary* getLibrary(void); void setLibrary(AniLibrary* library); std::string getCostume(void); void setCostume(const std::string& costume); std::string getAction(void); void setAction(const std::string& action); void setDirection(int direction); int getDirection(void); void advance(float time); AniCell* getCell(void);};class AniSheet{friend class AniLibrary;friend class AniController;private: float fps; int offsetX; int offsetY; bool loop; std::string nextAction; std::vector> frames; AniSheet(void);public: ~AniSheet(void);};class AniFrame{friend class AniController;friend class AniLibrary;private: AniImage* image; bool flipX; bool flipY; unsigned int color; AniFrame(void);public: AniImage* getImage(void); bool getFlipX(void); bool getFlipY(void); unsigned int getColor(void);};class AniImage{friend class AniCell;friend class AniLibrary;friend class AniController;private: int offsetX; int offsetY; int width; int height; void* image;public: AniImage(void); int getOffsetX(void); int getOffsetY(void); int getWidth(void); int getHeight(void); void* getImage(void);};class AniCell{public: int width; int height; int offsetX; int offsetY; bool flipX; bool flipY; void* image;};
any comments/questions/bugs can be posted as replies here, I'd love to hear what you all think :)