Embedding Resources with AS3

Aug 18 2006 Published by under Flash

Send to Kindle

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.

Send to Kindle

78 responses so far. Comments will be closed after post is one year old.

  • [...] Embedding Resources with AS3 This entry was posted on Tháng 12 10 2010 Original post: http://www.bit-101.com/blog/?p=853 [...]

  • kp says:

    An important concept that I may not have pointed up enough is that these assets are COMPILED IN to your SWF – at COMPILE TIME. They are NOT loaded in at run time. They are NOT in a runtime shared library. This means:

    1. You don’t need to deploy the library.swf when you deploy your application. They are not linked in any way.

    2. If you change something in the library.swf, you need to recompile your application swf to re-embed the changed assets.

  • kp says:

    After some more thought, I’m sure that there is a good use case for using a Flash 9 SWF as a library. Perhaps if the class you give a symbol in Flash 9 is an actual class, not an auto-generated one, but I’m not quite sure how or if that comes through. Still playing.

  • Ben says:

    Hey Keith,

    Great info once again. As far as the indentation thing, you have to not use the rich text editor or whatever they call it when writing your post. I had the same problem when I first installed iG.

  • kp says:

    Thanks. But I’m still having no luck with indenting. How do I not use the rich text editor? I can click on the html button on the top and paste my code in there, but when I hit update, it formats the whole thing into one long line. Are you using WP 2.0?

  • Dongwook says:

    I’m flying here to read this article, because I heard that Embed tag is not available anymore in AS3, but I think I was wrong. Anyway thanks for great tip. However, I have one question, somehow, I can’t complie this in Flash 9 preview version, could you tell me why isn’t that? It should work I guess. I did something wrong maybe.

  • Ben says:

    Yea, its kind of in a weird place. Options -> Writing -> uncheck “Users should use the visual rich editor by default”. I am using 2.0.3

    Good luck!

  • kp says:

    Thanks Ben. I tried that and it didn’t seem to make a difference, but I’ll give it another shot.

    Dongwook, metadata tags such as embed are not supported by the Flash IDE compiler, because you set everything up (stage size, fps, bg color) in the IDE, and you have a library, so don’t “need” to embed things like that.

  • kp says:

    Ah, found it! In addition to disabling the RTE in options, you have to disable it in your user preferences too. Yay! Indenting!

  • matt says:

    Thats great, thanks. I can compile in Flashdevelop and see all the shapes in the swf if i launch the swf with the standalone player, but the swf that opens in the tab is blank, any idea what the problem may be. Sorry if its slightly off topic :/

    cheers

    MaTT

  • Would embedding swf’s with linkage id’s be the best way to go for embedding components. Or are there specific metatags to handle swc embedding?

  • Philippe says:

    I’m fairly confident that FlashDevelop’s SWF exploration can show the symbols of Flash 9 IDE’s SWFs.

    Matt, check that you have the Flash 9 ActiveX plugin installed.

  • Francis Gabon says:

    Hey Keith,

    Thanks for that great tip. I’ve been looking for a way to embed SWF generated by the F9 IDE for a long time!

    As there’s no linkage id in F9 anymore, I tried to attach a class of my own (Anim.as) to a movieclip in the lib and that worked the same way :

    [Embed(source="lib.swf", symbol="Anim")]

    Nevertheless, back to my main app class in Flex Builder, I can’t cast the embedded MovieClip to my Anim class.

    trace("MovieClip: " + (anim is MovieClip)) //returns true
    trace("Anim: " + (anim is Anim)) //returns false

    Moreover, code I wrote on the Anim symbol’s timeline isn’t executed once the main app is launched in FB, although the symbol is visible. It’s pretty annoying as I may need some gotoAndPlay to be executed…

    Any help is welcomed on that :)

    Cheers,
    FG

  • kp says:

    Yeah, i haven’t quit figured out how to force the type of an embedded resource to anything beyond its default Movieclip/sprite/bitmap. Even if you have a named text field in an embedded asset, and try to access that, it says Sprite doesn’t have that property. I imagine there is a way, I just got distracted onto something else last night and didn’t explore it further.

  • Never mind..

    Swf embedded actionscript 2.0 components can not be used because of AS 3.0 compiler error’s, and Actionscript 3.0 components are simply classes to be instantiated ;) .

  • Sam says:

    So timeline code can exist. But wat about frames? Can assets have frames in their timelines?

  • yo Keith. thanks for sharing all this great info, much appreciated.
    im trying to import a symbol from my external swf and then cast it as a custom object, but failing miserably!!

    heres where i started, successfully instancing the asset as a sprite

    ——————————————————————

    [Embed (source = "../fla/library.swf", symbol = "customCursor")]
    private var cursorSprite:Class;

    var customCursor:Sprite = new cursorSprite();
    addChild(customCursor);

    ——————————————————————-

    but now i want to cast customCursor, so tried:

    ——————————————————————-

    import CustomCursor;

    [Embed (source = "../fla/library.swf", symbol = "customCursor")]
    private var cursorSprite:Class;

    var customCursor:CustomCursor = new cursorSprite() as CustomCursor;
    addChild(customCursor);

    ——————————————————————-

    and various variations on the above, all of which failed. any tips would be much appreciated.

    chur
    vinnie

  • kp says:

    i’ve run into the same thing vinnie. haven’t had the time to investigate it far enough to find the solution though.

  • kp says:

    sam, yes, as demonstrated in the example, you can have a timeline tween or frame by frame animation in a movie clip, and import that. however, you can’t control its frames. can’t even say stop() or gotoAndPlay().

  • alco says:

    “however, you can’t control its frames. can’t even say stop() or gotoAndPlay().”

    Presumably, this is because a SWF published in Flash 8 contains AVM1 bytecode, which, according to Adobe documentation, cannot be ‘understood’ by AVM2 bytecode. So when you build an AVM2 SWF (i.e. from AS3 sourcecode) mxmlc strips out incompatible AVM1 bytecode, even something as simple as a ‘stop()’.

  • thanks keith, thought i was being dense!!

  • jNj says:

    hey, new to AS2.0 let alone AS3.0 so could be doing alot wrong but the following worked

    [Embed(source="assets/tagDom.swf", symbol="dom")]
    private var dom:Class;

    var myDom:MovieClip = new dom();
    addChild(myDom);
    myDom.gotoAndStop(4); //changing frame number was working
    myDdom.x = 100;
    myDdom.y = 100;

  • jNj says:

    sorry,
    typo “myDdom.x = 100;”, “myDdom.y = 100;” myDom etc..

  • [...] A few weeks ago, I posted some info on embedding SWF-based assets in AS3. [...]

  • bong says:

    ok thanks a lot for that info ..

    this code :

    public function App()
    {
    init();
    }

    what exactly it do?

  • sascha/hdrs says:

    Can somebody give me a hint how to use embedded assets properly with a preloader? Before AS3 we used the timeline in Flash and put a preloader on frame1 and all the heavy stuff on frame2 or later. How does this go in AS3 without a Flash9 IDE? I’ve wrote a custom AS3 Preloader class that extends MovieClip and once it finished loading it jumps to frame 2 but how in the first place do I get embedded assets onto frame2 (if thats even possible)?
    I think there must be a way, after all Flex’s Preloader preloads properly (what a sentence!). And that one extends Sprite and Flex’s SystemManager class extends MovieClip, so maybe there are some parallels.

  • [...] BIT-101 tutorial on embedding resources in ActionScript 3.0 [...]

  • [...] Ressourcen zum Thema Embedding Resources with AS3 [...]

  • Mark Walters says:

    In case anyone comes stumbling upon this post again like I did, I wanted to offer up the solution to associating a custom class with an embedded symbol.

    Instead of doing something like this:

    [Embed(source="/library.swf", symbol="customButton")]
    private var CustomButton:Class;
    var customButton:SimpleButton = new CustomButton();

    Do this instead:

    [Embed(source="/library.swf", symbol="customButton")]
    public class CustomButton extends SimpleButton

    Add the embed tag above the class declaration that you want the embedded symbol to be associated with instead of above a variable that you want associated with the class.

  • Dennis van Nooij says:

    all this looks great but did anyone get this to work without embedding the Flex framework ? I get all kind of compile errors when I leave out the framework.swc.. :(

  • Dennis van Nooij says:

    note to self: better read the comments first..:)

    Mark’s solution works great. thanks

  • kp says:

    yeah, you’ll need the framework swc included, as assets are actually embedded as instances of SpriteAsset, MovieClipAsset, BitmapAsset, etc. which live in the mx package. Those classes are pretty self contained though, so you don’t have to worry that your file size is going to balloon by pulling in a bunch of the framework itself.

  • Jerry says:

    Maybe a solution: It works with anything, if you cast the Class, like this:


    [Embed(source="stuff/library.swf", symbol="Box")]
    private var Box:Class;

    var boxInstance:Sprite= new Box();
    addChild(boxInstance);
    Box(boxInstance).myLabel.text = "hello, again"; //"myLabel" is a Textfield in the Box

  • [...] A few days ago I had the intention to Embed a library-swf file in my AS3 code while using the Flash CS3 IDE. So I went for a search on the Internet and I stumbled upon the blog of bit-101 who already made a blog post on how to embed objects. Read the blog post here: http://www.bit-101.com/blog/?p=853 [...]

  • waltsatan says:

    Scalegrid doesn’t seem to work when embedding assets using the factory method.

    [Embed(source="roundedbox.png", scaleGridTop=2,scaleGridBottom=9, scaleGridLeft=2, scaleGridRight=9)]
    private var RoundBox:Class;

    It works as a bitmap, but when I try it as a sprite, it fails:

    var assetClass:Class = getDefinitionByName("RoundBox:) as Class;
    var assetBitmap:Sprite = new assetClass();

    Anyone know a way to get it to work?

  • [...] But what if I want to have a different button design for each button on my menu (NavMenu class)? Does this mean I must have a different NavItem class for each button? How lame is that? I just want to be able to use NavItem class on ANY MovieClip library item that may be a used as a button for my nav menu. (Flash requires that each item in the library be associated with a unique class). I’ve looked in to other ways of doing this, including ways to just access library graphics as Keith Peters describes: [...]

  • Dr S says:

    Thanks for this great tutorial. The only thing is I can’t seem to get this to preview from the Flash CS3 IDE. I get the swf to publish and appear with no compiler errors but I can see none of the symbols on the stage.

    Am I doing something wrong?

    Thanks :)

  • dannym says:

    Does anyone have experience importing a PNG from the Flash IDE that has jpg compression applied? I seem to recall that I was able to make this happen in the past, but now I get a “Error: Error #2136: The SWF file _ contains invalid data.” error. Works perfectly if I sent the PNG compression to loseless in the IDE, but I need to crunch these mofos. Worst part is, I remember doing this in the past. Has something changed? Doesn’t seem to work with Flex 2 or 3 SDK and fcsh.
    Any ideas?

  • [...] ActionScript 3 has an “Embed” tag that will allow you to put images in an applet. See this link for the complete explanation. Basically, you define a private Class variable, put the cursor just [...]

  • [...] a really cool article about the embedding of resources in Actionscript 3 in Keith Peters bit-101 [...]

  • In reference to Dannym:
    “Error: Error #2136: The SWF file _ contains invalid data.” error
    I’m using a .swf as an assets source to embedded images/icons in Flex.
    Flex send me this 2136 error.

    Situation:
    you import a png file into the Flash library, then it is exported as an swf to be used in Flex to get images to embed.
    If by default a jpg compression is applied to it, the 2136 error is sent when you try to use this asset.

    To fix this problem:
    just double click on the imported png image in the library, in the bitmap properties panel sets its compression to lossless (GIF/PNG), and then everything works great.

    Why?:
    I guess Flash or Flex makes a conflict between compressions and source files formats?

    I haven’t tested it in an “only Flash” workflow…
    I hope this will help somebody.

    Best regards.

  • halaszlo says:

    Hi,
    My code is the following:
    package
    {
    import flash.display.MovieClip;
    public class Main extends MovieClip
    {
    public var mcWall:MovieClip;
    public function Main():void
    {
    [Embed(source = '../Wall.swf')]
    var classWall:Class;
    mcWall = new classWall();
    addChild(mcWall);
    mcWall.stop();
    }
    }
    }
    I am using FlashDevelop and as3 project. The imported swf is a Flash 8 MovieClip.

    My problem is that the general movieclip functions don’t work (e.g. gotoAndStop() or stop().

    Is it caused by that the imported movie is Flash 8 or I am doing something wrong?

    Thanks in advance.

  • unhitched says:

    Is it possible to embed an flv file into a swf/swc that can be instantiated later? ie not importing to stage in Flash and saving as a MovieClip but using a standalone file that has been h264 encoded. I notice that if I create a Flex Library project and add FLV assets to it, I get a compiled swc conataining these assets – but can’t figure out how to use them in another Flex project. Any ideas would be great!

  • [...] References Embedding resources with AS3.0 AS3.0 with Free Flex SDK [...]

  • [...] http://www.bit-101.com/blog/?p=853 « Plaatje op een stage te krijgen met Action script 3 [...]

  • Doug says:

    You can embed and use an FLV file as follows:

    package
    {

    import flash.display.Sprite;
    import flash.display.MovieClip;

    public class Test extends MovieClip
    {

    [Embed(source="bin/test.swf")]
    private var myVideo:Class;

    public function Test ()
    {
    var k:Object = new this.myVideo();
    var v:MovieClip = k as MovieClip;
    addChild(v);
    v.play();
    }

    }

    }

    To generate a SWF from an FLV you need to transcode the file. I recommend using one of the (many) FLV to SWF encoders out there. Typically you can use ffmpeg directly if you already have the flv:

    ffmpeg -i myflv.flv -acodec copy -vcodec copy myswf.swf

    All the methods mentioned previously can then be used to load the swf as normal. Remember external swfs extend MovieClip, not Sprite. :)

  • [...] Peters had a couple of posts a little while ago about embedding assets in as3 (1 and 2). One thing that came up in both of them that could not be resolved was how to associate a [...]

  • Andrew says:

    I’m wondering if there’s a way to dynamically set the ‘source’ of the Embed so I can do batch Embeds? That would be fantastic.

    It seems you can’t access variables once you enter the embed tag…

  • BubbleBoy says:

    I am trying to do this but it doesnt work, I keep getting:

    “App_Picture.as(10): col: 42 Error: The definition of base class BitmapAsset was not found.”

    Any ideas?

  • BubbleBoy says:

    Seems I found the solution.

    Just create “fake” a BitmapAsset class, a fake SpriteAsset and a fake MovieClipAsset class.

    http://www.ultrashock.com/forums/flex/embed-flex-assets-without-using-flex-123405.html

  • ComChan says:

    For those who have problem on frame control with embedded Swf, without a debugger you will never understand what the hell is going on inside.

    [Embed(source="omg.swf")] public var OMGAnimation:Class;

    var omg_mc:MovieClip;

    function pasteOMG(){
    omg_mc = new OMGAnimation();
    addChild(omg_mc); // Yea i see that
    omg_mc.gotoAndStop(2); // That’s not working, the MC keeps on playing
    }

    So what’s the deal?
    Yup, omg_mc is really a MovieClip object, but only a shell with a Loader object as child.
    And the loader’s content is the real MovieClip object that you can manipulate.

    var omg_mc:MovieClip;

    function pasteOMG():void{
    var omg_object:MovieClip = new OMGAnimation();
    var omg_loader:Loader = omg_object.getChildAt(0) as Loader;
    omg_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderComplete);
    }

    function loaderComplete(e:Event):void{
    omg_mc = LoaderInfo(e.target).loader.content as MovieClip;
    addChild(omg_mc);
    omg_mc.gotoAndStop(2); // Now it works
    }

  • [...] Builder, now Flash Builder, you can embed image files in your code and make them act as classes (example 1, example 2). Quite useful, but again, it just makes your file size bigger. Having a preloader that [...]

  • Sumeet says:

    Andrew I am also looking for something like that. If anyone has some soluton then help would be appreciated.

  • kp says:

    Andrew, Sumeet, the only way to do that would be some kind of precompiler that changed the variable before the flash compiler got to it.

  • Peter Schum says:

    Hi there,
    I simply want to create something like what is explained in this tutorial but (maybe because of probabily the new version of Flex SDK) there is no way I can see the preload working, just a blank screen.

    Would it be worth trying within Flex Developer? And how?

  • [...] Embedding SWF files as assets for other SWF files using AS3 (requires FLEX) – http://www.bit-101.com/blog/?p=853 [...]

  • [...] hours of Googling (yes this should be a word added to the dictionary) I found the solution on Bit101. For some reason AS3 casts embedded symbols based on the number of frames they have. If your symbol [...]

  • Charles says:

    I’ve been trying to get this to work for some time.

    I have this:

    [Embed(source="mplib.swf",symbol="menuBgGr3")]
    var menuBG:Class;

    then later I call this:

    var theScreen:MovieClip = new menuBG();

    and I get this:

    Error #1007: Instantiation attempted on a non-constructor

    Any idea what I’m doing wrong?

    • keith says:

      looks right to me. what happens if you trace(menuBG) ?

      • Charles says:

        If I trace before I call the new statement, it’s null.

        If after, it won’t trace out. I just get the error.

        I’m working in the regular Flash program. Does that make a difference? Everything is AS3.

        • keith says:

          if it’s null, the symbol is not being embedded. wrong name, not exported correctly, wrong path, no idea.

          • Charles says:

            Hmm…

            I know it’s in the right spot and that the names match. I did a copy and paste from one to the other.

            Do I have so create the library SWF in a certain way so that it’s movieclips are accessible?

  • Charles says:

    I tried to download the source files but the link appears to be broken.

  • Terence says:

    Hi, how do I access properties of the Star, Circle? For example, if there is a dynamic text that I would like to control, can I code star.mytext.text = “hello”; I have try on my side..it does not seem to work

    • jipe says:

      You can try
      var starTF:TextField = star.getChildByName(“mytext”) as TextField;
      starTF.text = “hello world”;

  • Daniel Bunte says:

    hi there,
    you might also be interested in embedding fonts, bitmaps, binaryData, etc. without using the flex framework at all.
    see: http://danielbunte.de/2011/07/24/embed-bitmaps-fonts-binarydata-etc-without-using-the-flex-framework-at-all/

    best regards,
    daniel

  • Ray says:

    It seems that these code is obsolete now, I copy it and create the library.swf but it doesn’t make sense…

  • [...] than loading the image and in order to make things quicker, I simply embedded it in the [...]

  • [...] If you want to target iOS platform for your game, you must know that you can’t load swf at runtime. Indeed all your data must be “packaging” in one file an .ipa. So you are not able to load external data. To pass over that restriction, you need to use the metatag Embed properties.This is a blog post for Embedding Ressources with AS3. [...]

  • zzlasp says:

    Can you help to use an embeded swf’s property or variale?