AppEasy Core SDK  1.5.0
Cross platform mobile and desktop app and game development SDK - The easy way to make apps
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines
CzAnim Class Reference

A collection of animation frames. More...

#include <CzAnim.h>

Inheritance diagram for CzAnim:
IzXomlResource

List of all members.

Public Types

enum  eAnimStatus { AS_Stopped, AS_Playing, AS_Paused }
 Values that represent the current state of the animation. More...
typedef CzVector< CzAnimFrame * >
::iterator 
_Iterator

Public Member Functions

_Iterator begin ()
_Iterator end ()
void setType (CzAnimFrame::eAnimType type)
CzAnimFrame::eAnimType getType () const
float getDuration () const
void setDuration (float duration)
void addFrame (CzAnimFrame *frame)
 Adds an animation frame to the animation.
bool getCurrentFrame (CzAnimFrame **current, CzAnimFrame **next, float current_time)
 Gets current frame.
void CalculateCurrentData (float current_time, CzAnimFrame *current_data, bool interpolate=true)
 Calculates the current frame data.
int getFrameCount ()
CzAnimFramegetFrame (int index)
void setCategory (int category)
int getCategory () const
void setAutoDelete (bool enable)
bool isAutoDelete () const
 CzAnim ()
virtual ~CzAnim ()
void GenerateAtlasFrames (int count, int frame_w, int frame_h, int start_x, int start_y, int pitch_x, int pitch_y, int image_width, float frame_speed)
 Generates a group of rect image atlas frames.
int LoadFromXoml (IzXomlResource *parebt, bool load_children, CzXmlNode *node)
 Creates an instance of this class from XOML.

Protected Attributes

CzAnimFrame::eAnimType Type
 Type of animation.
float Duration
 Duration of animation.
CzVector< CzAnimFrame * > Frames
 Animation frames.
int Category
 User defined category.
bool AutoDelete
 If set to true thenm timeline will be deleted when finished.

Detailed Description

A collection of animation frames.

Introduction

There are plenty of great games and apps out there that do not feature any form of animation. However, most modern games do feature animations to enhance their look and feel. Lets take "Angry Birds" as an example, Angry Birds uses animations all over the place, such as the animating birds and pigs, even the menus contain flashing and sweeping animations.

When we initially decided to implement an animation system we decided that it had to be very flexible and support any type of animation, be it animating the position of an actor, animating the graphical frames of an actor or even animating a list of commands for an actor. From AppEasy's point of view, animation refers to any variable or set of variables that can change over time.

The AppEasy animation system currently supports the following features:

  • Time based frame and interpolated named animations
  • Delayed and looped animations
  • Support for boolean, float, vectors (2d, 3d and 4d), rect (for image frames), string and custom frame data types
  • Resource manager that tracks and manages sets of animations (scene local and global)
  • Animation data re-use using animation instances
  • Animation time lines to support multiple simultaneous animations that can target object specific properties such as the colour of a scene or the position of an actor
  • Time line manager that tracks and manages sets of animation time lines
  • Callback notifications for animation instance started, stopped and looped events
  • Animations and animation time lines can be defined and attached to actors and scenes using XOML
  • Support for OnStart, OnEnd and OnRepeat events in code and in XOML
  • Linear, quadratic, quartic and cubic in and out easing

The animation system is split into the following classes:

Animation Frame Data

Animation frame data is the backbone of all animations, it represents the actual discrete state of a variable at a given point in time (called a key frame). An animation frame consists of two components:

  • Frame data - Frame data is the value or values of a specific variable at a specific point in time
  • Frame time - The time at which the frame has its value (in seconds)

The base class for all animation frame data types is the CzAnimFrame. This class provides a means for the developer to implement their own custom animation frame data types. The following animation frame data types are already implemented:

  • CzAnimFrameBool - Boolean variables such as actor visbility
  • CzAnimFrameFloat - Floating point variables such as angle and scale
  • CzAnimFrameVec2 - Floating point 2 parameter variables such as 2D position and velocity
  • CzAnimFrameVec3 - Floating point 2 parameter variables such as 3D position and velocity
  • CzAnimFrameVec4 - Floating point 4 parameter variables such as colour
  • CzAnimFrameRect - Integer 4 parameter variables such as image source rectangles
  • CzAnimFrameString - String based parameters such as narrative text, commands or even other timeline's

Animations and the Resource Manager

The resource manager is used to manage a group of resources (animations). The idea is that you create a group of animations then add them to the resource manager and then forget about them. The resource manager will take care of cleaning them up when the scene or main app is destroyed. The main app object contains its own global resource manager whilst all scenes contain their own local resource manager.

Note that when animations are created via XOML mark-up they are added to the resource manager. Animations that are created inside a scene will be added to the scenes resource manager, whilst animations created outside of the scene will be added to the global resource manager.

To find an animation within a scenes resource manager you would use could such as:

CzAnim* anim = (CzAnim*)scene->getResourceManager()->findResource("Player1Anim", CzHashes::Animation_Hash);

Note that if the animation is not found within the scene then the system will automatically search the global resource manager for the animation. You can prevent this global search by passing false as the third parameter to findResource().

Timelines are stored in the timelines manager of a scene, actor or the global time lines manager, depending on where they are declared.

Animation Instances

CzAnim is basically used as a means to store the animation data in a convenient place. With this in mind you do not play a CzAnim directly, instead you create an instance of it using CzAnimInstance:

// Create and set up an animation
CzAnimInstance* face_anim = new CzAnimInstance();
face_anim->setAnimation(anim);
face_anim->setTarget(actor, "SrcRect");

Note the following line of code:

face_anim->setTarget(actor, "SrcRect");

This line of code tells the animation to modify the "SrcRect" (the actors image atlas position) property of the actor object, causing the image to change.

Animation instances can be played, paused, resumed, stopped and restarted. You can also tell an animation to delay playing for a finite period of time.

Animation Targets and Target properties

AppEasy Core uses the concept of animation targets and animation target properties. An animation target is basically a class that contains a variable or group of variables that can be targeted for modification by an animation. The actual variable or variables that are targeted are called target properties. An example target would be an actor and example target property would be the actors position. When you create an instance of an animation you set the target and target property that the animation will modify using code similar to that shown below:

face_anim->setTarget(actor, "SrcRect");

Any class can be used as a target for animation as long as it derives from the IzAnimTarget interface and implements the the following pure virtual method:

    virtual bool    UpdateFromAnimation(CzAnimInstance *animation) = 0;

When the animation updates it will call back this method passing in its data asking the method to update the state of the object. Both scene and actor classes already have this functionality implemented.

Lets take a quick look at a small section of CzScene::UpdateFromAnimation() to see how the CzScene class has implemented this method:

bool CzScene::UpdateFromAnimation(CzAnimInstance *animation)
{
    unsigned int property_name = animation->getTargetPropertyHash();
    bool delta = animation->isDelta();

    if (Camera != NULL)
    {
        if (property_name == CzHashes::Position_Hash)
        {
            CzAnimFrameVec2* frame = (CzAnimFrameVec2*)animation->getCurrentData();
            if (delta)
            {
                CzVec2 pos = Camera->getPosition();
                pos.x += frame->data.x;
                pos.y += frame->data.y;
                Camera->setPosition(pos.x, pos.y);
            }
            else
                Camera->setPosition(frame->data.x, frame->data.y);
            return true;
        }
        else
        if (property_name == CzHashes::Angle_Hash)
        {
            CzAnimFrameFloat* frame = (CzAnimFrameFloat*)animation->getCurrentData();
            if (delta)
                Camera->setAngle(Camera->getAngle() + frame->data);
            else
                Camera->setAngle(frame->data);
            return true;
        }
        else
        if (property_name == CzHashes::Scale_Hash)
        {
            CzAnimFrameFloat* frame = (CzAnimFrameFloat*)animation->getCurrentData();
            if (delta)
                Camera->setScale(Camera->getScale() + frame->data);
            else
                Camera->setScale(frame->data);
            return true;
        }
    }

    return false;
}

The logic is quite simple, we check the name of the property that was passed in by the animation instance then check that against known property names of the class. If it matches then we move the animation data from the animation instance into our classes local variable.

As you can see implementing your own custom animation targets is a simple case of:

  • Deriving your class from IzAnimTarget
  • Implement the UpdateFromAnimation(CzAnimInstance *animation) method

Animation Timeline's

An animation time line is basically a way to group together multiple animation instances and play, pause, stop and resume them all together. The general idea is that you create an animation time line then create animation instances and add them to the time line. You then attach the time line to your destination object, be that a scene or an actor. The animation system will then take care of the rest for you. Here is an example showing how to create and use a time line:

// Find our face animation
CzAnim* face_anim = (CzAnim*)scene->getResourceManager()->findResource("FaceAnim", CzHashes::Animation_Hash);

// Create and set up our animation instance
CzAnimInstance* instance = new CzAnimInstance();
instance->setAnimation(face_anim);
instance->setTarget(actor, "SrcRect");
timeline->addAnimation(instance);
timeline->play();

// Create an animation timeline to hold our image animation
CzAnimTimeline* timeline = new CzAnimTimeline();
timeline->addAnimation(instance);

// Attach timeline to the actor
actor->setTimeline(timeline);

Defining and attaching animations is much easier and more intuitive if done declaratively using XOML mark-up. More on this this later

Note that when you attach an animation time line to a scene or an actor, the scene / actor will automatically take over updating it for you.

Time lines can be played, paused, resumed and stopped. All animation instances within the animation time line will be affected.

Resource Manager and Timelines

The resource manager is generally responsible for managing the lifetimes of animations and animation time lines, in particular those created from XOML mark-up.

Each scene has its own local resource manager as well as a global resource manager.

Working with Animations

The general work flow when working with the animation system has two potential paths:

  • Manual definition - You manually create all of the animation frames, animation classes, instances, timelines etc in code
  • XOML definition - You load a XOML file that contains the definitions, find the time lines and attach

The first method is more difficult as it does require creatng and setting up animation classes yourself. Heres the basic flow for manual animation setup:

  • Create a CzAnim object and give it a meaningful name
  • Create and set-up animation frames
  • Add animation frames to the CzAnim object
  • Add the CzAnim object to the scene or global CzAnimManager
  • Later when you need to create an instance of the animation, search the animation manager for the animation by name
  • Create a CzAnimTimeline object
  • Create a CzAnimInstance object and attach the CzAnim object
  • Set up any additional paramaters for the time line object
  • Add the time line object to the scene or global time line manager (not essential as scenes and actors can clean them up for you)
  • Set the actor or scenes time line using setTimeline()
  • Call the time line's play() method to start the time line playing

The second method using XOML is much simpler:

  • Create a XOML file
  • Add Animation and Timeline definitions
  • If your scene / actor is also defined in XOML then you simply set the Timeline property to the name of the timline and you are done. If not then continue onto the next step
  • Search the scenes timelines for our named time line
  • Set the actor or scenes time line using setTimeline()
  • Call the time line's play() method to start the time line playing

Creating a Basic Animation in Code

AppEasy supports a number of different types of animation as previously explained. In our example we are going to create a basic floating point animation that animates the rotation property of an actor object.

// Create an animation
CzAnim* anim = new CzAnim();
anim->setName("TestAnim");
anim->setDuration(3);
anim->setType(CzAnimFrame::FT_Float);

// Create and add frames
CzAnimFrameFloat* frame = new CzAnimFrameFloat();
frame->Time = 0;
frame->data = 0;
anim->addFrame(frame);
frame = new CzAnimFrameFloat();
frame->Time = 1;
frame->data = 45;
anim->addFrame(frame);
frame = new CzAnimFrameFloat();
frame->Time = 2;
frame->data = 90;
anim->addFrame(frame);

// Create animation instance
CzAnimInstance* instance = new CzAnimInstance();
instance->setAnimation(anim);
instance->setDelay(0);
instance->setRepeatCount(0);
instance->setTarget(actor, "Angle");

// Creata a time line
CzAnimTimeline* timeline = new CzAnimTimeline();
timeline->setName("Timeline1");
timeline->addAnimation(instance);

// Play the timeline
timeline->play();

// Attach timeline to the actor
actor->setTimeline(timeline);

As you can see it is a little verbose, which is why we recommend using XOML mark-up for defining animations in particular.

Creating a Basic Animation in XOML

XOML is AppEasy's mark-up language that can be used to define and set-up actors, scenes, resource, animations and other game elements. Here is an example showing how to set up the previous example using XOML syntax:

<xml>
    <Animation Name="TestAnim" Type="float" Duration="3" >
        <Frame Value="0"   Time="0.0" />
        <Frame Value="45"  Time="1.0" />
        <Frame Value="90"  Time="2.0" />
    </Animation>
    <Timeline Name="Timeline1" AutoPlay="true">
        <Animation Anim="TestAnim" Target="Angle" Repeat="0" StartAtTime="0"/>
    </Timeline>
</xml>

As you can see it is incredibly easy to set up animations and time line's using XOML syntax.

XOML Anim tag properties

  • Name (string) - Name of this animation resource
  • Tag (string) - Resource tag (used to group resources together)
  • Type (type) - The type of animation frame data, can be one of the following:
    • bool
    • float
    • vec2
    • vec3
    • vec4
    • rect
    • string
  • Duration (seconds) - The duration of the animation

Type and Duration are required properties

XOML Anim Frame tag properties

  • Time (seconds) - The time at which this frame is available
  • Value (any supported type) - The value of the frame at the above time. The value here depends on the type of animation that was defined. For example, if you declared the animation as a string type then this value should contain a string. If you declared the animation as a vec2 then the value should contain pairs of values
  • Easing (easing) - Type of easing to use, supported easing types include:
    • linear
    • quadin
    • quadout
    • cubicin
    • cubicout
    • quarticin
    • quarticout

Time and Value are required properties

XOML Timeline tag properties

  • Name (string) - Name of this animation timeline resource
  • Tag (string) - Resource tag (used to group resources together)
  • AutoPlay (boolean) - When set to true the timeline will begin animating as soon as it is attached to an actor or scene
  • TimeScale (number) - This property can be used to change the speed at which the timelines animations are played back. For example, if we set this value to 2.0 then the animations in the previous example would play back twice as quickly. This feature allows us to speed up and slow down animations without having to create new instances of them
  • Local (boolean) - By default timelines declared inside an actor will be local to the actor and not the scene. By setting Local=”false” the timeline will be placed into the containing scene instead. This is useful if you want to show a group of timeline across different actors but do not want to move the timeline definition into the scene or global resource manager

Timelines also contain child Animation tags which define which animations will appear in the timeline. Lets take a look at the properties of this inner tag:

  • Anim (animation) - Names an animation to be included into the timeline
  • Target - Sets the objects target property that should be updated by the animation. For example, Position would target an actor scene position updating its position
  • Repeat (number) - The number of times that the animation should repeat before stopping (0 represents play forever, which is the default)
  • StartAtTime (seconds) - Setting this parameter will delay the start of the animation
  • Delta (boolean) - When set to true, instead of directly setting the target objects property it adds to it instead (called delta animations)
  • Interpolate (boolean) - When set true (which id default) animation frames will be smoothly interpolated from one key frame to the next. When set to false animation frames will suddenly switch when their time marker is reached. For most animation you will want to use interpolation, however some kinds of animations are not suited to interpolation, for example, image sprite animations
  • OnStart (actions list) - Defines an actions list that will be called when this animation starts playing (only called for animations with a StartAtTime value that is not 0
  • OnEnd (actions list) - Defines an actions list that will be called when this animation ends
  • OnRepeat (actions list) - Defines an actions list that will be called when this animation repeats

Anim and Target are required properties

Note that a time line can be assigned to as many objects you like but the time line will be played back the same on all objects. This is very useful if you have a group of actors that need to run the same animations synchronously.

Creating an Image Animation

We are now going to take a look at creating an image based animation that we can attach to an actor:

// Create an animation
CzAnim* anim = new CzAnim();
anim->setName("TestAnim");
anim->setDuration(0.8f);
anim->GenerateAtlasFrames(8, 36, 40, 0, 0, 512, 40, 512, 0.1f);

// Create animation instance
CzAnimInstance* instance = new CzAnimInstance();
instance->setAnimation(anim);
instance->setDelay(0);
instance->setRepeatCount(0);
instance->setTarget(actor, "SrcRect");

// Creata a time line
CzAnimTimeline* timeline = new CzAnimTimeline();
timeline->setName("Timeline1");
timeline->addAnimation(instance);

// Play the timeline
timeline->play();

// Attach timeline to actor
actor->setTimeline(timeline);

Setting up an image based animation is a little simpler because the CzAnim::GenerateAtlasFrames() method() automates the generation of frames for us.

Although the same can also be done in XOML which is even simpler, e.g:

<Animation Name="TestAnim" Type="rect" Duration="0.8" >
    <Atlas Count="8" Duration="0.1" Pitch="36, 40" Size="36, 40" Width="36" />
</Animation>
<Timeline Name="Timeline1" AutoPlay="true">
    <Animation Anim="TestAnim" Target="SrcRect" Repeat="0" StartAtTime="0"/>
</Timeline>

The properties for the Atlas tag are as follows:

  • Count (number) - Number of frames to generate
  • Duration (seconds) - The amount of time to display each frame
  • Pitch (x, y) - The amount to step across and and right to get to the next frame in pixels
  • Size (x, y) - The width and height of each animation frame in pixels
  • Width (number) - The width of the image atlas in pixels
  • Position (x, y) - The position on the atlas where frames should start being taken from

Member Typedef Documentation

typedef CzVector<CzAnimFrame*>::iterator CzAnim::_Iterator

Member Enumeration Documentation

Values that represent the current state of the animation.

Enumerator:
AS_Stopped 
AS_Playing 
AS_Paused 

Constructor & Destructor Documentation

CzAnim::CzAnim ( ) [inline]
virtual CzAnim::~CzAnim ( ) [inline, virtual]

Member Function Documentation

void CzAnim::addFrame ( CzAnimFrame frame)

Adds an animation frame to the animation.

Parameters:
[in,out]frameIf non-null, the frame.
_Iterator CzAnim::begin ( ) [inline]
void CzAnim::CalculateCurrentData ( float  current_Time,
CzAnimFrame current_data,
bool  interpolate = true 
)

Calculates the current frame data.

This method is called internally by the animation systen to calculate the animations current frame data from its current and next animation frames, taking into account the elapsed time, interpolation and tweening effect.

Parameters:
current_TimeThe current time.
[in,out]current_dataIf non-null, current anim frame.
interpolatetrue to interpolate animation frames.
_Iterator CzAnim::end ( ) [inline]
void CzAnim::GenerateAtlasFrames ( int  count,
int  frame_w,
int  frame_h,
int  start_x,
int  start_y,
int  pitch_x,
int  pitch_y,
int  image_width,
float  frame_duration 
)

Generates a group of rect image atlas frames.

Parameters:
countNumber of frames to generate.
frame_wThe frame width.
frame_hThe frame height.
start_xThe start x coordinate.
start_yThe start y coordinate.
pitch_xThe x pitch.
pitch_yThe y pitch.
image_widthWidth of the image.
frame_durationDuration of each frame.
int CzAnim::getCategory ( ) const [inline]
bool CzAnim::getCurrentFrame ( CzAnimFrame **  current,
CzAnimFrame **  next,
float  current_Time 
)

Gets current frame.

Author:
Mat
Date:
14/01/2013
Parameters:
[in,out]currentIf non-null, the current.
[in,out]nextIf non-null, the next.
current_TimeThe current time.
Returns:
true if it succeeds, false if it fails.
float CzAnim::getDuration ( ) const [inline]
CzAnimFrame* CzAnim::getFrame ( int  index) [inline]
int CzAnim::getFrameCount ( ) [inline]
bool CzAnim::isAutoDelete ( ) const [inline]
int CzAnim::LoadFromXoml ( IzXomlResource parent,
bool  load_children,
CzXmlNode node 
) [virtual]

Creates an instance of this class from XOML.

LoadFromXoml is the main method used by all classes that can be instantiated from XOML mark-up. This method creates an instance of this class from the supplied XML node structure specified by node.

Parameters:
[in]parentIf non-null, the parent.
load_childrentrue to load child nodes.
[in]nodeIf non-null, the XOML markup node that defines this object
Returns:
nergative value for error. if 0 then processing of further XOML will stop.

Implements IzXomlResource.

void CzAnim::setAutoDelete ( bool  enable) [inline]
void CzAnim::setCategory ( int  category) [inline]
void CzAnim::setDuration ( float  duration) [inline]
void CzAnim::setType ( CzAnimFrame::eAnimType  type) [inline]

Member Data Documentation

bool CzAnim::AutoDelete [protected]

If set to true thenm timeline will be deleted when finished.

int CzAnim::Category [protected]

User defined category.

float CzAnim::Duration [protected]

Duration of animation.

Animation frames.

Type of animation.


The documentation for this class was generated from the following files: