Skip to content

Resource Handling in Flash – Part One

June 2, 2010

It’s easy to pickup ActionScript3 with a programming background in C++,/C# or Java as the languages shares the same concepts and similar syntax. So, why learn about stages and timelines, keyframes and whatnot when you can write your games like you always did? Well… almost. There are concepts in Flash that require some getting used to. Resources is one of them.

There are two fundamental different ways to get your resources loaded.

One is to embedd all the potentially needed data into your SWF file. This increases the initial loading time but once the application has fully loaded all resources are instantly available, too.

The second option is to send a lean application and load individual resources on demand. This is will reduce the initial load but making things less convenient for the coder and user.

Loading Resources on Demand

Loading individual resources when they are needed is similar to what you’d do in most local applications only that a request takes a lot longer to return the result because the data is on a server and not your local harddisk. Pausing the application while waiting for the result isn’t an option so instead you make the request and then register an event-listener to get notified when the resource has been loaded. Flash provides two classes for this task called Loader and URLLoader.

function load():void
{
    var loader:Loader = new Loader();
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
    var urlReq:URLRequest = new URLRequest(myimage.jpg);
    loader.load(urlReq);
}
function onLoadComplete(event:Event):void
{
    var myimage:Bitmap = event.target.content as Bitmap;
}

The Loader can be used for images and SWF files only. To to load binary data like XML or TXT files you use the URLLoader class instead. You access the resource using the data property instead of one named content and you usually have to do use some other classes to interpret the raw binary data. For example to load an XML file you have to pass the data as a constructor parameter to a newly created XML instances.

function load():void
{
    var loader:URLLoader = new URLLoader();
    loader.addEventListener(Event.COMPLETE, onLoaded);
    var urlReq:URLRequest = new URLRequest(myxml.xml);
    loader.load(urlReq);
}

function onLoadComplete(event:Event):void
{
    var myxml:XML= new XML(event.target.data);
}

So we see that depending on the type of resource you have to use different loading mechanisms. There is no general approach – sometimes classes even provide integrated loading. For example to load an MP3 (the only sound format natively supported) you use the load function of the Sound class which is special in the way that it allows you to start playback before the resource has fully loaded. (Streaming)

function load():void
{
    var sound:Sound = new Sound();
    var urlReq:URLRequest = new URLRequest(mysound.mp3);
    sound.load(urlReq);
    sound.play();
}

The above examples show that while it is possible to load individual resources on demand there is not one generalized approach to do so. This can make it quite difficult to integrate for large applications.

Embedding Resources

Another option is to embedd all potentially required resources directly into your SWF file. To do so you must use the [Embed] metadata tag before a variable definition of type Class. As a parameter of the [Embed] tag you specify a resource location. When your sourcecode is compiled a new class is added that represents the embedded resource and the class-variable right below the embed tag will point to it. This variable can then be used to instantiate copies of the resource.

	[Embed(source="data/music.mp3")]
	private var music_sound:Class;

	function playMusic():void
	{
		var sound:Sound = new music_Sound();
		sound.play();
	}

If you don’t provide an absolute path to the resource (starting with a drive-letter) Flex matches the path to at least 3 directories: the projects root, the source directory and the directory of the file containing the embed tag. You can not use URLs to resources.

Once a resource is located it gets transcoded and added to the SWF as a full featured AS3 class. These generated classes are called embedded asset classes and inherit from the well known base classes classes.
For example a JEPG will end up as a descendant of the Bitmap class. The only difference to the ordinary Bitmap class is that when you instantiate the embedded asset class (with the new keyword) you get a Bitmap that preinitialized with the embedded JPEG.

What kind of class is generated to represent a resource depends on file extensions.

  • JPEGs, GIFs and PNGs -> Bitmap
  • Mp3s -> Sound
  • SVG -> Sprite
  • SWF -> MovieClip
  • TTF -> Font

Note: for Fonts you need to specify an additional parameter fontFamily to be able to use it by name like any other font.

Sometimes you’ll want to embedd resources that are haven a unsupported file extension. In this case you have to specify explicitly how to transcode the file. Usually an unsupported file extension means that the file format is one that isn’t in the list above so your best option is to encode it as binary data. To do so set the mime-type parameter to ‘application/octet-stream’.

The embedded asset class created for binary data descends from the ByteArray class. So you can embedd *any* file in flash but for some you get only a very lowlevel representation. But with a bit of luck there are higher level classes available to handle it with. Remeber the example about loading an XML dynamich using the URLLoader? The same works when embedding the XML:

	[Embed(source = "some_xml.xml", mimeType="application/octet-stream")]
	private static var xml_binary:Class;

	function doSomething():void
	{
		var xml:XML = new XML(new xml_binary());
		//do stuff
	}

A quite similar process is used to embed Pixelbender shaders. And if you want to embed text files you can access the content by converting the binary data to a String:

	[Embed(source = "ramblings.txt", mimeType="application/octet-stream")]
	private static var txt_binary:Class;

	function doSomething():void
	{
		var bytes:ByteArray = new txt_binary;
		var text:String = bytes.toString();
		//do stuff
	}

This is an extensive post allready but so far I’ve only touched the basics. In the second part I list some drawbacks of these simple methods. I explain an alternative approach in which multiple resources get packed in SWFs or SWCs and linked with the main project either dynamicly or staticly. I’m also showing how to use the Flash IDE to create such resource packs because this provides better worklfow and treats like automated encoding of WAV files with support for support gap-less looping.

Advertisements

From → Tutorials

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: