Embedding Resources with AS3

ref: http://www.bit-101.com/blog/?p=853

Someone recently asked about “code injection” using AS3. Code injection comes from MTASC, where the byte code is added to an existing SWF. The person wanted to create a Flash 9 SWF with the Flash 9 AS3 preview IDE, and use mxmlc.exe to inject code into it.

This is not possible, but there are some equally powerful alternatives using embedding in AS3. As this whole AS3 thing is fairly new to many, I thought I’d explore it a bit and post some info.

Using the AS3 compiler, you obviously don’t have a library for storing movie clips, graphics, text field, bitmaps, etc. So how do you get these into a SWF? Using the Embed tag. Here’s how that looks:

[as]
[Embed(source="assetname")]
private var AssetClass:Class;
[/as]

Here, “assetname” would be the path to a file, usually a bitmap or a SWF. For example, to embed a bitmap named “picture.jpg” in your SWF, do something like:

[as]
[Embed(source="picture.jpg")]
private var Picture:Class;
[/as]

Now Picture represents a class that you can create an instance of, like so:

[as]
var pic:Bitmap = new Picture();
[/as]

Notice that because you imported a bitmap, it ends up as type Bitmap.

That’s pretty cool, but importing assets from SWFs is even more powerful. In fact, you can even import Flash 8 SWFs, though you’ll only get the graphic assets in them.

You can embed SWFs two ways, just like the bitmap example above where you embed the whole thing, or you can target a particular library asset from the SWF to embed. The latter is obviously much more powerful. Here’s the syntax for that:

[as]
[Embed(source="library.swf", symbol="linkageID")]
private var AssetClass:Class;
[/as]

Here, “library.swf” is the name of the SWF holding your assets, and “linkageID” is, you guessed it, the linkage ID of the particular asset you want to embed in your new SWF. AssetClass is again the name of the class that will be associated with that asset.

To try it create a new Flash 8 file and save it as “library.fla”. Create a few shapes on the stage and convert each one to a movie clip, exporting it for AS. I saved mine as “star”, “square” and “circle”. You don’t need to leave the symbols on the stage. As long as they are in the library and exported, you are fine.
Inside the star movie clip, I made a tween that just spun the star around.

Inside the square movie clip, I put the code:

[as]function onEnterFrame()
{
_rotation += 5;
}
[/as]

Then, publish this movie, so it creates “library.swf”.

Now create a new AS3 class, like the one below:

[as]
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;

public class App extends Sprite
{
[Embed(source="library.swf", symbol="star")]
private var Star:Class;

[Embed(source="library.swf", symbol="square")]
private var Square:Class;

[Embed(source="library.swf", symbol="circle")]
private var Circle:Class;

public function App()
{
init();
}

private function init():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align=StageAlign.TOP_LEFT;

var star:Sprite = new Star();
addChild(star);
star.x = 100;
star.y = 100;

var square:Sprite = new Square();
addChild(square);
square.x = 200;
square.y = 100;

var circle:Sprite = new Circle();
addChild(circle);
circle.x = 300;
circle.y = 100;
}
}
}
[/as]

Save this in the same directory as the library SWF, and compile it with mxmlc. When you do so, you’ll get a warning that the ActionScript in the square symbol is AS2, and will be ignored. (I just put it there to prove a point. If you believe me, you can leave it out.)

When you open the new swf, you’ll have your three symbols sitting on stage. The star will be tweening around, but the square won’t move, as its AS2 code was ignored.

Note that you don’t have to import all the assets from the library. You could have a large library SWF with hundreds of elements, think skins, which you could import whichever ones you needed and leave the rest behind. Only the ones you chose would get compiled into your SWF.

Of course, you can also create a Flash 9 SWF with the new AS3 preview IDE, and import assets from it in the same way. And, since those assets could include AS3 timeline code in them, you could actually have the code come along with them. But if you are coding apps in AS3 and embedding resources from external library SWFs, you are probably not the kind of developer who writes timeline code, and you wouldn’t likely want that coming into your nicely organized code base anyway, so for the most part, you are using the SWF to import visual elements only, so it really doesn’t matter whether it’s Flash 8 or 9.

Another big advantage to using Flash 8 for this purpose, at least if you are using FlashDevelop, is that when you add the library SWF to your project, you can actually expand it and see what exported assets are in it, and double click on them to add the linkage name directly to your code. (FlashDevelop cannot currently decompile a Flash 9 SWF in this way.)

I’ve created some sample files if you want to test this out yourself:Embedding.zip

(It’s created as an Ant-based FlashDevelop project, but you can ignore everything but the Flash files in the src dir if you use something else.)

ps. If anyone knows how to get proper indenting using iG syntax highligher in WordPress 2.0, let me know.

posted on 2010-12-07 17:35  Tobin  阅读(364)  评论(0编辑  收藏  举报

导航