OmegaAnimationList

Introduction

OmegaAnimationList provides the following new functionality in Omega:

It also introduces a new TAdvancedAnimationSprite class to use these animations with. These are the features:

Please do look at the sourcecode of included example to roughly see what is possible. Play around with it!

Concepts

TOmegaAnimationList contains a collection of TOmegaAnimation instances. The TOmegaAnimation instances are the actual animations what this component is about.

TOmegaAnimation contains an animation in the form of a collection of TOmegaAnimationFrame instances. Each TOmegaAnimation has a name, so that inside each animation you can jump to another animation by name.

TOmegaAnimationFrame contains the properties the make up one animationframe of animation. Because you can specify a duration with each animationframe, they can take as long as you want. You can also specify a name with each frame so that you can jump back or loop to earlier frames by name.

TOmegaAnimationPlayer is a seperate class that keeps track of where you are in an animation. With it's Progress() method you can walk through an animation for a given time period and it will populate an object you pass to it with the proper values. Currently it only supports TAdvancedSpriteAnimation and will most probably support TOmegaBitmapFont in the future too.

TAdvancedSpriteAnimation is a sprite based on the TOmegaAnimationList functionality. You can assign to it more than one TOmegaAnimationPlayer instances to enable you to actually 'layer' several animations together.

All collections are based on the standard Delphi TOwnedCollection and TCollectionItem classes. Therefore they contain the standard Add, Insert, Delete, Count etc. methods and properties. Additionally each item contains a Name property and each collection contains a Find method which can search it's items for an item with the given name. These common properties and methods will not be described below as they are quite standard on most Delphi classes.

Loading and saving files

The TOmegaAnimationCollection class contains LoadFromFile' and 'SaveToFile' methods, they function like you would expect. It will save and load this type of file:

AnimList Files Files (*.oal)

TOmegaAnimationList

This is the component you can place on your form. It resembles the TOmegaSpriteList a lot as it does not contain any property editors or other things like that. All animations need to be added at runtime.

Properties

Property Description
OmegaImageList: TOmegaImageList Published. References the TOmegaImageList instance you will use for all animations inside this component. Notice that, since any name references in the animations will be replaced by their indexes at runtime, you can easily point this to another imagelist to have, for example, 'themable' animations! (think about it a little bit... yes... that's it!)
Animations: TOmegaAnimationCollection Public. Via this property you can access the TOmegaAnimation collection that is hosted by this component

TOmegaAnimationCollection

This is the actual collection of TOmegaAnimation instances. It contains all the usual properties and methods of a TCollection type plus some additional ones.

TOmegaAnimation

A TOmegaAnimation instance contains a frame-collection that make up the actual animation itself.

Properties

Property Description
Frames: TOmegaAnimationFrameCollection References the frame-collection that represents this animation.

Methods

Method Description
FindNext(var AFrame: TOmegaAnimationFrame; var AAnimation: TOmegaAnimation; var ALoopCount: Integer; var AReturnAnimation: TOmegaAnimation);

Find-next is used to find a frame that follows AFrame in the frame collection of this animation. It takes into account possible flow-control commands inside frames like GotoFrame, GotoAnimation etc. The passed variables will reference the actual next frame (AFrame), animation (AAnimation), keeps track of the loopcount for the Loop frame-command (ALoopCount) and will keep track of possible returns from and jumps into "Gosub" animations (more about that later).

Do not worry, this method is meant for TOmegaAnimationPlayer mainly :)

TOmegaAnimationFrameCollection

This is the actual collection of the individual TOmegaAnimationFrame instances that make up an animation. It contains quite a few methods to make creating animations at runtime easier to do.

Properties

Property Description
Animation: TOmegaAnimation Returns the animation this collection belongs to.

Methods

Please note that wherever an ImageListItemIndex, FrameIndex or AnimationIndex is used as a parameter of type Integer, there is also an overloaded version of the same method available where you can specify the name of that item instead of the index number.

Method Description

function AddPlay(
const Duration: Single;
const AName: String;
const AActions: TOmegaAnimationActions;
const TileIndex: Integer = 0;
const ImageListItemIndex: Integer = 0;
const AAnimX: Single = 0;
const AAnimY: Single = 0;
const AAlpha: Integer = 0;
const ARotation: Single = 0;
const AScaleX: Single = 0;
const AScaleY: Single = 0;
const ARed: Integer = 0;
const AGreen: Integer = 0;
const ABlue: Integer = 0;)
: TOmegaAnimationFrame;

Adds a new Play frame. Duration indicates the time it will take to progress from this frame to the next in seconds or in frames (depending on your design choice in your game), AName is the framename, AActions describes which actions will be performed in this frame (more about this later), TileIndex and ImageListItemIndex describe the image you want to display, AAnimX and AAnimY describe the relative position of the animation for this frame, ARed, AGreen and ABlue describe the colorization for this frame (0-255), AAlpha is the alpha of this frame (0.0-1.0), ARotation described the rotation of the image for this frame (in degrees, 0-360) and AScaleX and AScaleY describe the scale of the image for this frame.

The AActions parameter indicate which parameters mean something for ths frame. All parameters that are not needed can be left out (or just use -1 to recognize them easily). It has to be a set of these commands:
aaImage: The image parameters will be used
aaPosition: The position parameters (AnimX and AnimY) will be used
aaColor: The color parameters (ARed, AGreen, ABlue) will be used
aaAlpha: The AAlpha parameter will be used
aaRotate: The ARotation parameter will be used
aaScale: The scale parameters (AScaleX, AScaleY) will be used
Only an action that is present in two Play frames after each other, taking flowcontrol-commands in mind, will be interpolated. So, if you have a frame of Duration 4.00 and Alpha 0, and after that a frame with Alpha 255, the animation will fade in from 0 to 255 during 4 seconds only if these two frames have aaAlpha in their AActions property/parameter!

function AddStop: TOmegaAnimationFrame; Adds a new Stop frame. When playing an animation normally, this will stop the animation until a new animation has been started. When playing an animation by the 'GosubAnimation()' command (see TOmegaAnimationPlayer) this will return to the original animation that was present when the first GosubAnimation() was called.
function AddDie: TOmegaAnimationFrame; Adds a new Die frame. With a TAdvancedAnimationSprite, for example, this will cause the Dead() method of that sprite to be called, effectively removing it from the sprite list.
function AddGotoFrame(
const FrameIndex: Integer): TOmegaAnimationFrame; ;
Adds a new GotoFrame frame. FrameIndex indicates the frame number you want to go to. Notice that frames are counted from 0, so 0 is the first frame you added. By using the overloaded version of this method you can indicate the frame by name also.
function AddGotoAnim(
const AnimIndex: Integer): TOmegaAnimationFrame;
Adds a new GotoAnim frame. AnimIndex indicated the animation number in the animation collection this frame collection belongs to that you want to go to. These animations are also counted from 0. By using the overloaded version of this method you can indicate the animation by name also.
function AddLoop(
const FrameIndex, Loops: Integer): TOmegaAnimationFrame;
Adds a new Loop frame. The animation will go to the frame indicated by FrameIndex and loop a total number of times indicated by the Loops parameter. By using the overloaded version of this method you can indicate the frame by name also.

TOmegaAnimationFrame

This is the actual frame that TOmegaAnimationFrameCollection collects. The only public property is it's name, you should not need to access these.

TOmegaAnimationPlayer

This class takes care of progressing through an animation and populating a delivered object with the new values, interpolated and all.

Properties

Property Description
Animation: TOmegaAnimation Returns the animation that is currently being played by the player. Setting this property to another animation will immediately start playing that animation, even when the previous animation was stopped, except when an animation is playing that was initiated by the GosubAnimation() method below. In this case, the new animation will be the animation that will be returned to after the Gosub-animation.

Methods

Method Description
procedure Progress(
MoveCount: Single;
const Sprite: TAdvancedAnimationSprite);

Updates the Sprite with the player's animation as if MoveCount time units have elapsed. Time units are here dependant on how you specified your Duration parameters in the TOmegaFrameCollection methods.
If you take OmegaTimer.DeltaSecs you'll always get a proper value to use as MoveCount if you specified your animations in seconds. If, however, you specified your animations in frames, you should set your OmegaTimer to a TargetFPS that is higher than 0 and pass OmegaTimer.Delta as MoveCount, which will then always be the number of frames passed.

procedure ResetAnimation; Restarts playing the current animation.
procedure GosubAnimation(
const Value: TOmegaAnimation);
This remembers the currently playing animation and starts the new animation indicated by the Value parameter. As soon as the new animation encounters a 'Stop' frame, the original animation will be started again from frame 0. Starting new animations with this command while another Gosub-animation is already active will start that animation, but it will still remember the original animation that was playing in the beginning. You can use this for 'you hit me' animation sequences, for example, after which you want the animation to return to the original one.

TAdvancedAnimationSprite

This sprite class fully supports multiple layer of TOmegaAnimationPlayer instances to control it's appearance.

Properties

Property Description
PlayerCount: Integer The number of TOmegaAnimationPlayer instances you want to be available for this sprite instance.
property Players[
Index: Integer]: TOmegaAnimationPlayer
Gives access to the individual players available. You start a new animation by setting the Animation property of these player instances, for example. Look at the demo for a thorough example of multi-layered animation in the spriteclass.
BaseX, BaseY, BaseRotation, BaseAlpha, BaseScaleX, BaseScaleY These are the equivalents of TSprite's X, Y, Rotation, Alpha, ScaleX and ScaleY properties. But these values are the values all animation commands will be calculated with. So BaseX and BaseY always indicate the base position of your sprite, while X and Y will now indicate the position of your sprite after AnimationX and AnimationY have been added to it. Same for the other Base... properties. This way, X and Y will always contain the real position of the sprite, while you are free to move it independant of it's animation position with BaseX and BaseY.
AnimationX, AnimationY, AnimationRotation, AnimationAlpha, AnimationScaleX, AnimationScaleY Same as for BaseX, BaseY etc. except that these values contain the calculated values as given by the current animation of the player.

Methods

Method Description
procedure Move(
const MoveCount: single); override;

The Move() method of the TSprite class is overridden here to automatically update all involved animations for your sprite, and at the same time populating your sprite's properties with the correct values. This will in practice be the only function you call to advance animation. MoveCount is then treated just like you did before: As if MoveCount time units have elapsed. Time units are here dependant on how you specified your Duration parameters in the TOmegaFrameCollection methods.
If you take OmegaTimer.DeltaSecs you'll always get a proper value to use as MoveCount if you specified your animations in seconds. If, however, you specified your animations in frames, you should set your OmegaTimer to a TargetFPS that is higher than 0 and pass OmegaTimer.Delta as MoveCount, which will then always be the number of frames passed.
So please take care of setting up everyhting in your game the same: Either use TargetFPS = 0 and go for the seconds-based approach (which is the best in my opinion anyway) or, if you really have to, set TargetFPS > 0 and either base all your animation durations on frames and deliver OmegaTimer.Delta to this method as MoveCount, or still base all your animations in seconds and pass OmegaTimer.DeltaSecs to this method as MoveCount.

procedure ResetAnimation; Restarts playing the current animation.

Back to the Index