Visviva Player | Visviva Tools | SDK for Developers | ScriptV
ScriptV Overview

This chapter will take new users step by step through a basic overview of the ScriptV language.  It will also briefly describe the process of composing animation sequences with the Visviva Animation Engine.

Like a painting, or a poem, all computer animation originally issues forth from a vision in the mind of an artist.  The task of the artist is to create a work of art that is as similar to that original vision as the artist’s abilities and technical skills will allow. 

As an introduction to ScriptV, we will create an image of an aquarium with a supply of active tropical fish. 

As we progress through this chapter, we’ll demonstrate how ScriptV and the Visviva Animation Engine can be used to construct this cyber-aquarium.

Objects

Objects are the basic building blocks of a ScriptV animated program, and they are defined in ScriptV by lines of program code.  An object in a Script V animated title is anything shown or hidden on the display, such as an animated cartoon character, a 3D vehicle, a button, an instrument, a menu, a spreadsheet, an image, an outline, or a transformation.

Almost every visible thing in ScriptV computer animation is an object.  An animation title played in the Visviva Animation Engine is essentially a multi-tiered arrangement of objects.

Suppose ScriptV was used to develop a cyber-aquarium:

The graphic images of the fish that swim around inside the aquarium would be referred to in ScriptV as objects.

The aquarium image would be called an object.

The path along which the fish swim, and the frame-by-frame animations of each fish are also objects.

There are also many invisible objects inside the aquarium, including sound and keyframe animation control nodes.

1.1.    Hierarchy in Objects

Objects in ScriptV will very often have a hierarchical structure. Objects can be thought of as building blocks that are used in the creation of higher-level entities, which in turn will serve as building blocks to make still higher-level entities, and so on.  Think of a human body as an example: a human body can be seen as a composite object that contains 6 components, or child objects - a head, a torso, and four limbs.  A human head can be described as a composite object containing several smaller component objects, such as eyes, ears, nose, and mouth.

In ScriptV, object hierarchies are common because very few entities are indivisible.  A ScriptV complex object may be described as an ordered collection of simpler objects.

Object hierarchy in ScriptV may be symbolized as an upside-down tree, with each child object represented as a single node.  The objects used as components for building larger objects are the child nodes at the lower levels of the tree.  The complete object is the parent node at the upper level of the tree, as shown in the accompanying figure:

In this object hierarchy, the animated fish is the parent node at the top of the tree.  The animated fish is composed of four frames, and each of these frames contains two separate images: a fish body and a fish tail.  When the fish is animated, the program will display the first, second, third, and fourth frames in a looped sequence, giving the fish image an illusion of continuous motion.  This is the principle behind traditional motion pictures.

ScriptV describes this hierarchy of objects as a "nested" structure.  Each object used as a component for building a larger object is nested in the context of the description of the larger object being built.  This hierarchical structure intuitively reflects the architecture of the object’s composition.

The animated fish shown in the above figure is written in ScriptV as follows:

    object fish: AnimateFrame

    {

       object frame1: Frame

       {   object tail: Image { pixmap=("grntail11.bmp", white); }

           object body: Image { pixmap=("grnfish11.bmp", white); }

       }

       object frame2: Frame

       {   object tail: Image { pixmap=("grntail12.bmp", white); }

           object body: Image { pixmap=("grnfish12.bmp", white); }

       }

       object frame3: Frame

       {   object tail: Image { pixmap=("grntail13.bmp", white); }

           object body: Image { pixmap=("grnfish13.bmp", white); }

       }

       object frame4: Frame

       {   object tail: Image { pixmap=("grntail14.bmp", white); }

           object body: Image { pixmap=("grnfish14.bmp", white); }

       }

    }

The keywords begin and end may be substituted for curly brackets ( “{” and “}” ), if desired.

1.2.    Making a Class of Objects

An object may contain many different kinds of component objects within itself.  Some of these component objects may each be exactly the same.  For example, the cyber-aquarium may contain a great number of fish that are exactly similar.  However, repeatedly describing every fish in the aquarium with its own individual animation code can become time-consuming.

Additionally, an object may be composed with a very lengthy hierarchy.  It will be very difficult to read and maintain the code of this object if it is written in a flat style with many indentations for child components. 

Above are two compelling reasons why we need to create objects from out of a class.  A class is a template from which objects are actually made.

Writing a class code in ScriptV is very similar to writing an object code.  The main distinction between classes and objects, however, is that a class is not an object itself, but instead is only a template from which an object may be created.  An object will receive its form from its class template.

The term object creation is used to refer to the procedure of creating an object from a class. This procedure is also referred to as object instantiation, because a created object is said to be an instance of a class.

To make a class out of the fish example, we simply replace the keyword object with class:

    class Fish: AnimateFrame

    {

       object frame1: Frame

       {   object tail: Image { pixmap=("grntail11.bmp", white); }

           object body: Image { pixmap=("grnfish11.bmp", white); }

       }

       object frame2: Frame

       {   object tail: Image { pixmap=("grntail12.bmp", white); }

           object body: Image { pixmap=("grnfish12.bmp", white); }

       }

       object frame3: Frame

       {   object tail: Image { pixmap=("grntail13.bmp", white); }

           object body: Image { pixmap=("grnfish13.bmp", white); }

       }

       object frame4: Frame

       {   object tail: Image { pixmap=("grntail14.bmp", white); }

           object body: Image { pixmap=("grnfish14.bmp", white); }

       }

    }

Now, we can use this class to create a fish object by using this expression:

    object fish: Fish;

The class Fish specifies the components that a fish object should have.  These fish object components are frame1, frame2, frame3, and frame4.  Each object created from the Fish class will contain these four frames.

In the aquarium, many fish may be created by simply repeating the above expression:

    object fish_tank: Frame

    {

       object background: Image { pixmap = "aquarm1.bmp"; }

object fish1: Fish;

object fish2: Fish;

object fish3: Fish;

object fish4: Fish;

    }

There are two kinds of classes in ScriptV: Built-in Classes and User-defined Classes.

Built-in classes are predefined classes in the Visviva Animation Engine.  These Built-in classes are written in C++ and can be extended in the Visviva Authoring Engine SDK.

User-Defined classes are written entirely in ScriptV, such as the Fish class described above.  Each class written in ScriptV is stored in a separate class file.  A complete animation title can be composed of hundreds or possibly thousands of classes.

1.3.    Specifying Object Attributes

Every object will have a set of attributes.  Attributes are used to describe the various properties that differentiate individual objects.  Objects may have different shapes, images, colors, styles, sizes, positions, posture orientations, materials, textures, texts, sounds, and so on.

Additionally, different kinds of objects will have different sets of attributes.  A vector graph object, to name a single example, has the object attributes line_color and fill_color.  The attribute line_color assigns a color to the outline of a vector graph object, and fill_color indicates the color filled inside the shape of a vector graph object.

The attributes of an object are specified by attribute declarations, which are usually provided in an object's class definition.  If a class declares a color attribute, for example, then all objects created from that class would have a color attribute as well.

Following is a definition of a simple vector graph shape class:

    class VShape

    {

       line_color:  Color = Foreground;

       fill_color:  Color = null;

    }

This vector graph class contains two attribute declarations.  In each attribute declaration, the first character string (line_color and fill_color) is the name of the attribute, and the attribute name is followed by a colon.  Then the type of the attribute appears after the colon.

 

The system uses the type of an attribute to determine whether a given value is correct for an attribute.  For example, a geometric measurement cannot be assigned to the line_color attribute, because this attribute will only accept a value from the type of Color.

 

Actual values may not be assigned to object attributes during class definition.  Instead, the value of an object attribute must be assigned at the time of object creation. 

 

When creating an object, we usually have to assign specific values for some of the attributes declared in the object's class.  If a specific value is not given for certain attributes, a default value will be used.  In the above example, the default color value of the vector graph class's line_color attribute is defined as the color of the foreground of the display.  The vector graph's fill_color is defined as a default value of no (or, null) color.  Therefore, vector graph objects created from this vector graph class that have undefined line_color and fill_color attributes at the time of object creation will receive the default attribute values listed in the vector graph class definition.

 

Here's an example of creating a vector graph object and specifying new colors for the line_color and fill_color attributes:    

 

 object my_shape: VShape

 {

line_color = black;

       fill_color = red;

        }

 

1.4.    Specifying Object Functions

In ScriptV, objects are not inert.  Objects have the ability to react to user commands, such as keystrokes, or clicking the mouse. 

The interactive features of all ScriptV objects are described by object functions.  Functions are a sequence of actions an object performs in response to user interaction events.  For example, a fish can swim and blow bubbles when the mouse is clicked.  Depending on what keys are pressed, a dog can bark, jump, or wag his tail.  A button, when activated, can notify other objects to perform a given set of actions.

In ScriptV, an object function is equivalent to a member function in C++ or a method in Java.  A function provides a convenient way to encapsulate a set of actions that an object can perform.

A function has an interface that specifies a number of input parameters that are necessary to complete the function.  For instance, a Move function needs at least two input parameters: the x (horizontal) coordinate and the y (vertical) coordinate. 

The Move function of a Drawable object has an interface as following:

     class Drawable: Object

     {     

            func Move (x, y: GeoScalar);

     }

In this function, x and y are the input parameters of the Move function.  Parameters that are defined with variables are often referred to as formal parameters.

Now suppose that we have made an object out of the class Drawable, and the name of this object is my_object:

my_object: Drawable;

To write a move function that takes this object to a new position on the computer screen, the move function's actual parameters must be provided: namely, x and y.  In the example below, we're relocating this object with a move function.  Here's the code:

my_object.Move (3.45mm, 23.4mm);

This object will move a x value of 3.45 millimeters and a y value of 23.4 millimeters.

A function may also have an output specification that describes the type of objects produced (or output) by the execution of the function.  For instance, the function AbsX in

     class Drawable: Object

     {     

            func AbsX (): GeoScalar;

     }

 outputs a geometric scalar that indicates an object’s absolute x position in screen coordinates.

1.5.    Creating Objects

Objects are created by stating the name of the object, the name of the class used to create the object, and the attribute values of the object.  Then component (child) objects, as well as functions, may be added.

 

In the example below, the button3 object contains a style attribute, three child objects described by images, and an OnButtonActivate function:

 

object button3: Button

{

  object focus_image: Image {pixmap=("red_dot.bmp",white);}     //

  object active_image: Image {pixmap=("red_dot1.bmp",white);}   //

  object gray_image: Image {pixmap=("gray_dot.bmp",white);}     //

  draw_style = CursorSensitive;

    

  func OnButtonActivate()

  {

     fishtank.SetBackground ("backgrounds/underwater/scene1.bmp");

  }

}

 

This button3 object gives a button with the following images:

 

                                      This is how the button would look normally.

                                      would appear when the cursor was resting on the button, and

                             would appear when the button was pressed.

 

Additionally, the OnButtonActivate function displays a fishtank background image when the button is pressed.

1.6.    Subclasses and Inheritance

Classes, as seen so far, provide a good modular decomposition for ScriptV objects.

If that was all there was to ScriptV, however, this programming language wouldn't meet the demands of today's programmers.  Every time a new class of objects was designed, programmers would have to describe all the attributes and functions of each object in the new class.

Luckily, this isn't the case.  In ScriptV, entirely new classes may be designed by adapting the structure of previously existing classes.

Suppose that we were going to design a new frame class to make a window that displays a list of icons.  We’ll call this new frame class IconListFrame.

Assume that we already have a general frame class that defines all of a frame's necessary attributes (such as layout, attachment, display style, background description, border style, margins, spacing, alignment, etc.) and functions (resize, background change, scrolling, sliding, etc.).  Our IconListFrame will have many of the same attributes and functions of the frame class, with only a few differences.  Do we have to build our new IconListFrame class from the ground up?

No.  All we need to do is create our new IconListFrame as a subclass of the general frame class.

By using a subclass, all of a class's preexisting attributes and functions can be reused to make a new class.  To build a subclass, we only need to refer to the functions and attributes that need to be changed from the original class.

We can make the IconListFrame a subclass of the general frame class by writing:

    class IconListFrame is Frame

       /* Note: this can also be written as -- class IconListFrame: Frame */

 

The IconListFrame class will automatically inherit all of the attributes, functions and child objects that were defined in the general frame class.  In other words, since the attributes of layout, attachments, display styles, etc. have already been declared in the general frame class, the IconListFrame will also declare the same attributes, even though the attribute declaration is not actually presented in the subclass.  The purpose of inheritance, then, is to make building classes for specialized objects easier.

 

The class from which a subclass is derived is called a superclass, which is a complementary concept to subclass.  For example, if class A is a subclass of B, we can say that class B is a superclass of A. 

 

A subclass of a class usually ascribes additional features to a subset of the objects in that class.  Therefore, in addition to inheriting attributes, functions, and child objects, a subclass will often expose more attributes, functions, and child objects than its superclass.

 

What happens if a feature or features inherited from a class are not required in a subclass?  This is a common occurrence.  A superclass deals with a general topic, and a default setting or handling that is assumed by a superclass can be modified in its subclasses.  Modifying these default settings is accomplished in a subclass with the override mechanism.  By overriding, a subclass can re-declare default attribute values that were assigned in its superclass.  A subclass can also override a function that was already specified in its superclass.  When the override mechanism is used, the actual function performed will be the one that is designated in the subclass.

Return to Developer's Home Page

Copyright © 2000~2005 Visviva Software, Inc. All rights reserved.