AS3 Embed and asset paths

I ran into a surprise last night as I was using the Embed metadata tag in an AS3 project. I had assumed that the path to the embedded asset would be relative to the project root. Turns out that it’s relative to the location of the individual .as file which does the embedding. After some thought, I see the logic of it, but it creates a few little problems… well maybe annoyances.

First, an example. Say you have a project dir that has a main class and a set of nested package folders:

Project
   Main.as
   com
      bit101
         projectname
            MyClass.as

Now, say MyClass.as embeds and uses icon.png. If you do not specify a path, it will look inside the projectname folder. I had been assuming that it would look in the main Project folder.

Now, obviously, you don’t want to start storing your assets in your classpath folders. Yuck! So, what are the alternatives.

1. You can use an absolute path: C:/Documents and Settings/blah/blah/blah/icon.png

This makes the whole project completely unportable. So that’s no good.

2. You can use relative paths to work your way back up the package chain til you get to the root: ../../../icon.png

I guess the latter is the only real workable solution, but I think it’s ugly. Say I decide to move MyClass into a new package, interface, that is part of projectname. In addition to any other refactoring, I have to adjust the path for any and all embeds, and count the little dots and mentally map them to package heirarchies. Just doesn’t seem very elegant. Too bad there is not a shortcut for this, say {projectroot}/icon.png for example.

Of course, for a larger application, you would probably create an asset manager class as a singleton that takes care of all the embedding and has getters that return the assets you need. But for smaller projects I guess we’re stuck with counting the dots.

This entry was posted in Flash. Bookmark the permalink.

10 Responses to AS3 Embed and asset paths

  1. darron says:

    I work around the path issue by having a single class used to bring assets in, namely AssetImporter. It looks something like this:

    public final class AssetImporter
    {
    [Embed…]
    public static const IMAGE_1:Class;
    }

    Then, whenever I need image 1, I just use {AssetImporter.IMAGE_1}. By having the assets centralized in one class, you avoid the “what if I refactor to new package” problem, since all of the assets are pulled in via constants. Because the variables are declared as constants as well, you don’t need to mark the class [Bindable] and you can’t accidently overwrite them somewhere else in code.

    This has been working well for me for both large and small projects…

  2. kp says:

    Yup, that’s pretty much what I referred to in my last paragraph. Thanks for validating my concept. 🙂

  3. Chris Allen says:

    What kind of small projects are you talking about Keith? Moving random shpes around the screen and what not? 😛 Anyway, I think That having the utility class makes a lot of sense, Write it once and then your small projects can use it too. Hmm, makes me think that I should port our Asset Managing classes from Fling to AS3 soon. Thanks for the tip.

  4. kp says:

    even random shapes need to embed assets. don’t hate!
    Yeah, I guess it makes sense to create a reusable class that can handle all that stuff for any size project.

  5. Ben says:

    I agree the class solution is probably the best option, but just out of curiosity, does starting the path with / not make it begin at the project root?

  6. kp says:

    I didn’t try it, but I assume it would be interpreted as the file system root.

  7. Ben says:

    Starting the Embed path with / does indeed signify the project root. So you could use [Embed(“/assets/images/logo.gif”)] from anywhere in your project.

  8. kp says:

    well damn. that’s good to know. like the old saying goes, “when you assume…”

  9. Troy Gilbert says:

    As pointed out, the best solution is starting the embed path wit a forward-slash, “/”, as that’s relative to the project root!

Leave a Reply