An Object Oriented Approach To Animation Notes

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 12

An Object Oriented Approach to

Animation
By Yatin S. Shelke

Introduction to Object Oriented Animation


In the past 20 years, the video game industry which has seen rapid growth from simple
2D monochromatic games to full blown high resolution, full color and fast 3D games
that are so popular today, and even modern films are full of computer-generated
images. At the same time, object-oriented programming has made it easier to conquer
the complexity involved in creating high quality computer animation. Creating an
animation can be conveniently thought of as drawing objects currently in view on the
computer screen. For example, a monster in the game DOOM is an object instance of
the class for that kind of monster.

Simply put, an Object Oriented Animation application defines various classes, creates
the instances of these classes and performs operations on the object instances. Below,
we'll explain some of the essential abstractions that you can use to create your own
computer animations.

This article assumes that you have basic familiarity with the principles of object-
oriented programming in C++. If you don't know C++, first check the C++ Made Easy
tutorial, especially the sections on classes and inheritance.

Graphic Object abstraction


The most basic abstraction in animation is that of a Graphical Object, which we'll
represent here as class GraphicObject. Anything that is drawn on the screen as a unit is
a Graphic Object. A point, a line, a polygon, a Bezier curve, a Bezier surface, a polygon
with a texture map, a background, a flat image, a sprite a 3D shape made of polygons
are all examples of Graphic Objects. (Don't worry if you don't know what something like
a Bezier curve or a sprite is—Bezier curves and surfaces are just special curves and
surfaces that have mathematical properties that make them easy to work with in
animation, and a sprite is just a simple 2D image—your mouse pointer on the screen is
an example of a sprite). Simple graphic objects can be combined into more complex
graphic objects.

The most basic problem that an animation engine must solve is to be able to draw
these objects on the screen. In procedural (non-objected oriented) programming, there
may be nothing in common between the functions to draw a cube and a sphere. But in
object oriented programming, we want to be able to have a generic solution for drawing
objects. We can think of "drawing" a graphical object as an action that someone (the
caller) can perform on an entity (the callee) i.e. the Graphic object. The caller should
not have to care about the details of how the drawing is done, as long as the Graphic
Object makes the action available to the caller. So the class GraphicObject which should
have a method on it to draw the object, i.e. GraphicObject::draw(). Concrete graphic
objects like cubes, spheres, lines, curves, surfaces etc. can all inherit from class
GraphicObject and implement the method GraphicObject::draw().

Designing a draw() function this way is not only good style, but has some very
important implications for animation engine design. An engine that deals only with the
abstract class GraphicObject will NOT have to be changed on introduction of new types
of Graphic Objects. As an analogy, a hypothetical automobile engine may be designed
to be able to take in gasoline, ethanol, natural gas, or perhaps even vegetable oil! As
long as the combustion unit design is isolated from other parts of the engine, such that
it interfaces with the rest of the engine through a piston that can drive other parts, it
does not matter how the combustion unit is built or what type of fuel it uses. To the
driver of the automobile, the engine must simply have an external interface, i.e. the
ignition system. The driver simply needs to insert the ignition key and turn it to start
the engine. The GraphicObject abstraction in the case of an animation engine is like the
combustion unit, and the method GraphicObject::draw() is like turning on the ignition.

Thus, the method GraphicObject::draw() is the essential method for to all Graphic
Objects. Without this method, the object cannot be made visible on the screen. By
making the GraphicObject::draw() an abstract method, we get a complete separation of
interface and implementation, so that the animation application can call this method on
each Graphic Object in a generic manner, yet each Graphic Object can be drawn in its
own unique way.

To further extend the scope of GraphicObject, we can include camera movements as


drawing operations. Thus in addition to objects that the user can see, the GraphicObject
abstraction could include implementations of the animation engine camera—we'll talk
more about this later.

The Graphic Object abstraction has properties and methods that may or may not be
implemented by all Graphic Object classes. Most Graphic Objects have the property of
"position", which the method GraphicObject::draw() can use as a reference point for
drawing the object. The position is like an anchor point for the graphic object.
GraphicObject::draw needs to know how to draw the object with reference to that
position.

When the graphics engine moves the graphic object, the GraphicObject::draw() method
needs to recalculate the location of all parts of the graphic object and draw them at
their new location, thus redrawing the graphic object as a whole. The advantage of the
position property in GraphicObject is that the engine simply sets a new position on the
graphic object, and the graphic object redraws the rest of itself in the new location.
Without the position property, the engine would have to relocate individual parts of the
graphic object, thus binding the engine design to the details of its graphic objects.

Not all user visible graphic objects need a position property. An example is a graphic
object representing the background. The drawing of the background is not tied to any
position because it is just drawn on the entire screen. On the other hand, there may be
graphic objects that are not user visible, but do need a position. An example of such a
graphic object is the animation camera, as it does need a position to compute the view
of the rest of the visible objects.
Graphic Objects with the position property may also have operations on them to
perform rigid body movements, such as GraphicObject::reposition(),
GraphicObject::displace(), or GraphicObject::rotate(). A "rigid body movement," by the
way, is just a mathematical term for a movement where all the points in the object stay
in the same places relative to each other after the movement—for example, if you pick
up a book and put it on the bookshelf, the cover and all the pages are still in the same
places relative to each other afterwards, even though the book has moved. An "elastic
body movement" on the other hand is when the points move in relationship to each
other—for example, after you inflate a helium balloon, the points on the balloon are
much further from each other than before. Elastic body movements could include
GraphicObject::scale(), or GraphicObject::shear(). These rigid and elastic movements
could potentially be made part of the abstract Graphic Object interface, as they apply in
a generic manner to a large variety of Graphic Objects. Note that these methods are
not intended to draw the graphic object. These methods affect the target object so as
to make the method GraphicObject::draw() draw the object with the desired
transformation applied.

 GraphicObject::reposition(Vector new_position) : sets the position of the Graphic


Object to the given new position. The object will get drawn around the new
position by the method GraphicObject::draw().
 GraphicObject::displace(Vector displacement) : sets the position of the Graphic
Object to a new position that is the sum of the current position and displacement
vector. The object will get drawn around the new position by the method
GraphicObject::draw().
 GraphicObject::rotate(Vector axis, double angle) : rotates the point representing
the position of the body around the given axis by the given angle. The object will
get drawn around the new position by the method GraphicObject::draw().
 GraphicObject::scale(double proportion) : sets a scale by which the Graphic
Object is to be resized, without changing its position. The object will get drawn
around the new position by the method GraphicObject::draw().
 GraphicObject::linear_shear(Vector axis, Vector shear_displacement) :
repositions each point of the Graphic Object by moving it parallel to the given
axis, by the given shear displacement. The object can be drawn around the new
position when you call GraphicObject::draw().
 GraphicObject::planar_shear(Vector plane_axis_1, Vector plane_axis_2, Vector
shear_displacement) : repositions each point of the Graphic Object by moving it
parallel to the given plane defined by plane_axis_1 and plane_axis_2, by the
given shear displacement. The object will be drawn around the new position
when you call GraphicObject::draw().

On the other hand, "plastic body" movements—operations that change the shape of the
object in potentially arbitrary ways—probably shouldn't be a method on the abstract
Graphic Object. A good example of performing plastic operations on graphic objects is
in the game SPORE, which allows the player to reshape a creature's body through
plastic deformations.

The problem with plastic body movements is that the function interface required for
that operation depends greatly on the specifics of the Graphic Object. To achieve plastic
transformations of a graphic object, the graphic object must be modified using a more
specific interface, independent of the animation engine. For example, event handling
code in an animation game may map certain events to operations on instances of
graphic objects. These operations would be specific to the type of the graphic object
and the application and could perform the plastic transformations on the graphic object
using methods that are not available on the GraphicObject itself. In fact, the animation
engine will not even know about these happenings, but will simply call
GraphicObject::draw(), which will draw the object with the new plastic deformation.

Given that there will be properties of a Graphic Object that are unique to its
implementation, we need a GraphicObject::refresh() method that could get called
internally from methods like GraphicObject::displace(), GraphicObject::rotate(),
GraphicObject::shear() or GraphicObject::scale() to perform calculations common to all
these methods. For example, take a flashlight Graphic Object (class FlashLight) being
rotated around an axis. The FlashLight::rotate() method should do just the geometric
transform, e.g. changing the direction vector property of the flashlight. It shouldn't
need to worry about the direction of the light source—instead, it can call the
FlashLight::refresh() method which will change the position of the flashlight's light
source based on the new direction of the torchlight. The refresh method saves other
methods the trouble of recalculating changes in non-geometric properties that result
from a geometric operation.

Here's a possible interface for the Graphic Object based on what we've looked at so far:

1
2class GraphicObject {
3protected:
4 virtual void refresh() = 0;
5public:
6 virtual void draw() = 0;
7 virtual void reposition(Vector position) = 0;
8 virtual void displace(Vector position) = 0;
9 virtual void rotate(Vector axis, double angle) = 0;
10 virtual void scale(double proportion) = 0;
virtual void linear_shear(Vector axis, Vector shear_displacement) = 0;
11
virtual void planar_shear(
12
Vector axis1, Vector axis2, Vector shear_displacement) = 0;
13
};
14class PositionalGraphicObject : public virtual GraphicObject {
15protected:
16 Vector position;
17public:
18 Vector get_position();
19 void set_position(Vector p);
20};

Composite Graphic Object Abstraction


Not all graphics objects need to be based on pixels. Simple Graphic Objects can be used
to create a Composite Graphic Object. For example, a cube could have a list of 6 Face
Graphic Objects as a field to define the surface of the cube. This greatly simplifies
operations like rotating the cube around an axis. As long as the Face Graphic Object
has the rotate method implemented, the Cube Graphic Object simply has to call that
method on each of the Face objects in its list and the Cube will rotate as desired. Using
a generic Graphic Object greatly simplifies the composition and implementation of more
complex Graphic Objects. Imagine a creature in a game like SPORE—it will be
composed of simpler objects representing the head, torso, arms and legs, which in turn
would be composed of polygons or Bezier surfaces. To make the creature rotate, the
abstract rotate operation with identical parameters needs to be called on its head,
torso, arms and legs, which would in turn do the same on their list of polygons or
Bezier surfaces. The complex creature object is able to delegate much of the work to
simpler objects, rather than having to compute everything itself.

Here's pseudocode showing a possible declaration of a composite graphic object:

1
class CompositeGraphicObject {
2
protected:
3 List<graphicobject>* graphic_object_list;
4public:
5 CompositeGraphicObject(List<graphicobject>*);
6 void add_graphic_object(GraphicObject* graphic_object);
7 void delete_graphic_object(GraphicObject* graphic_object);
8};
9</graphicobject></graphicobject>

Camera Abstraction
The Camera is an essential abstraction for an animation engine. The camera maps
objects in an animation to the rectangular animation display window. The camera
determines what parts of the animation are visible on the screen based on its location
and other parameters. Intuitively, a simple animation camera is a hypothetical lens that
has the ability to clearly focus any number of objects, located at arbitrary distances in
its field of view, to a single rectangular screen. Most video game animation engines use
this kind of simple camera abstraction. This kind of camera is different from a camera
lens or the human eye, which focus on only part of a scene (as determined by the focal
length). 3D animated movies like Ratatouille or Cars, unlike games, need a camera
similar to the human eye in order to shift focus between near and far objects.

For 3D perspective view animations (most contemporary video games), the Camera is
defined by its position and orientation in the animation (virtual) world. When a 3D
Cartesian coordinate system is used, the camera is defined by 3 vectors - position,
direction of view, and upward orientation vector. Imagine yourself in the center of a
room with your head oriented straight up and looking straight. Your position in the
room, the direction you are facing and the orientation of your head is analogous to the
camera's position, direction of view, and upward orientation vector. Moving around the
room is like changing the position of the animation camera. Turning your head in
different directions - left, right, up, down, turning around etc. is like changing the
direction of view and upward orientation vector. To understand why a separate view
direction and upward orientation vector are needed, imagine tilting your head to your
left (without turning your neck). The direction of view remains same in this case, but
the upward orientation is changed. Similarly turning your head to the left without tilting
it causes the direction of view to change, but not the upward orientation. There is a
one-to-one mapping from the triplet {position, direction-of-view, upward-orientation}
to the contents of the field of view.

In a 3D game, the player's viewpoint moves around the virtual world when the
animation engine moves and orients the animation camera.

Although the camera is not drawn as an object on the screen, it is nonetheless a worthy
candidate to inherit from class GraphicObject. Its implementation of
GraphicObject::draw() will position and orient the camera in the virtual world, allowing
the rest of the visible objects to be drawn correctly onto the screen.

Here's psuedocode that demonstrates a possible definition of class Camera:

1
class Camera : public virtual GraphicObject {
2. . . other protected members . . .
3 Vector position;
4 Vector direction;
5 Vector up;
6public:
7. . . other public members . . .
8};

Frustum Abstraction
The frustum is a concept closely related to the camera. It defines the clipping planes for
the field of view. It is of the shape of a square pyramid, except part of the top of the
pyramid is cut off. To understand the frustum better, imagine yourself looking at a
small rectangle in front of you, with a much larger rectangle behind this small
rectangle, such that the sides of the rectangles are parallel to each other. If your eye
were the apex of a pyramid with the larger rectangle as its base, then the frustum is
the part of this pyramid between the small rectangle and the big rectangle. If the small
rectangle represents the video screen as a window into the animation world, then you
can only see things inside the frustum on the screen; anything outside it is simply out
of your field of view. The clipping planes of the frustum are the planes that contain the
faces of the frustum. Diagram 1 gives a 3D representation of the frustum.

The camera defines all possible points in space that can be mapped to the screen. The
frustum defines all the points that actually do get mapped to the screen. The process of
using the frustum to define these points is known as frustum culling. The camera is
located exactly at the apex of the pyramid described above, and its direction of view is
the vector from the tip of the pyramix to the center of the base and perpendicular to
the near and far rectangles. The camera's upward orientation is parallel to one of the
sides of the rectangle. You can see the camera in Diagram 1.
Diagram 1: Frustum 3D Representation

The dimensions of the frustum are usually set only once at the beginning of the
animation application. However, it is one of the inputs given to the animation engine,
and therefore should be abstracted to keep the engine platform/library independent.

A possible definition of class Frustum is given in pseudo code.

1class Frustum {
2private:
3 double near; // z coordinate of near rectangle with respect to camera
4 double far; // z coordinate of far rectangle with respect to camera
5 double right; // x coordinate of right side of near rectangle with respect to camera
6 double left; // x coordinate of left side of near rectangle with respect to camera
7 double top; // y coordinate of top side of near rectangle with respect to camera
8 double bottom; //y coordinate of bottom side of near rectangle with respect to camera
9};

Animation Object Abstraction


An animation application needs to do more than just drawing Graphic Objects. It needs
to animate them, which means changing the Graphic Object in discrete steps. The
structure of most animations is a loop of two steps. The first step is to make all the
computations needed for drawing a single frame of the animation. The second step is to
draw the frame by updating the video memory of the display device. These two steps
repeat until the animation stops. This is essentially the same as the way a movie is
displayed in a theater. The movie projector closes its shutter and rolls a frame of the
film in front of the light source (step 1), then opens the shutter to let the light of the
frame image out to screen through the lens (step 2). This sequence repeats itself as
nearly 48 times in a second which gives the viewer the illusion of a continuous movie
experience.

A simple abstraction for an animation is to have a class with a single method on it that
simply does the computation for loading the image of the frame to be displayed next.
Although it would be tempting to call this method draw(), a more appropriate name
would be get_next_frame().

If the film projector above were implemented in software, it would have one animation
object whose method AnimationObject::get_next_frame() would load the image from
the Image Graphic Object into that part of the application's memory that gets copied to
the video memory of the display device. As another example, the abstract class
"MovieClip" used in ActionScript (a programming language used to creating Flash
applications) is a generic Animation Object abstraction.

An animation application may not want to draw just one Image Graphic Object in each
frame. Instead, it would identify various Animation Objects and put them together in
each frame. For example, the monsters in the game DOOM each map to an Animation
Object. The AnimationObject::get_next_frame() for each of the monster's Animation
Objects performs actions on the Graphic Object associated with the monster. These
operations might include repositioning, displacing, rotating, scaling, or even smiling and
growling! The DOOM game application creates the monsters and the DOOM animation
engine goes through the list of all monsters, calling AnimationObject::get_next_frame()
on each of them, thus giving the user the illusion that they are all moving, turning,
attacking or growling.

Let us consider why we need the Animation Object. If you see an animated movie such
as Disney's Cars, you can't help but notice that every object in the movie is animated
individually. The animation engine that renders each frame must manipulate several
objects at once for each frame of the movie. The animation engine that creates the
movie is asking each of the objects to draw themselves in each frame. For each frame
that GraphicObject::draw() is called on an object, the object will get drawn, potentially
differently. Even though it is easy to relate to the abstraction of Graphic Object in a
single frame, it is a little more difficult to grasp that the Graphic Object is actually
extended over a range of frames of the movie. The extension of the Graphic Object
across a range of frames is precisely the abstraction of "Animation Object". To
understand this is to take a giant leap into the world of animation! If you ever get lost
in the design of your animation/game engine, simply read this paragraph again to
return to home base.

Now we can derive some essential properties of an Animation Object. One of the
properties of the Animation Object is a Graphic Object or (a list of Graphic Objects) that
it needs to draw across its range of frames. Because the exact Graphic Objects depends
on the nature of the Animation Object, each Animation Object subclass will define its
own member variables to hold onto the Graphics Objects it needs. To perform the
animation, the Animation Object needs to call GraphicObject::draw() on each of its
Graphics Object members during the AnimationObject::get_next_frame() method.

There is one property that can be considered to be valid for all Animation Objects. The
idea that there is a range of frames across which the Graphic Object will be displayed
suggests that the range of frames is an essential property of an Animation Object. For
simplicity, the animation object's first frame can be 0, while its last frame would be
equal to (nframes - 1), where nframes is the total number of frames that the animation
persists. The range will be depicted as {0, nframes - 1}. This range of frames is used
not by the animation engine, but by the method AnimationObject::get_next_frame(),
or by a module other than the animation engine (like an event handler module) to
extend or shrink the range.

To understand the range of frames better, let's look at an example of an Animation


Object: a moving cube that begins moving at frame X and stops at frame Y. This cube
is an example of an animation object with a range of frames { 0 , (Y - X - 1) }. For now
let's assume that something manages the animation object's placement in the
animation engine, so that the cube animation is seen on the screen only for the range
of frames specified. When the cube animation object is created, its frame number would
be 0. When this object is given to the animation engine, the engine simply calls
AnimationObject::get_next_frame() on it. This method sees that the frame number is
0, draws the cube in its initial position, and increments the frame number. The engine
then comes back and calls AnimationObject::get_next_frame() the second time. Since
the current frame counter has changed to 1 (frame 2), this method draws the cube in
its next position. And so on till the last frame is reached. Thus the cube gets animated
by the engine over its range of frames. This is illustrated in pseudocode below, wherein
the X position of the cube gets changed over its range of frames.

1
FrameState CubeAnimationObject::get_next_frame()
2{
3 if (current_frame displace( Vector( 0, deltaX ) ;
4 }
5 . . .
6cube->draw();
7. . .
8}
It is very common to find animation objects in movies/animations/games that repeat an
animation effect continuously, such as for a continuously rotating object, or even a
continuously repeating scene. On the other hand, some animations stop after the last
frame is displayed. In video games, there are other ways an animation can play out, for
example, on pressing a key, a blinking object stops blinking—a continuously repeating
animation that gets stopped in its tracks. In some cases an animation can play in
reverse. For example, in the game DOOM, when monsters are killed, their bodies
disintegrate into pieces that collect in a pile at the place the monster was killed.
Sometimes, these monsters get revived. In this case, the animation of the
disintegration of the monster's body is played back exactly in reverse sequence. The
above examples illustrate the need for more abstract operations on the Animation
Object. The abstract operations on an Animation Object can be summarized as follows:

 AnimationObject::get_next_frame() : to play the animation forward (first frame


to last)
 AnimationObject::get_previous_frame() : to play the animation in reverse (last
frame to first)
 AnimationObject::pause() : to pause the animation
 AnimationObject::resume() : to resume a paused animation
 AnimationObject::rewind() : to rewind the animation and start playing from first
frame

One issue that must be addressed is how the animation engine determines which of the
above calls must be made next. For example, after a call to
AnimationObject::get_next_frame(), it is possible that for a repeating animation, the
last frame was reached, and the next call must be AnimationObject::rewind().
However, if this was not the last frame, then AnimationObject::get_next_frame() must
be called next.

One obvious, but bad, solution is that the animation engine keeps track of the frame
number for each of its animation objects and somehow knows what to do for each
frame of each animation object. This would completely break the abstract relation
between animation engine and animation object! A much better alternative is for the
animation object to track of its frames because it knows best what to do for the next
frame. In this case, the animation object must return information to the engine about
what to do next. One way to do this is to return an enumerated value to represent
instructions to the animation engine. The enumeration FrameState is described in
pseudocode below along with a possible declaration of the abstract class
AnimationObject.

1enum FrameState {
2// tells the caller of the AnimationObject method what to do after the call
3 PLAY_NEXT_FRAME, // play next frame (start play or resume paused)
4 PLAY_PREVISOUS_FRAME, // play the previous frame
5 STOP, // stop playing the animation object
6 PAUSE, // pause playing the animation object
REPEAT // rewind the animation object
7
};
8
class AnimationObject {
9
protected:
10
11
List<graphicobject>* graphic_object_list;
12
int start_frame = 0;
13
int total_frames;
14
public:
15 virtual FrameState get_next_frame() = 0;
16 virtual FrameState get_previous_frame() = 0;
17 virtual void pause() = 0;
18 virtual void resume() = 0;
19 virtual void rewind() = 0;
20};
21</graphicobject>

A real example of an animation engine that implements these operations is a DVD


player. This animation engine has one currently playing Animation Object (the scene or
chapter being played), that contains one Graphic Object per frame of the animation, i.e.
the image of the scene to be displayed on the screen for that frame. Subsequent calls
to AnimationObject::get_next_frame() on the Animation Object load the next frame's
Graphic Object and call the method GraphicObject::draw() on it. These Animation
Object operations are performed on the DVD player by pressing keys on the DVD
remote control. When you press the PLAY button on the remote control, you are really
asking the DVD player's animation engine to call AnimationObject::get_next_frame()
continuously. When you press the PAUSE or STOP button, you are really calling
AnimationObject::pause(). The STOP button additionally stops the animation engine
completely. This additional stop step is not an operation on the Animation Object,
rather, it is an operation on the animation engine itself. The PLAY button also maps to
AnimationObject::resume(), asking the player to continue calling
AnimationObject::get_next_frame() from where it was paused. The STEP BACK button
is calling AnimationObject::rewind() to rewind to the frame of the Animation Object i.e.
the scene being played. The STEP FORWARD button is really asking the animation
engine to replace the current Animation Object by the Animation Object for the next
scene and start calling AnimationEngine::get_next_frame() on the new current
Animation Object. The REWIND button is asking the player's animation engine to make
calls to AnimationObject::get_previous_frame() at different frequencies (1x, 2x, 4x and
so on). Similarly the FFWD button is asking the engine to make calls to
AnimationObject::get_next_frame() at those different frequencies. Whenever you are
wondering about interface of the Animation Object abstraction, think of your DVD
player and its remote control!

As another example, the animation camera can also be animated, and this animation
can be implemented via a Camera Animation Object. To animate the camera, an
Animation Object will not have a drawable (visible) kind of Graphic Object to
manipulate, instead, it will have to manipulate the camera triplet {position, direction,
up}. Note that all such Animation Objects need to manipulate exactly one global
camera, as one animation can have only one camera. (I honestly don't know how a
spider manages to see with 8 eyes, but if the animation engine were a spider, it would
have to do with just one eye. Further, I would certainly not want to teach animation to
a spider.)
Article 2 will how Animation Objects are contained in Layers. Although the discussion so
far implicitly assumes that the animation engine calls the methods of AnimationObject
directly, a better design is to have the Animation Object contained in a "Layer", and its
methods to be called via the Layer container object. Article 3 will discuss how layers,
layer folders and animation objects are used in an animation engine. It will also discuss
how to break up an animation into layers for more modularity.

Summary
A Graphic Object is an abstraction for anything that contributes to the content of a
single frame of animation. A Graphic Object can be visible on the screen, such as
objects on the screen, or it is something invisible, but that affects the rest of the
objects that are visible, such as a Camera Graphic Object. Most Graphic Objects require
a "position" property, while some do not need a "position" such as the background
Graphic Object.

An Animation Object is an abstraction for the extension of a Graphic Object across a


range of frames. An Animation Object contains one or more Graphic Objects. The
animation application can consist of one or more Animation Objects. The method
AnimationObject::get_next_frame() performs computations necessary to get its list of
Graphic Objects drawn to the display. Other methods on the Animation Object cause it
to pause, resume, rewind or reverse.

An animation application or game implementation can become very complex simply due
to the large number of Graphic and Animation Objects involved, even ignoring all the
game logic and drawing and interaction of each piece of the animation/game, making
an object oriented approach useful for managing the complexity. The next
article discusses how the concepts of Frames, Layers and Layer Folders help organize of
the multitude of things that need to be drawn and animated in your game.

Continue to Part 2: Frames, Layers and Layer Folders


Popular pages

 Jumping into C++, the Cprogramming.com ebook


 How to learn C++ or C
 C Tutorial
 C++ Tutorial
 5 ways you can learn to program faster
 The 5 most common problems new programmers face
 How to set up a compiler
 How to make a game in 48 hours

You might also like