Monday, December 8, 2008

Visual objects

Flash supports a number of built-in visual objects. Nevertheless, the number of varieties is limited, that's why in most cases needed elements, e.g. Graphic User Interface, are created by combining a few standard objects. All the standard objects are defined in DefineXXX. They are: Shape, MorphShape, Static Text, Dynamic Text, Button, Video and Sprite.

Pay attention to the fact that there is no Image object. To display an image, it must be used as a fill for rectangular shape.


Unique CharacterID

Each visual object has its own unique CharacterID – a number of the word type, i.e. value between 0 and $FFFF. If you create object by yourself, you have to ensure its uniqueness. Uniqueness is needed to let player definitely understand what object to use at processing tagPlaceObject.

When it's needed to combine a few SWF, the first task is to ensure the uniqueness of these CharacterIDs, otherwise some objects won't be displayed. To do that, it's necessary to redefine all values in one SWF by changing existing values to values which is known to be free.


Objects names

As I've mentioned before, object name is set in tagPlaceObject, it's obligatory to specify CharacterID here. It's possible to create a few copies of one object with different names. Again, at combining two SWFs, it's necessary to ensure names uniqueness. As a rule, names are used in ActionScript for managing these copies, that's why in case of renaming objects it's necessary to make corresponding corrections in ActionScript.

Monday, November 17, 2008

Frame, scene or display list

As I said before, the displaying happens when there is a ShowFrame tag in SWF. To display a visual object, one should at first describe it (DefineXXX tags), and then place it on a needed depth with the help of PlaceObject tags. One object can be placed many times, so we have cloning effect. Depending on PlaceObject tag parameters, the instances of a visual object can look absolutely different. The instances are displayed until they are forcibly removed by RemoveObject tag. That allows to determine, place and remove instances of objects in different frames.

Looking at this scheme, one can answer the question what objects are displayed in what frame – one have to make a list of all PlaceObject before the current frame and except those ones which were removed by RemoveObject tag. One should also take into account that PlaceObject can have a flag PlaceFlagMove which indicates that the occupied depth must be cleared, i.e. it's analogous to RemoveObject in one tag.


PlaceObject review

It's the main tag used to indicate what object, where and how should be displayed. As the SWF format was developed, additional parameters were added to this tag. Now there are three "editions": tagPlaceObject, tagPlaceObject2 and tagPlaceObject3.

Key parameters:

  • Depth – the depth where an object is placed. The lager the value is, the "higher" an image is. As this parameter can't be more than 2 bytes, the maximum value is 65535. To be displayed correctly, there shouldn't be other objects on a depth, otherwise one have to set PlaceFlagMove as true.
  • CharacterId – identifier of an existing object.
  • Name – name of object instance. It can be used in ActionScript for programming animation and interactivity.
  • Matrix – the group of parameters for geometric transformation. It includes TranslateX and TranslateY to indicate position (nought in the top left corner), ScaleX and ScaleY for reducing or enlarging, SkewX and SkewY for bevels and rotations.
  • ColorTransform – the group of parameters for color transformation. It includes addR, addG, addB and addA for changing color components by adding specified values; multR, multG, multB, multA for changing color components by multiplying them by specified values.

By setting different parameters in different frames, we have animation. For instance, by changing Translate value, one can create movement. By changing addA or multA, one creates appear and disappear effects.

Wednesday, October 29, 2008

SWF TimeLine

Flash player plays SWF by frames. This happens when flash player "meets" tagShowFrame, i.e. no changes in animation can be seen without this tag. Frame rate is specified in file title as FPS value. The summary duration of playing SWF can be calculated by multiplying the number of frames by FPS (Frames per Second) value.

This is theory, but in practice everything is much more difficult and that's why.

The matter is SWF can be not a simple movie, but a complicated logic script with interactivity elements. Frames can be changed in whatever sequence, including the one with stopping on a frame to wait user reaction. In fact, such SWFs are web applications.

Besides, in a movie, one can use special objects Sprites, in terms of Flash IDE they are called MovieClips. Sprites have the same structure as SWF (a set of tags) and their own timeline. There are SWFs with only one SWF frame where all the animation takes place in sprites.

And the last. Sometimes flash player can't prepare frame for playing in time. As a rule, this happens when there is a transformation of images or superposition of multiple masks in a frame. In this cases, frames are changed obviously more seldom than it's specified in FPS.


Conclusion. In most cases it's IMPOSSIBLE to determine duration of SWF. In most cases it's IMPOSSIBLE to scroll SWF for example to the third frame if you don't know movie structure and script. In most cases it's IMPOSSIBLE to know if an SWF finished playing, because "the action" can take place not in the main timeline, but in sprites.

Friday, October 24, 2008

Introduction. SWF structure.

I think everybody knows that awkward situation when you're asked a "wrong" question because the person who asks knows nothing about the topic. It's difficult to understand what to start answer from in such a situation. That's why I'll begin... at the very beginning.

Introduction

When saying Flash, we can mean absolutely different things even within the bounds of web-technology terms. Not to get confused, I'll use the following terms:

  • Flash – the technology of web-animation on the whole;
  • Flash player – program, ActiveX library which displays flash;
  • Standalone Flash player – application (exe file) displaying flash;
  • Flash IDE, Adobe Flash, Flash Professional – development environment provided by Adobe Systems (former Macromedia);
  • FLA – project (source) animation file for Flash IDE;
  • Movie – an integral web-animation at the development stage;
  • SWF – result animation file.
  • So, when loading a web page with flash animation, the following processes take place: web-browser detects an embedded flash animation in an HTML markup, creates and object of flash-player and indicate what file needs to be displayed. Flash player loads SWF file and begins to display it if possible. Due to this principle of work, flash player can display so called preloaders, reproduce streaming audio and video (for example, YouTube) without loading SWF fully.

    SWF structure

    File format is described in "SWF file format specification" document, which can be downloaded at Adobe.com. Documentation is usually issued some months after the release of a new version of flash player. At the moment, flash player v.10 is already released, but specification document is not renewed and contains specification of version 9. One can find specifications about almost everything I explain here, but the matter is that "almost", but not everything :)

    Basic structure of SWF doesn't depend on version, that's why SWF always has Header+Body structure. Body consists of records which are called tags in specification.

    To describe data structure, I'll use Object Pascal syntax.

    Header

    Header contains main information about SWF. It can be described in this way:

    TSWFHeader = packed record
    SIGN: array [0..2] of AnsiChar;
    Version: byte;
    FileSize: LongWord;
    MovieRect: TRect;
    FPS: word;
    FramesCount: word;
    end;

  • The first parameter is SIGN. CWS value means that this file is packed using ZLib compression method, not an FWS.
  • Version – version of file format.
  • FileSize – size of UNPACKED file in bytes.
  • MovieRect – size of displayed image in twips (1px = 20twips). I should note that in fact SWF and graphic objects can't be larger than $ffff/ 20 = 3276 px. I haven't seen swf with top-left value less or more than 0. Nevertheless, having set these values in my tests, I made sure that these values are really taken into account. It's worth noting that the specified rectangle is a place given by browser. When opening SWF in a standalone player, sometimes one can see "decorations behind the scenes".
  • FPS (frames per second) – value in format 8.8 fixed, i.e. for human perception this value is Result := FPS shr 8 + (FPS and $FF) / ($FF+1);
  • FramesCount– frames number. As a rule, SWF always has at least one frame, but it's possible to create SWF without frames if this file is used as a library for other SWFs.
  • SWF compression

    To reduce file size, Macromedia has used two approaches.

    The first one consists of that bit-by-bit compression method is used for saving numbers. It looks like this. Let's presume we need to save a size of rectangle, i.e. four numbers of integer type. At a simple record it will be 4 * 4 bytes = 16 bytes. At recording to SWF, the number of bits needed for coding the largest value is recorded to the first 5 bit, and then these 4 values in bit representation with a specified bit length. For example, it's necessary to save coordinates (0,0 – 100, 100) or in twips (0,0 – 2000,2000). In bit representation number 2000 = 11111010000 (11 bit + 1 for a sign). We have (5 + 4 * 12) / 8 = 7 byte (almost 2 times less). This approach leads to the fact that some identical tags can have different size. It also applies to Header.

    The second approach is using ZLib compression method both for the whole SWF and for separate tags.

    When a file is compressed, first three parameters of a Header (8 bytes) are not compressed, but the rest are compressed. This explains why it's impossible to read an SWF header only with one read method.