SpriterMC is a Starling implementation for importing skeletal (and non-skeletal) animations generated with Spriter, complete with a familiar API mimicking Starling MovieClip. Features include SpriterMC generation from an existing TextureAtlas or individual assets (a TextureAtlas is generated from assets dynamicall), bone support, ability to create multiple instances with low overhead, Framerate-independant and adjustable playback speed and playback direction, swap entire texture sets at runtime, and more. It currently supports all features of the Spriter file format (version a4.1), with future support planned for any subsequent changes to the SCML format.
First, create an animation using Spriter. You can use skeletal or non-skeletal animation. You can download Spriter at http://www.brashmonkey.com/spriter.htm. There are great tutorials (and more to come) on using Spriter found on the Spriter tutorial page.
You will never create a new SpriterMC. Instead, the SpriterMCFactory will create one for you and return it. You then need to add it to the stage and to a Juggler, just like any other Starling MovieClip. There are two methods to create a SpriterMC:
SpriterMCFactory.createSpriterMC($name:String, $scmlPath:String, $textureAtlas:TextureAtlas = null, $onReadyCallback:Function = null, $returnInstance:Boolean = true):SpriterMC – defines and then returns a new SpriterMC for the first time. The only required parameters are $name and $scmlPath. $name must be a unique String used to identify this type of SpriterMC incase you want to generate more instances of it later, and ScmlPath is the path to the SCML file. SpriterMCFactory.generateInstance($name:String, $onReadyCallback:Function = null, $altTexturePack:String = “”):SpriterMC – returns a new instance (a duplicate) of an existing SpriterMC, using the $name as reference. You can optionally pass it an alternate TexturePack from an existing SpriterMC as long as they're compatible (advanced use only).
Ideally, for performance and memory considerations, you should also pass an already-created TextureAtlas containing the assets for your character as the $textureAtlas parameter. This same TextureAtlas can be used for multiple SCML files as long as all the required assets are present!. This is the most optimal situation possible. However, you can also let SpriterMC load the individual assets listed in the SCML file and it will create a TextureAtlass for you. Be aware that this potentially uses more memory.
var monster1:SpriterMC = SpriterMCFactory.createSpriterMC("monster", "xml/monster.scml"); monster1.play(); //Note: SpriterMC's will not actually start playing or show up on stage until SpriterMC.SPRITER_MC_READY is broadcast //Add each SpriterMC to a Juggler, just like a regular Starling MovieClip myJuggler.add(monster1);
var monster1:SpriterMC = SpriterMCFactory.createSpriterMC("monster", "xml/monster.scml", _textureAtlas); monster1.playbackSpeed = 1.5; //Demonstrating playbackSpeed, which is like Scale, 1 == 100%. You can also set negative values to play backward monster1.play(); //Note: SpriterMC's will not actually start playing or show up on stage until SpriterMC.SPRITER_MC_READY is broadcast //Add each SpriterMC to a Juggler, just like a regular Starling MovieClip myJuggler.add(monster1);
//create monster and call spriterReadyHandler when it is ready var monster1:SpriterMC = SpriterMCFactory.createSpriterMC("monster", "xml/monster.scml", _textureAtlas, spriterReadyHandler); monster1.play(); //generate a new instance of "monster", and call spriterReadyHandler when it is ready var monster2:SpriterMC = SpriterMCFactory.generateInstance("monster", spriterReadyHandler); monster2.setAnimationByName("Posture"); //set the animation to "Posture" instead of "Idle" monster2.currentFrame = 4; //start it off at frame 4 monster2.play(); //Add each SpriterMC to a Juggler, just like a regular Starling MovieClip myJuggler.add(monster1); myJuggler.add(monster2);
Most methods of SpriterMC are very similar to that of the Starling MovieClip, with a few exceptions. Below is a list of functions and a brief description:
While you don't need to worry about the internals, it might be helpful to understand the components of a SpriterMC. Each SpriterMC has two pieces of data it relies on: an ScmlData object and a TexturePack. The ScmlData is parsed from the loaded SCML file provided when the SpriterMC is first created, and contains all relavant animation info. A TexturePack is the set of textures generated from a TextureAtlas, which is either provided at creation (by far the most recommended method) or generated dynamically from individual assets. When the SpriterMCFactory defines a new SpriterMC, it is really just creating a ScmlData and a TexturePack and giving them each the provided name. It then creates a SpriterMC by passing these two objects to a new SpriterMC instance. When the SpriterMCFactory generates a new instance of an existing SpriterMC, it's really just grabbing the previously created ScmlData and TextureAtlas by name, then creating a new SpriterMC instance with them and returning it. So in essence, the SpriterMCFactory is storing all created ScmlData and TexturePack objects and only creating actual SpriterMC's on request. This design allows multiple SpriterMC's to share the same ScmlDatas and TexturePacks, keeping memory low and allowing only one draw call per TextureAtlas used!
A SpriterMC is not considered “ready” until all required assets are fully loaded and parsed. SpriterMC dispatches “SpriterMC.SPRITER_MC_READY” when it is complete.
Each SpriterMC contains various Animation objects it is capable of playing and switching between (switch between them by using setAnimationByName or setAnimationByID). SpriterMC and Animation both implement Starling's IAnimatable interface. Any calls to SpriterMC such as play, stop, etc, are delegated to the current Animation it is playing. Inside of Animation's advanceTime method, the number of milliseconds passed is retrieved, the current keyframe is calculated (depending on if it's playing forward or backward), and all data values are manually interpolated based on the playhead time between the current frame and next frame. When Considering Bones, their data (position, rotation, scale, etc) is only relative to their immediate parent. This is true of any image that is a child of a Bone as well, therefore the entire Bone chain must be traversed and each Transform concatenated to calculate the final values. (Thanks to GrimFang for the tip to abondon Matrices…SCML does not use Matrix math).