Problems with Embedding SWFs in ActionScript or Flex

There are two ways of including assets (images, swf animations, music, ect) in your flash application. Either use the URLLoader to load the files externally, or embed your assets, so you can distribute just your swf, and not need to include any other files.

It sounds straight forward, but there any many places Flash may try to “trick you” into assuming it is behaving as expected.

Embedding a SWF file

One way you can import all your assets easily is by having all your assets inside one .FLA flash file, and embed the swf in your program.

[Embed(source = 'mario_main_menu.swf')]
public var tex_main_menu:Class;

You would think you would have access to all your objects on stage? Not at all-

Embedding a Symbol From a SWF

To be able to have access to objects on stage, you need to put them all into a symbol (MovieClip) in Flash, and embed the name of that symbol in the library in your program.
You must also(in Flash) right click on your symbol, go to “properties”, and click both “Export for Actionscript” and “Export in Frame 1”.

[Embed(source = 'mario_main_menu.swf', symbol="main_menu")]
public var tex_main_menu:Class;

Now if you create a new MovieClip with this class, you can add the movieclip to your stage, and it will show everything from that symbol in your swf/fla file.

//create an instance of your overall movieclip from your fla file
var main_menu_mc:MovieClip = new tex_main_menu();

//Throws an error!:
//[Fault] exception, information=TypeError: Error #1034: Type Coercion failed: cannot convert tex_main_menu@6921e21 to flash.display.MovieClip.

Flash Trick: Exporting MovieClip as Sprite

What the heck, you might ask? Flash is saying that your movieclip, exported into swf, is in fact not able to be converted into a MovieClip!

Guess why? Since your MovieClip only has one frame, Flash exports it instead as the Sprite class.

You think to yourself, well thats okay, I guess. Kind of dumb, but I can work with a Sprite fine, I don’t really need it to be a MovieClip, it only has one frame after all, all I am interested in is embedding and using it, and Sprites are lighter weight than MovieClips.

//create an instance of your overall movieclip from your fla file
var main_menu_mc:Sprite = new tex_main_menu();

//now add it to the stage
stage.addChild(main_menu_mc);

//worked fine, you can now see your movieclip! 

//well, lets add a listener to the "start game" button in our main menu(that was in our 'main_menu' symbol), so when we click on it, we can run the function to start the game

main_menu_mc.btn_start_game.addEventListener(MouseEvent.CLICK, StartGame);

//Again an error:
//[Fault] exception, information=TypeError: Error #1010: A term is undefined and has no properties.

Flash Trick: Embedded Sprite Not Able To See Children

Oh happy day! It looks like we don’t have access to any of our objects inside the main movieclip….
If you create a for loop, go through the main movieclip children, and print out by name, you’ll see that all of our objects are still there, we just don’t have direct access to them by name.

Why is this? Because exporting as a Sprite makes it so that the object cannot have “dynamic properties” on it, so importing our objects as Sprites effectively disables our access to the children by calling them by dot notation. (although we could search through the children, find them by name, and create references to refer to each time)

But MovieClip types allow us access to the objects we placed inside them. But, stupidly enough, there seems to be no method to force our MovieClips to be exported as MovieClips, due to them only having one frame.

The fix? Add another frame to your MovieClip before saving the swf.

//create an instance of your overall movieclip from your fla file
var main_menu_mc:MovieClip = new tex_main_menu();

//now add it to the stage
stage.addChild(main_menu_mc);

//worked fine, you can now see your movieclip! 

//well, lets add a listener to the "start game" button in our main menu

main_menu_mc.btn_start_game.addEventListener(MouseEvent.CLICK, StartGame);

//actually works this time, and finds our object from our imported movieclip!

Summary

Rules for embedding content from a swf:

  • If you need access to something in your swf, you must create a symbol/MovieClip in your fla library, and under properties, export for ActionScript in frame 1
  • You must embed that symbol by name, in the format: [Embed(source = ‘mario_main_menu.swf’, symbol=”main_menu”)]
  • If your embedded object only has one frame, it needs to be setup as a Sprite, but you will lose access to any internal MovieClips
  • To have access to any internal MovieClips, you must add an extra frame (at least 2 total) to force flash to save as a MovieClip instead of converting to a Sprite

So if you have any problems embedding, or accessing properties of embedded MovieClips, you probably have to check how flash is handling things differently than “the most obvious way”.

Bookmark the permalink.

4 Comments

  1. Thanks a lot.
    These conditions should have been mentioned in the documentation.

  2. Wow, weird.
    Great post, thanks!

  3. Pingback: Embed movieClip in flex, on9, u will get error | code@butterflybone

  4. I have the same problem/situation. I’m using Flash Builder 4.7 and embedding swfs built with Flash CS5 (FP10, AS3). If my swf has a dynamic text field, simply adding frames still doesn’t work. However, if I leave the type declaration off like so:

    var main_menu_mc = new tex_main_menu();

    I get warnings but at least it works. I’d like to not leave the type declaration off, but I don’t know how else to make the swf work containing a dynamic text field.

Leave a Reply

Your email address will not be published. Required fields are marked *