The SpriteRenderComponent used to display the static sprite in the last tutorial also has the ability to display frames of animation. By assigning a resource to the loadFromImage property, the SpriteRenderComponent will in fact create a SpriteSheetComponent with a single frame of animation. In combination the SpriteSheetComponent and SpriteRenderComponent have the ability to reference a number of individual frames contained in a single image, like a filmstrip.
The first step in implementing an animation is to remove the code that instructs the SpriteSheetComponent to load an image.
var Render:SpriteRenderComponent = new SpriteRenderComponent(); Render.positionReference = new PropertyReference("@Spatial.position"); entity.addComponent( Render, "Render" );
The SpriteRenderComponent does not really have any concept of animation. It can be instructed which frame of animation to display at any given time, but it does not have the ability to cycle through these frames itself. For that we need to introduce a new component: the AnimationController. The purpose of the AnimationController is to update the state of an animation (namely to move to the next frame of the animation after a specified period of time) and to tell a SpriteRenderComponent which frame from which SpriteSheetComponent to display.
var Animation:AnimationController = new AnimationController(); Animation.spriteSheetReference = new PropertyReference("@Render.spriteSheet"); Animation.currentFrameReference = new PropertyReference("@Render.spriteIndex"); Animation.defaultAnimation = "IdleRight";
So as we mentioned earlier the SpriteSheetComponent references an image, and knows how to break that image down into its individual frames. Here we create a SpriteSheetComponent that references one such film strip image.
var IdleRightSpriteSheet:SpriteSheetComponent = new SpriteSheetComponent(); IdleRightSpriteSheet.imageFilename = "../media/idleright.png";
The individual frames in a film strip image can be aligned in a number of different ways. For this demo we are using a series of frames that are aligned horizontally. You can see how this works in the image below.
The CellCountDivider class provides a way for us to inform the SpriteSheetComponent how the images are aligned. Here we are telling it that there are 6 images along the x axis.
var divider:CellCountDivider = new CellCountDivider(); divider.xCount = 6; IdleRightSpriteSheet.divider = divider;
The final step in implementing animation is to create add an AnimationControllerInfo object to the internal database of animations maintained by the AnimationController. Each AnimationControllerInfo references a SpriteSheetComponent and maintains some additional details like the frame rate, whether the animation is looped etc. Here we create a AnimationControllerInfo object that references the SpriteSheetComponent created above.
var IdleRightAnimation:AnimationControllerInfo = new AnimationControllerInfo(); IdleRightAnimation.frameRate = 12; IdleRightAnimation.loop = true; IdleRightAnimation.spriteSheet = IdleRightSpriteSheet;
This AnimationControllerInfo is then referenced by the AnimationController, and the AnimationController is added to the entity.
Animation.animations["IdleRight"] = IdleRightAnimation; entity.addComponent(Animation, "Animation");
Animations in PushButton require combining quite a few classes together, but once you understand the process it is a reasonably straight forward process to animate an entity.