Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The Animate property returns whether the IAnimationChainAnimatable is performing animation (cycling through AnimationFrames). This property does not reflect whether the IAnimationChainAnimatable has a CurrentChain. If it does not, this value may still be true indicating that the IAnimationChainAnimatable will animate once a CurrentChain is set.
The IAnimationChainAnimatable interface only requires that the Animate property returns a value - it doesn't require a setter; however, common IAnimationChainAnimatable-implementing classes like Sprite and SpriteFrame provide a setter. If the specific implementing class allows, setting this value to false will prevent animation from occurring, and will stop any existing animation. For example, the following code can be used to toggle whether a Sprite is animating:
The AnimationSpeed property controls the speed at which an Animation is playing. The default value for AnimationSpeed is 1, which means the amount of time that each AnimationFrame displays is equal to its FrameLength property.
Increasing this value above 1 will make animations play faster.
Setting this value between 0 and 1 will make animations play slower.
Setting this value to 0 will make animations stop (similar to setting Animate to false).
Setting this value to a negative number will make animations play in reverse.
A Sprite's AnimationSpeed can be changed in the FlatRedBall Editor in the Variables tab.
The CurrentChainName property gets and sets the name of the AnimationChain currently played by the owner of the property. Setting this property is the most common way to change between different animations at runtime, and it can also be set in Glue to control the animation displayed by an IAnimationChainAnimatable (such as a Sprite).
The CurrentChainName property is a string, so code can assign animation chains in a way that is not tied to the underlying content. The following code shows how to set the animation of an object according to pressed keys.
Changing CurrentChainName does a number of things:
Sets the displayed animation to the animation matching the set name.
Restarts the animation from the very beginning.
Immediately updates the IAnimationChainAnimatable's textures and texture coordinates to reflect the first frame in the animation.
Note that these actions are only taken if the CurrentChainName *changes. *Assigning CurrentChainName to the same value performs no logic, so it can be safely set every frame without restarting the animation from the beginning. To restart the animation from the beginning, set CurrentFrameIndex to 0.
Keep in mind that some properties will not change in response to CurrentChainName being set:
JustCycled
JustChangedFrame
IAnimationChainAnimatable-implementing objects should automatically update their displayed frame according to time. It is possible that a frame may last less than one frame of game time - if the game is running slowly or if the frame is of very short duration. Sprites, for example, will skip frames if the timing advances far enough. Not all frames are guaranteed to play.
The list of AnimationChains referenced by this instance.
The IAnimationChainAnimatable interface defines methods and properties for objects which can be animated by AnimationChains (which are stored in a AnimationChainList). Examples of classes which implement the IAnimationChainAnimatable interface include the Sprite and SpriteFrame.
The following shows various ways to set a Sprite's current AnimationChain. The reason there are so many examples is because Sprites and AnimationChains can be created many different ways. What follows are examples which cover the most common scenarios. For information on how to create AnimationChains, see the Creating AnimationChains wiki Entry.
Normally the Sprite's AnimationChains can be set in Glue; however, to set them manually in code:
IAnimationChainAnimatables like Sprites can also have their AnimationChains set after they are created:
If the Sprite has had its AnimationChains value set, either in code or in Glue, then you can simply select which animation to play:
Calling SetAnimationChain or setting the CurrentChainName needs to only be called when the AnimationChain is changing or being set. It does not need to be called every frame to keep the animation going.
See FlatRedBall.Graphics.Animation.IAnimationChainAnimatable.CurrentFrameIndex.
When an IAnimationChainAnimatable changes the AnimationFrame that it is displaying, its JustChangedFrame property is true for that frame.
Walk North
Walk South
Walk West
Walk East
Attack (likely also has directions, but not included to save space)
Die
Since these behaviors share many similarities they should be put in a base class. However, setting AnimationChains becomes a problem. If each type of object (human peasant, orc peasant, ogre) references different AnimationChains the the code cannot fully be standardized if references are used to set the current animation. That is, if methods are called when a state change occurs, there will need to be virtual methods that can be called by the base class to set the current AnimationChain to the appropriate reference. While this will work, it is not very convenient or readable - for a new user to understand the behavior he will have to traverse multiple files and follow the execution path up and down the inheritance tree. The alternative is to recognize early on that this similarity between objects exists and design for this standard behavior both in content and in code. In other words, if the behaviors previously listed in bullet points are recognized early on before content creation begins, then this pattern can be used when all AnimationChainLists are created. Once the textures for all animations are created, the .achx file created in the AnimationEditor can use the same names for their AnimationChains. Therefore, the humanPeasant.achx file and the orc.achx file will both reference different textures, and can even have a different number of textures or frame times, but they should include a set of same-named AnimationChains. What the AnimationChain holds internally is insignificant from the programmer's point of view, just the name. Once these AnimationChains are created, the code simply loads the appropriate .achx file in the derived class' constructor. The base class can set the current AnimationChains using the Name property. As an example, the following code would work for all objects which have walking and dying animations:
So long as all objects which inherit from the class containing this code have AnimationChains named WalkNorth, WalkSouth, WalkWest, WalkEast, Attack, and Die, this code will handle all AnimationChain setting with no regard to the actual contents of the AnimationChain being set.
The previous section discusses how to set AnimationChains on an IAnimationChainAnimatable. Of course, for the CurrentChainName property to work, the IAnimationChainAnimatable must have a reference to an AnimationChain with a matching name. Another way of looking at it is that if you are going to toggle between AnimationChains, then the object that is going to have its AnimationChain set must have references to multiple AnimationChains. How can this be done? The most common and data-driven approach is to load a .achx file created in the AnimationEditor or some other tool. The .achx file can contain multiple AnimationChains so this greatly simplifies the process. However, it's also possible to set up your IAnimationChainAnimatable to use multiple AnimationChains if you are creating the AnimationChains by hand. To do this, you can simply add each AnimationChain to the AnimationChains property. For example, assuming that animationChain1, animationChain2, and animationChain3 are valid AnimationChains:
Did this article leave any questions unanswered? Post any question in our forums for a rapid response.
Objects which implement the IAnimationChainAnimatable interface hold an AnimationChainList reference internally. This AnimationChainList is referenced by IAnimationChainAnimatables to standardize the setting of AnimationChains according to state or behavior. The game Warcraft 2 will be used as an example of how the internal storage of AnimationChains can standardize code and simplify development. Warcraft 2 has numerous characters which share similar behavior. All ground units have the following behavior:
The UseAnimationRelativePosition property controls whether the IAnimationChainAnimatable sets its relative values when the current AnimationChain changes its displayed frame. This value is true by default for the Sprite object. If you are applying relative values to an object such as a Sprite and do not want the AnimationChain to interfere, then set this value to false in code:
The JustCycled property is a property which is usually false, but will be set to true when an animation either finishes or cycles. This can be used to perform logic whenever an AnimationChain ends. By default, objects (such as Sprites) which play animations will automatically loop. When this happens, the object begins displaying the first frame in the animation. When this occurs, the JustCycled property will be true. Keep in mind that when this value is set to true, the object will display the first frame of animation that frame. It is possible to prevent this by performing logic (such as destroying the object) when this is true.
The JustCycled property reports whether an object that is displaying an AnimationChain has just reached the end of an animation and has cycled to the beginning. You can perform logic in response this being set to true. The following code assumes MySprite is a valid Sprite. The if statement will trigger when the Sprite completes.
JustCycled can be used to play an animation once, then stop the animation when it's cycled. For this example we'll use an animating Sprite called MySprite:
If you are changing which animation an object is showing when JustCycled is set to true, keep in mind that JustCycled will stay true for the entire frame, regardless of whether you change chains in code. For example:
When JustCycled is true and if the displayed object has its Cycling set to true, then CurrentFrameIndex will be 0 (unless an animation is playing backwards). In a typical setup (in an unmodified FlatRedBall template), the FlatRedBall Engine will perform its logic before custom game logic is executed every frame. This means that if JustCycled is true, custom code will have an opportunity to react to the cycle before the animation visually starts over. For example, consider this code:
The CurrentFrameIndex gets and sets the current frame that the IAnimationChainAnimatable is displaying. As animation plays this property will automatically increment and cycle. This value will always be between 0 and the count of the current AnimationChain minus one (inclusive).
Assuming that mSprite is a valid Sprite that has a current AnimationChain the following code will manually cycle the Frames:
Restarting the animation can be done either by setting the CurrentFrameIndex to 0 or by setting the CurrentChainName so long as the CurrentChainName differs from the set value. That means if your current animation is "DesiredAnimation" and you want to restart the animation you can either:
OR