Overview:
Often I’ve had some dynamically created movieclip and then wanted to reference it in my code. This is hard to do if it is named dynamically as well, such as with an incrementing variable. If you use one (or more) variable to name an instance in run time, you can’t always know what it will be called.
There are two ways (that I know of) to reference these clips, one is the array operator [] and the other is using the eval() function is as2 (but I’ve noticed that as3 has removed the eval function, so I’d recommend getting used to array notation).
Steps:
- Create the object dynamically (or with a variable) (_root.myClip.duplicateMovieClip (“myClip”+i, i);)
- Reference it with either array notation or with eval. (thisOne = _root[“myClip”+i];) or (eval(“myClip” + i))
Example:
[kml_flashembed fversion=”9.0.0″ movie=”https://circlecube.com/circlecube/wp-content/uploads/sites/10/2008/07/reference-dynamically-named-clips.swf” targetclass=”flashmovie” publishmethod=”dynamic” width=”500″ height=”500″]
[/kml_flashembed]
I create some movie clips dynamically using a for loop and name them all incrementally with a variable (myClip+i). But then i want to refer to some of them later, specifically. I don’t know what they are named though. They are all myClip1 myClip2 myClip3 and so on. I can use array notation to reference these (or eval). I’ve found it’s easiest to create a reference to the name once and then use it to refer to the clip I want. I imagined a scenario that when you click a mc you would want a different one to be moved. So clicking myClip3 moves myClip4 and so on. I’ve made it wrap so that 5 moves 1… They change the _y property of the next to match the one that’s clicked. Clicking the refresh button will loop through all the clips and (this time using eval) randomize the y coordinate.
Actionscript:
[cc lang=”actionscript” tab_size=”2″ lines=”40″]
var myLimit = 5;
//myClip._visible = false;
for(var i=1; i<=myLimit; i++) {
_root.myClip.duplicateMovieClip (“myClip”+i, i);
thisOne = _root[“myClip”+i];
thisOne._y = Math.random() * Stage.height;
thisOne._x = Stage.width/(myLimit+1) * i ;
thisOne.id = i;
thisOne.idDisplay.text = i;
thisOne.onRelease = function() {
nextOne = (this.id == myLimit) ? _root[“myClip”+1]: _root[“myClip”+(this.id+1)];
nextOne._y = this._y;
}
}
myClip.onRelease = function() {
for (var i=1; i<=myLimit; i++) {
eval(“myClip” + i)._y = Math.random() * Stage.height;
}
}
[/cc]
Download:
Source fla file: download
Reference:
Nuno Mira shows a good example:
[cc lang=”actionscript”]
this.createEmptyMovieClip(“outer_mc”, 1); // create a mc called outer_mc
outer_mc.createEmptyMovieClip(“inner_mc”, 1); // create a mc called inner_mc inside outer_mc
// 3 different ways of targeting inner_mc
trace(outer_mc.inner_mc);
trace(outer_mc[“inner_mc”]);
trace(this[“outer_mc”][“inner_mc”]);
// all output _level0.outer_mc.inner_mc
[/cc]
TheCanadian@Kirupa states it nicely:
The Problem
How can I reference objects using a variable? This is commonly a problem with dynamically created buttons:
ActionScript Code:
for(i = 0; i < 3; i++) {
button+i.someProp = "Hello World!"; //error
}
The Answer
This is probably the question that gets asked the most. Referencing an object with a variable is done using something called associative array referencing or array notation. The fundamental concept behind this is that:
ActionScript Code:
myObject.prop = "value";
//and
myObject["prop"] = "value";
Are the same thing. Associative array referencing follows the pattern of scope[“prop”] where scope is the object which contains the property and prop is the name of the property you wish to reference. Save appearance, array notation works in exactly the same way as dot notation.
Going back to the original, problematic, example, the correct code would look like this:
ActionScript Code:
for(i = 0; i < 3; i++) {
this["button"+i].someProp = "Hello World!";
}
The button string is concatenated (joined) with the i variable, forming a new reference with each iteration of the loop. First button0, then button1, et cetera.
That’s the quick, but some of you may think that that’s the same notation that is used with instances of the Array class. While that is true, the converse is actually more correct: Array instances use that notation.
Arrays are exactly the same as generic Objects, the only difference is that they have a collection of methods to deal with their properties. And because they require a need for organization, they typically only use numerical properties. Given the array myArray = [“a”, “b”, “c”], you could theoretically reference the indices using myArray.0, myArray.1 and myArray.2. The reason that we must use array notation is because the compiler doesn’t allow the reference of numerical properties with dot notation.