"Matrix"-Style Animation: Building a Bitmap Text Engine
May 8, 2003
by Jerry McManus
Intro
While working on a game project recently I was faced with the challenging requirement of building an object oriented bitmap text display and animation system. As I began designing the animation system I realized that an excellent way to put my scripts to the test would be to recreate a visual effect that is instantly recognizable to movie fans around the globe: the 'melting text' effect seen in the movie The Matrix.
Screenshot from the movie The Matrix
Matrix Animation
The melting text animation has several key features that contribute to its distinctive look. First, and most obvious, is the appearance of the text moving vertically down the screen. This is achieved not by moving the text itself, but by making each character visible in sequence, one character after another. Essentially the same as a typing text animation. Next are the characters that randomly cycle through what appears to be a Japanese Kanji character set, although it should be noted that not all of the characters are cycling, some are static. Next is the appearance of a glowing white character at the beginning of the string as it moves down the screen. The final effect to complete the look is the appearance of strings that are of different random lengths and animating at random speeds.
It quickly becomes apparent that Director's built-in text and field members do not have the features required for this task. It is also apparent that pre-rendering the animations for a reasonably large number of random text strings would be labor-intensive, difficult to edit, and would have a negative impact on file size. Using sprites in the score for each character would be one possible solution, but it would require a very large number of sprites, and with the added overhead of blending effects, it would probably animate slowly. Fortunately there is a fast and relatively simple solution: this is a job for Imaging Lingo.
Imaging Lingo and Bitmap Text
At the heart of our Imaging Lingo solution is the copyPixels function which we will use to copy characters from a bitmap font image into a display image. The copyPixel command also has several additional features that we can use to animate color and alpha effects in our text display. The first thing we need to do is create the image that contains the character set for our animation.
This bitmap text image was created in Photoshop using, in part, a Japanese Kanji font and is arranged in such a way that all of the characters fit neatly into a 10 by 14-pixel rectangle. It's important to note that the pixels in this image are not the actual pixels that will be copied to our display image. This grayscale image will instead be used as a mask applied to a separate color image and it is the pixels from the color image that will actually be copied into our display.
This is the syntax used for the copyPixels command:
displayImage.copyPixels (colorImage, targetRect, sourceRect, [#maskImage: maskImage, #blendLevel: blendLevel])
displayImage is the image object that we are writing the char to.
colorImage is an image object that is filled with the RGB color of our text.
targetRect is the area of the display image that we are writing to.
sourceRect is the area of the bitmap font that we are copying from.
maskImage is the mask image object of the bitmap font.
blendLevel is the level of transparency.
Object-Oriented Analysis
Now that we have a method for displaying bitmap text our next task is to design a system for animating it. An object oriented analysis of the problem domain reveals that the animation of bitmap text can first be broken down into three basic objects, the Char Display, the String Display, and the Panel Display.
The Char Display object contains the information necessary for performing the copyPixels function which writes the character to the display member. The String Display object holds display properties which it uses to initialize a list of Char Display objects. The Panel Display object also has display properties which it uses to initialize the list of String Display objects.
Further analysis reveals that in addition to the display objects there is a requirement for animation objects which act as controllers and are responsible for animating the properties of their corresponding display objects. The animation objects are broken down into a hierarchy that corresponds to the display objects, consisting of a Char Animation, a String Animation, and a Panel Animation.
The final analysis results in this design for our object framework:
The Objects
Following is a brief description of some of the key methods that make up the interface to our objects:
Char Display Object
The Char Display object holds the properties necessary for writing the character to the display member.mSetSourceRect
The Char Display object uses the ASCII code of its char property to determine where in the font image its source rect is located.
mBuildImage
This method is really the heart of the display system, this is where the actual copyPixel function is performed.
String Display Object
The String Display object holds a list of Char Display objects.mBuildCharList
This method is used to build the list of Char Display objects. Each Char Display is initialized using the display properties of the String Display object.
mSetTargetRects
The String Display object is responsible for setting the target rects for its list of Char Display objects. The target rects determine where in the display image the char will be written. This method accepts a list of Char Display objects and an integer offset into the display image as parameters.
Panel Display Object
The Panel Display object holds a list of String Display objects.mBuildStringList
This method is used to build the list of String Display objects. Each String Display object is initialized using the display properties of the Panel Display object. These properties are first set in the mInitialize method of the Panel Display object.
Char Animation Object
The Char Animation object holds a Char Display object.mInitializeAnim
This method is used to reset key animation properties without having to re-initialize the entire Char Animation object.
mAnimate
This method uses the animState property to determine which Char Display object properties to animate. The #start state sets the mask image and blend level of the character display. The #glow state checks the glowDuration property and then resets the mask image and blend level properties. The #cycle state chooses a random ASCII code and sets the Char Display objects source rect property.
String Animation Object
The String Animation object holds a list of Char Animation objects.mInitializeAnimList
This method is used to reset key animation properties without having to re-initialize the entire String Animation object.
mAnimate
This method uses the displayState property of the Char Animation object to determine if the animation has been completed. If true then the String animation reinitializes the Char Animation object and begins a new animation cycle. This method then calls the mAnimate method for each Char Animation object that has a displayState of true.
Panel Animation Object
The Panel Animation object holds a list of String Animation objects.mAnimate
In this method the Panel Animation object uses a timeOut object to drive the String Animation objects and, in turn, the Char Animation objects. The timeOut object is set to call this method every 50 milliseconds, equivalent to 20 frames per second. When this method is called it uses it's frameList property to initialize a new random String Animation object and then calls the mAnimate method for each String Animation object that has a displayState of true.
The Demo
Here is a demo movie of our finished bitmap text display and animation system:
Click anywhere in the display to start, or restart, the animation.
The Director 8.5 source for this movie is available in ZIP and SIT archive formats.
Conclusion
And there you have it, a Hollywood-style text animation that would be very difficult to accomplish using standard text and field members, or even using standard sprites in the score, but with the power of Imaging Lingo this complex, random, non-repeating animation uses one sprite and only half a dozen script objects.
On a final note, it should be pointed out that the scripts representing the animation objects in the demo movie were designed specifically for the melting text animation. With a little imagination, however, the enterprising developer could greatly expand this system to include a wide variety of different animated text effects.
"There is no spoon."- from the movie The Matrix
Copyright 1997-2024, Director Online. Article content copyright by respective authors.