ActionScript 3 Standard Library Primer

Warning! Some information on this page is older than 5 years now. I keep it for reference, but it probably doesn't reflect my current knowledge and beliefs.

20:15
Thu
08
Apr 2010

ActionScript 3 Standard Library Primer

I've recently blogged about the syntax of ActionScript 3 language. Today I'd like to present what I've learned about the Flash standard library, especially in terms of displaying graphics. The official documentation to this is avaiable as ActionScript 3.0 Language and Components Reference (offline version for download - multipage HTML packed in ZIP).

Main package for graphics-related classes is flash.graphics. When programming in Flash, you do not redraw whole screen every frame like you do in DirectX or OpenGL. Instead you create a persistent hierarchy of objects, change their parameters and they are automatically drawn and updated. Base class of all objects that can be placed in this hierarchy is flash.graphics.DisplayObject and the class that can have children (the composite design pattern appears here) is DisplayObjectContainer. DisplayObjectContainer has methods such as addChild or removeChild to manage subobject.

For example, knowing that Sprite class that is the base class of our Main class inherits from DisplayObjectContainer and the TextField class we use here inherits from DisplayObject, the simplest Flash application that shows anything may look like below. The display object hierarchy here is: main object of the Main class with the tf object of TextField class inside, added as a child.

package
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.text.TextField;
  
  public class Main extends Sprite 
  {
    public function Main():void 
    {
      if (stage) init();
      else addEventListener(Event.ADDED_TO_STAGE, init);
    }
    
    private function init(e:Event = null):void 
    {
      removeEventListener(Event.ADDED_TO_STAGE, init);
      
      var tf:TextField = new TextField();
      tf.text = "Hello World!";
      addChild(tf);
    }
  }
}

Each DisplayObject has number of interesting properties that control its appearance. First, there is of course its position (controlled by properties x, y), its scaling (scaleX, scaleY) and orientation (rotation as a Number expressed in degrees - remember we do 2D graphics here!).

The scale9Grid property is a great invention that could help to conveniently control of displaying images with the inner area stretched after scaling while some border remains fixed width. If only it worked with bitmaps... but unfortunately it doesn't :(

Flash supports alpha-blending and alpha is a 0..1 number separate from colors. There is also the blendMode enumration property that has many useful values, like ADD, SUBTRACT, DIFFERENCE, MULTIPLY, SCREEN, OVERLAY, LIGHTEN, DARKEN and more.

You can also set transform property of a DisplayObject to some object of flash.geom.Transform class. A transform combines affine 2D transform (merged into a 2x3 matrix of class flash.geom.Matrix) with colorTransform of class flash.geom.ColorTransform (that represents linear transformation of the colors of all pixels by some x2 = x1 * multiplier + offset, where x are ARGB components).

Still that's not all! DisplayObject has also filters property that can be set to an array of filters, each represented by an object of one of the classes derived from flash.filters.BitmapFilter. These filters can add some interesting effects to objects without forcing you to prepare them offline as bitmaps. They actually resemble a bit the effects that can be applied to layers in Photoshop. Of course you do not write per-pixel processing routine by yourself (it would have no chance for good performance - ActionScript is a scripting language :P), so here is the list of ready effect classes available: BevelFilter, BlurFilter, ColorMatrixFilter, ConvolutionFilter, DisplacementMapFilter, DropShadowFilter, GlowFilter, GradientBevelFilter, GradientGlowFilter.

Here is how I've made a WoW-like button procedurally, by drawing black rounded rectangle and applying two filters to it:

var s:Shape = new Shape();
addChild(s);
s.x = 16;
s.y = 16;
s.graphics.beginFill(0x000000, 1);
s.graphics.drawRoundRect(0, 0, 96, 24, 8, 8);
s.graphics.endFill();
s.filters = [
  new BevelFilter(3, 45, 0xE0E0E0, 1, 0x808080, 1, 2, 2),
  new GlowFilter(0xFFFF00, 1, 4, 4, 3)
];

There are two foundation classes that derive from DisplayObject. flash.display.Shape class is more lightweight and inherits directly from DisplayObject. flash.display.Sprite class inherits from DisplayObjectContainer, so it can also have child objects. Both classes have the graphics property of type flash.display.Graphics, which is a canvas where you can draw some vector graphics. Again, you do not have to do it every frame. Things you draw remain on the screen until you call clear method. Graphics class is very powerful. Its methods for drawing shapes are: drawRect, drawRoundRect, drawCircle, drawEllipse, moveTo, lineTo, curveTo. But the real power lies in parameter richness of methods for setting line and fill style. We have the lineStyle method (8 parameters) and lineGradientStyle (8 parameters), as well as beginFill (2 parameters), beginBitmapFill (4 parameters) and beginGradientFill (8 parameters). I won't go into details here about how gradients are represented in Flash, but it's definitely worth seeing.

Between DisplayObject and DisplayObjectContainer classes there is an flash.display.InteractiveObject class, that has nothing to do with graphics. It exists there so every DisplayObjectContainer class (like Sprite or TextField) can handle mouse and keyboard input. The class dispatches many events, e.g. mouseDown, mouseUp, mouseMove, mouseWheel, mouseOver, mouseOut, keyDown, keyUp. As we talk about events, each DisplayObject also dispatches an enterFrame event that can make some code executed every frame.

It looks like the root of all display objects is an object of class flash.display.Stage. Each display object that has already been added as a child to the hierarchy has a reference to it as its stage property. The stage object can be useful to obtain some of the "environmental" values like stageWidth, stageHeight and frameRate.

Obviously there is not only the vector graphics available in Flash, but also loading and displaying of bitmaps. Some standard bitmap file formats are available for loading like JPEG and PNG. A bitmap can be loaded from the Web or embedded into the SWF file. A particular instance of a bitmap displayed on the screen is an object of the flash.display.Bitmap class, derived from DisplayObject. The smoothing property controls whether Flash applies some filtering to the rendered pixels. Here is an example:

[Embed("c:\\WINDOWS\\ServicePackFiles\\i386\\nextover.jpg")]
  private static const m_BitmapClass:Class;

private function init(e:Event = null):void 
{
  removeEventListener(Event.ADDED_TO_STAGE, init);
  
  var bmp:Bitmap = new m_BitmapClass();
  addChild(bmp);
  bmp.x = 16;
  bmp.y = 16;
}

The actual bitmap pixels lie inside an object of flash.display.BitmapData class. You can manipulate these data by using methods of this class like applyFilter, colorTransform, copyChannel, copyPixels, fillRect, getPixel, setPixel and some other.

When it comes to manipulating binary data on the byte and bit level in Flash, it is possible, although I'd be afraid of the performance of such operations. Data can be downloaded from an URL with flash.net.URLLoader class or flash.net.URLStream class and stored in the memory using flash.utils.ByteArray class. Access to the data is made the way similar to Java, C# and other high level languages that have no pointers. So we have the flash.utils.IDataInput and flash.utils.IDataOutput interfaces with methods like readByte, readInt, readDouble, readUTF (for strings), writeByte, writeInt etc. We can create bitmaps pixel-by-pixel this way by using getPixels and setPixels methods of BitmapData class.

Rendering some graphics onto bitmaps (something like render targets known to DirectX programmers) is also possible in Flash. BitmapData's draw method can render onto a bitmap anything that implements the flash.display.IBitmapDrawable interface. It is very powerful as this interface is implemented by BitmapData as well as DisplayObject classes.

When it comes to math and geometry needed for doing graphics, Flash offers some classes from the flash.geom package: Matrix, Point and Rectangle. Matrix represents 2x3 affine transform. All geometric quantities are of type Number, which is internally a double-precision float.

Flash is also capable of displaying text. There is one almighty class for this called flash.text.TextField. It can serve as a simple text label, as well as an input box (it can handle user input with selecting and editing text) or a scrollable, multiline control with formatted hypertext inside (the htmlText property accepts strings with kind of HTML subset).

Comments (0) | Tags: flash rendering | Author: Adam Sawicki | Share

Comments

(No comments)

Post comment

Nick *
Your name or nickname
E-mail
Your contact information (optional, will not be shown)
Text *
Content of your comment
Calculate *
(* - required field)
STAT NO AD [Stat] [Admin] [STAT NO AD] [pub] [Mirror] Copyright © 2004-2017 Adam Sawicki
Copyright © 2004-2017 Adam Sawicki