| Register
Friday, January 05, 2007   

ActionScript 3.0 Display Lists and Display Objects

Created By  Tibor Gyorgy Ballai, at  11/25/2006 - 1 comments.

One of the biggest changes in ActionScript 3.0 is the way Flash renders (or rather manages rendering of) visual assets. Previously, you'd had to attachMovie() from the library, createEmptyMovieClip() or createTextField(). But all of these were methods of existing movie clips. So if you wanted to create a new visual asset, you had to start with a defined movie clip and that asset would be bound to that clip until it was destroyed. It would also automatically be added to the rendering engine. So, if you wanted to create a new MovieClip on the root and then drag and drop it into another MovieClip (say a window that you could drag around), you'd have to remove the MovieClip from its origin and recreate it in the target.

On top of this, there was the issue of depth management. MovieClip.getNextHighestDepth() helped depth management, but if you were using v2 components, getNextHighestDepth() often conflicted, creating headaches that I'm not going to rehash here.

Thankfully, the way Flash handles rendering in ActionScript 3.0 addresses all of these issues. It now uses what's called a Display List and DisplayObjects. The root of any ActionScript 3.0 application is a DisplayObjectContainer, and within that DisplayObjectContainer, you can add DisplayObjects or other DisplayObjectContainers (something that can contain child DisplayObjects). At the same time, you can create DisplayObjects that exist as data objects but are not necessarily added to the Display List and therefore are not even considered by the rendering engine. This means if you have something like a slide show, you may have 100 Bitmap DisplayObjects, but are only showing one or two at a time, saving resources as the rendering engine only has to consider the objects currently in the Display List. Also, at any point, you can re-parent (change the scope of a DisplayObject) by adding it as a child of another DisplayObjectContainer. Best of all, the Display List pretty much makes depth management a thing of the past.

So, that was a lot of words. What does it mean in practice? Well, we still have a stage, and the stage is still the root of the display hierarchy. You can refer to the stage from any DisplayObject by referencing it's “stage” (lowercase 's'') property.

DisplayObjects can be things that contain no child DisplayObjects (such as a Bitmap, a Shape, Static Text, Video and a MorphShape). This means that if you need nothing but to display a Bitmap or a simple vector shape, you don't have to create a MovieClip (and all the resources a MovieClip requires) just to display a graphic. But DisplayObjects can also be Interactive Objects like SimpleButtons TextFields and DisplayObjectContainers. Among DisplayObjectContainers are the objects that can contain child DisplayObjects such as Loader, Sprite and Stage. On the bottom of the hierachy is the resource heavy, but familiar MovieClip. The chain of inheritance among DisplayObjects looks like this:

The DisplayObject isn't intended to be instantiated directly. It's the base class that everything else extends. So, you're likely to start by choosing to create objects like a Bitmap (which can display BitmapData). Bitmaps are cool because when you apply BitmapData to them, if that BitmapData changes, the visual Bitmap will automatically update. When you just need to draw a shape, but don't need to interact with it, the light weight Shape or MorphShape are perfect choices. StaticText is perfect for labels and Video is perfect to display FlashVideo that the user won't be directly interacting with.

InteractiveObjects include support for user interaction. So you may choose a SimpleButton, which works essentially like Flash Buttons (with an Up, Over, Down and Hit state) in previous versions of Flash. And TextFields are much like old TextFields, used for user input or HTML interaction.

DisplayObjectContainers are capable of adding additional DisplayObjects, like a loader, which you would use to load external visual assets (like SWFs or graphics), Sprites which are similar to Shapes, but are capable of containing other DisplayObjects as children and the Stage.

Finally, there is the MovieClip which is the heavy hitter we've been using for years. It has a timeline, can draw graphics, load external assets. It basically does everything MovieClips were capable of in previous versions of Flash. It's much like a sprite, but has the capability to control the play head. In most cases, you won't need all the power (and the overhead that comes with it) of the MovieClip, but its the most robust of the DisplayObjects.

Like I mentioned before, a DisplayObject can be created, but doesn't necessarily become displayed visually until it's added as a child of a DisplayListContainer. For example, lets say we want to create a Shape (in this case a circle) and show it on the stage. We can create an ActionScript Project in FlexBuilder2 called “CircleShape” and use the following code:

package {
	import flash.display.Sprite;
	import flash.display.Shape;

	public class CircleShape extends Sprite
	{
		public function CircleShape()
		{
			var myCircle:Shape = new Shape();
			myCircle.graphics.beginFill(0xFF, 1);
			myCircle.graphics.drawCircle(40, 40, 20);
		}
	}
}

We created a new Shape. It should be a blue circle, but if you test the application you'll see this:

Where's our circle? Well, we created it, but we didn't add it to the Display List as a child of the stage. If we add one more line of code:

package {
	import flash.display.Sprite;
	import flash.display.Shape;

	public class CircleShape extends Sprite
	{
		public function CircleShape()
		{
			var myCircle:Shape = new Shape();
			myCircle.graphics.beginFill(0xFF, 1);
			myCircle.graphics.drawCircle(40, 40, 20);
			addChild(myCircle);
		}
	}
}

Now we can see our circle rendered on the stage. addChild(myCircle); puts our shape onto the DisplayList of the stage and puts it in order to be rendered on the screen visually.

Now, let's try to put another circle inside our existing circle. We can create a new circle and try to add it as a child to our existing blue circle with this code:

package {
	import flash.display.Sprite;
	import flash.display.Shape;

	public class CircleShape extends Sprite
	{
		public function CircleShape()
		{
			var myCircle:Shape = new Shape();
			myCircle.graphics.beginFill(0xFF, 1);
			myCircle.graphics.drawCircle(40, 40, 20);
			addChild(myCircle);
			
			var myCircle2:Shape = new Shape();
			myCircle2.graphics.beginFill(0xFFFF00, 1);
			myCircle2.graphics.drawCircle(40, 40, 10);
			myCircle.addChild(myCircle2);
		}
	}
}

As soon as we save the file, FlexBuilder2 will highlight line 17 as an error.

It will also give us a compile time error, because we're trying to add a child to a Shape. And a Shape is not a DisplayObjectContainer and is not supposed to contain child DisplayObjects.

But if we change myCircle from a Shape to a Sprite (which is a DisplayObjectContainer and can contain children) with the following code:

package {
	import flash.display.Sprite;
	import flash.display.Shape;

	public class CircleShape extends Sprite
	{
		public function CircleShape()
		{
			var myCircle:Sprite = new Sprite();
			myCircle.graphics.beginFill(0xFF, 1);
			myCircle.graphics.drawCircle(40, 40, 20);
			addChild(myCircle);
			
			var myCircle2:Shape = new Shape();
			myCircle2.graphics.beginFill(0xFFFF00, 1);
			myCircle2.graphics.drawCircle(40, 40, 10);
			myCircle.addChild(myCircle2);
		}
	}
}

We get our bullseye!

Conclusion

The Display List and the variety of DisplayObjects are probably the biggest change to get used to in ActionScript 3.0, but once you get a handle on which tool is appropriate for the problem you want to solve, you'll find that it's actually much easier than the old way of attaching MovieClips and trying to manage depths.

Depth management is pretty much built in. In the coming weeks we'll be writing more about adjusting depth of particular objects in the display list. But the ability to load/create DisplayObjects as data objects that can be applied (and removed) as children to DisplayObjectContainers and then applied to other DisplayObjectContainers means that you can load or create visual assets and work with them in a much more dynamic way than you could in previous versions of Flash.

You no longer need to create a MovieClip within a particular scope. You can create a library of DisplayObjects and apply them to the Display List as needed without having to destroy and recreate them in various scopes.

With all of the new capabilities of ActionScript 3.0, we plan to release continually more granular tutorials on a regular basis. So, please come back and see more specific information and participate in the discussion in the comments and our forum.

Recent Articles by  Tibor Gyorgy Ballai

Need Professional Help For Your ActionScript Project?
ActionScript.com Consulting Services provide top quality professional ActionScript consulting to businesses around the globe. If you have a professional project in need to world-class talent, tell us about your project by requesting a quote today.

Reader Comments

  1. Kingda Sun  Replied:
    ( 1/1/2007 At 9:45 PM)

    quote:
    "When you just need to draw a shape, but don't need to interact with it, the light weight Shape or MorphShape are perfect choices. StaticText is perfect for labels and Video is perfect to display FlashVideo that the user won't be directly interacting with.
    "
    There are some little mistakes. ActionScript 3 cannot access or create the instances of MorphShape and StaticText. They can only be created through the Flash Authoring Tool.(I mean, Flash 9 or Flash CS3)

Login to post your comments. If you do not have an account with us please Register.
Copyright 2005 by ActionScript, Inc.   |  Privacy Statement  |  Terms Of Use  |  ActionScript Client Extranet