AS3 Tutorials – Instantiate Using a Dynamic Class Name

You likely know how to instantiate a class in Actionscript 3 using the new keyword:

1
var someClassInstance:SomeClass = new SomeClass();

But what if you want to instantiate a class where the class name is dynamic?

For example, we’re working on a project that has a Character class. We pass it a character name (“Fred”, “Joe”, “Tom”, etc), and among other things, it goes into the library and instantiates a linked MovieClip based on the character name.

In Actionscript 2, you would do this:

1
2
this.attachMovie(dynamicLinkageName, "instanceName", depth);
// Where dynamicLinkageName is "Fred", "Joe", "Tom", etc

So in Actionscript 3, you’re tempted to say something like this:

1
2
3
4
5
6
7
public class Character
{
	public function Character("charName")
	{
		var charClip:[charName] = new [charName]();
	}
}

But that’s not going to work at all. Here’s how to do it:

1
2
3
4
5
6
7
8
9
10
11
12
13
import flash.utils.getDefinitionByName;
 
public class Character
{
	public var charClip:MovieClip();
 
	public function Character("charName")
	{
		var ClassReference:Class =
			getDefinitionByName(charName) as Class;
		charClip = new ClassReference();
	}
}

Voila!

20 thoughts on “AS3 Tutorials – Instantiate Using a Dynamic Class Name

  1. Alex Lomax

    I hate to burst your bubble, but that doesn’t solve the problem. Using that method relies on having a library symbol with the appropriate linkage, and doesn’t allow you to instantiate a code class with a dynamic name at all.

    Reply
  2. Ryan

    You’re right – bubble burst. This method only works if the class exists as a symbol in the library.

    HOWEVER … if you can tolerate a work-around, you can use the same code to (sorta) do what you want.

    You have to hard-codedly name the classes you want to instantiate somewhere in your code. For example, if you have classes called Class0, Class1, Class2 and Class3, somewhere in your code (maybe in your Main class?), just below the import statements, write:

    Class0;
    Class1;
    Class2;

    Then you’ll be able to use getDefinitionByName to “dynamically” instantiate your classes. You’re not actually creating a class dynamically. You’re instantiating classes using an dynamic name, as in this example.

    Reply
  3. Josh

    Hey Ryan, this is exactly what I am trying to do. I am just starting in on AS3, so please forgive my ignorance, but I can’t seem to get this work. I copied your code verbatim and put it inside of a package:

    package {

    import flash.utils.getDefinitionByName;

    public class Character {

    public var charClip:MovieClip();

    public function Character(“charName”) {
    var ClassReference:Class = getDefinitionByName(charName) as Class;
    charClip = new ClassReference();
    }
    }
    }

    I am getting errors:

    “expecting semicolon before leftparen” on public var charClip:MovieClip();
    and
    “expecting identifier before charName” on public function Character(“charName”){

    Should “charName” be a literal? I tried using Character(charName:String), but I got an error when I tried to call it. I’m sure this is a bit noobish, but I would really appreciate any help you can give me.

    Reply
    1. Ryan

      There are a few little things you need to fix up to avoid those errors:

      1. Ditch the brackets at the end of charClip:MovieClip() … you only need the brackets if you’re actually instantiating an mc. Here, you’re just declaring/defining it.
      2. You’re right about the parameter – try charName:String instead of “charName”
      3. The interpreter will probably want this class to inherit from MovieClip (public class Character extends MovieClip) (remember to import flash.displayMovieClip when you do this)

      Hope that helps.

      – Ryan

      Reply
  4. Alexandre Madurell

    Thanks, Ryan.

    At first, I couldn’t get the getDefinitionByName to work with items in the library whose class definition wasn’t automatically created by Flash (that is, library items with a custom class linkage set in their properties).

    I’ve finally found a solution through the comments in http://thillerson.wordpress.com/2007/03/01/runtime-class-instantiation-in-actionscript-30/. The missing piece was using getQualifiedClassName to obtain the name of the class of an already existing instance of that library item… for some reason giving it just the name of the class didn’t work.

    Basically, it’s like an AS3 version of the old AS2 duplicateMovieClip.

    var ___classType:Class = getDefinitionByName(getQualifiedClassName(_avatar.AVATAR)) as Class;
    var ___avatar : Avatar = new ___classType();

    where _avatar.AVATAR is an already declared instance of 1 class (out of 4 possible characters in a game I’m developing).

    Reply
  5. Burton

    Just wanted to share this explanation that I’ve found online today. It covers the ability to dynamically load a movieclip in an external swf by name. This allows you to decouple the assets from your code. The approach I’m using is a config file has a catalog of the used movieclip names. That file is read in and then I request the appropriate movieclips from the loader.

    http://annafilina.com/blog/instantiating-and-displaying-movieclips-from-loaded-swf/

    Reply
  6. HybridMind

    Thanks for this! I’ve been wondering how to do something similar in AS3 for AGES! Was never able to search for the right terms of what I was trying to do though. Luckily a buddy of mine helped me search and found this post today. I was used to being able to do this type of stuff in Perl and Ruby all the time and it is nice to see they do support it. All I needed was the ability to do “var LevelClassReference:Class = getDefinitionByName(“Level1_12″) as Class;” and then “new LevelClassReference();” and this works! Once again I’ve done horrible workarounds in the past until this.

    Reply
  7. Alex

    Wow this is perfect for what I’m looking for! (Of course I had to type just the right words into Google to get what I wanted)

    I’m trying to make a world generator using BitmapData and stuff, and I would have hated trying to make a class for every single object (Dirt, wood, stone, leaves, grass, sand, etc.). Very practical application for this code.

    Thanks Ryan! You-dah-bomb! :)

    Reply
  8. RiaanP

    Hey man. Thanks for this article. Helped a lot. :) I do have a question though..

    I’m trying to use this to play many different sounds based on a single String that I pass.

    So, I embed the mp3:
    [Embed(source=’../../../sounds/testsound1.mp3′)]
    private var testsound1:Class;

    Then, when I want to play it I use:
    var ClassReference:Class = getDefinitionByName(_snd) as Class;
    snd = new ClassReference() as Sound; // instantiate new sound
    //snd = new testsound1(); // To test if it works – yes it works
    //stopSounds(); // This also works
    channel = snd.play();

    Any ideas why I get this error?:
    ReferenceError: Error #1065: Variable testsound1 is not defined.
    at global/flash.utils::getDefinitionByName()
    at com.jewint.sound::SoundManager/playSound()
    at com.jewint.actors::Blackboard/clickHandler()

    Reply
  9. RiaanP

    Oh boy.. I answered my own question through a bit of sheer luck and guessing ;)

    Here’s what I changed the code to and now it works for dynamically playing sounds based on string identifier.

    var snd1 = new (this[_snd])(); // instantiate new sound
    //stopSounds();
    channel = snd1.play();

    Reply

Leave a Reply to Deepak Cancel reply

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