Learning Actionscript 3 Graphics

This is a continuation of my exploration of Flash. I am trying to document my learning process so that I can formalise and improve upon the way I learn.

At first when I tried to understand graphics in AS3 I was a little confused – the issue was further confused by the fact that there are two schools of thought: One that uses Flash’s retained-mode display model and the other creates an immediate-mode surface, in the form of an off-screen image buffer, on top of the Flash’s built-in display model. Here are some examples of immediate-mode style graphics in flash: example1, example2; note that they no-one seems to use the retained/immediate terminology just blitting & double buffering. I focused my efforts on the built-in model because it formed the basis of the immediate-mode approach. Perhaps I will revisit which I think is best in future but for now I will focus on the graphics using just the built-in features. But I found an article that compares the two approaches (here) and a discussion at OSFlash (here).

I  focused on Actionscript 3.0 in my brief exploration of the graphics system. I found that basically in flash, you cannot draw directly on the screen. However, you have access to a tree like structure, which is similar to a scene-graph. The root of this structure is called the stage. It contains a number of display objects which have a visual representation, like a bitmap or vector graphic, that is displayed on the screen. The stage also contains display object containers, which can have their own visual representation, but also have the ability to contain a number of child display objects. The Flash player draws the stage and all its children and its children’s children and so forth at a frame rate capped by the you. This was a slight paradigm shift sense I expected the API to expose a drawing canvas of sorts, something along the lines of what you get in the GDI, XNA SDL etc… I used the official documents(here) as the main source of information on the display model.

Another interesting thing I found out was that the z-order of display objects is determined by the order in which they were added to their parent display object container. Basically, the the display object added last is displayed first. The order in which display objects are added is maintained. FlashGameU gives a good explanation (in the form of a streaming video tutorial) of how to control the z-order of the display objects (here).

Now that I had an understanding of the display model, I wanted to try to display something onto the screen. Initially, I tried to display vector graphics which I found required access to a graphics object which is only available to Sprite/Shape classes ( the core display classes are explained here ). So to gain access to the graphics object I identified two approaches, we could descend from the Sprite/Shape class or by instantiating a Shape/Sprite and directly accessing the graphics property. The vector graphics were created by calling the drawing commands of the graphics object. When learning a library/API/technology, I like to try to create the simplest example possible and then build from there to create more complicated applications of the library/API/technology. I found that the official language reference documents (here) on the graphics class were very helpful.

package
{
 import flash.display.DisplayObject;
 import flash.display.Sprite;
 import flash.events.Event;

 
 //sets the width, height and background colour of the stage
 [SWF(width=600, height=400, backgroundColor=0xDFEEEF)]
 public class Main extends Sprite
 {
  
  public function Main():void
  {   
   //Set the line style to 1 pixel thickness, and black colour.
   graphics.lineStyle(1, 0);
   
   //Set the fill colour to light blue
   //this must be called before we can draw shapes.
   graphics.beginFill(0xffff);
   
   //Create a circle, centred at (100,00) with a radius of 20 pixels.
   graphics.drawCircle(100, 100, 20);
   
   //Called to notify the graphics object that we are
   //finished drawing shapes.
   graphics.endFill();
  }  
 } 
}
zip file

Something neat about the built-in display model, basically a scenegraph, is that that local coordinate system of a display object are dependant on the coordinate system of its parent. So if the parent is rotated 10degrees then so is then the child’s coordinate system is rotated 10degrees. The display object’s coordinate system can be transformed by changed by adjusting the display object’s properties, x, y, scaleX, scaleY and rotation (doc files here). 

In comparison to vector graphics I found displaying bitmaps is a simpler affair. Especially if the bitmap is embedded into the AS3 file – alternatively the bitmaps could have been loaded from a URL, I focused on the embedding approach. That being said I found some leads for future research if I ever I need to dynamically load some flash (lead1 & lead2). Here is a simple example I wrote of displaying a bitmap on screen.

package
{
 import adobe.utils.ProductManager;
 import flash.display.Bitmap;
 import flash.display.Sprite;
 import flash.events.Event;
 public class Main extends Sprite
 {
  //embeds 'image-sample.png' into the swf file
  //and creates a class "ImageSample" which
  //contains the embedded data.
  [Embed( source = 'image-sample.png' )]
  private var ImageSample : Class;
  
  public function Main():void
  {
   //instantiates the embedded data class,
   //which inherits from flash.display.Bitmap
   var bitmap : Bitmap = new ImageSample();
   
   //adds the bitmap to the main class so that it
   //will be displayed.
   addChild( bitmap );
  }  
 } 
}
zip file

Having coded in a couple of different APIs, OpenGL being one, I found it nice to be able to quickly and easily get access to content (here is one of the resources I found on embedding content and an official link here which I found gave a little more depth).

 That was what I found out to be the basics of flash’s display model. Next time I will focus on getting input from the AS3.

Tags: , , , , , ,

Leave a Reply