create movie clip from a name from a string - actionscript-3

Basically instead of var thing_mc:test_mc=new test_mc I want to somehow do thing_mc:String=new String, where String is defined by an array. I've tried several methods and searched all over, but I can't find out how to do this. I don't know if I'm not searching for the right thing or what, but I just can't find an answer.
Example of what I want:
var anarray:Array=new Array
anarray[0]="thismc"
anarray[1]="thatmc"
var thing_mc:anarray[0]=new anarray[0]
addChild(thing_mc)
I know what's obviously wrong, but I don't know what's right and that's the easiest to understand example of what I'm trying to achieve.

You could use
var anArray:Array = ["AClassName", "AnotherClassName"];
var class:Class = flash.utils.getDefinitionByName(anArray[0]);
var instance:* = new class();
But worth noting is that the classnames you're referencing in your array DO need to be imported somewhere in your project else the application won't be able to find those classes at runtime.

Related

How to append new ListElement in QML?

So, I need a button that would add a new ListElement to existing list. I need to fill in one value, taken from TextField. I have no idea how to do this. I tried something like
onClicked:{
nameOfList.append(JSON.parse([nameOfList.nameOfColumn,myTextField.text]));
}
Obviously it didn't work. Do I have to send these two values to C++, then make a QJsonObject and send it back, or is there an easier way?
While the question does not describe the type of nameOfList, I assume it is ListModel since the question is about adding a new ListElement. In that case, appending would be straightforward:
onClicked:{
nameOfList.append({"nameOfColumn": myTextField.text})}
}
However, if nameOfList.nameOfColumn is not constant, you'd need to make a temporary:
var temp = {}
temp[nameOfList.nameOfColumn] = myTextField.text
nameOfList.append(temp)
It can depend on what exactly nameOfList is, but here you will most probably find an answer.

AS3 Dynamic variable naming

Is dynamic variable naming like this possible in ActionScript 3?
for (var xz=0;xz<10;xz++){
var this['name' + xz]:Number = xz;
}
You should use an array for this kind of list of variables.
While you can create properties dynamically, you usually want to avoid it. Especially in your case, where the actual identifier of each variable is not a String, but a number. So why not use something that does exactly that: identify its elements by a number? And that's exactly what an array does.
code example:
var xzs:Array = [];
for (var xz:uint = 0; xz < 10; xz++){
xzs.push(xz);
}
Short answer is: no, you can't declare at runtime typed properties.
Long answer is: kinda.
If you want to create new typed properties you'll have to store them in a Vector<>.
Anything else would let you do it but untyped, dynamic class, store in object, store in array, etc ...
Yes, it sure is - AS3 comes from ECMA script, so this is setting a property to an object (in this case it's this). So you can dynamically set properties. But you are a little bit wrong about how to do it - there is no need to use var, because you don't declare it, you set it. It's like using:
this.propertyName = 'value';
From now on, this will have propertyName equal to 'value'. Therefore you should just use:
this['name' + xz] = xz;
That's all!
Edit: as BotMaster mentioned - if you are using classes and you want to dynamically add properties, the class must be set as dynamic. Most of the commonly used ones are already dynamic (as Aaron mentioned :)).
I didn't go into much details as I think you simply need to do this on your timeline. If not - please specify this in your question so that you can get more accurate answer than this one. The same goes if your new property needs to be typed (can't think of any point wanting this) - you should see BotMaster's answer :)

Square bracket notation to dynamically load library items?

So I've spent an embarrassing number of hours trying to save myself a few minutes and make my code a bit neater, and Google has produced nothing, so now I come crawling to stackoverflow. The problem is with square bracket notation + library items:
So let's say you have a MovieClip called "myMC_5", and you want to set its X position to 0..
myMC_5.x = 0;
..and if you don't want to hard-code the name of the MC but instead you want one line of code to move a specific MovieClip based on a variable, you could do something like this:
var selectMC = 5;
root["myMC_"+selectMC]x = 0;
..and this will have the exact same effect as myMC_5.x = 0, except that this time you must specify the location ("root" or "this" or something).
THE PROBLEM:
I'm working on a game in which the graphic for the background is loaded from the library, and it's different for each level. The initial loading of the vector from the library looks like this:
private var land:vector_land0 = new vector_land0();
..and this works fine, but it only loads that one specific vector. There should be about 30 or more. I'd like to just have 1 line of code in the constructor to load any of them, based on a variable which keeps track of the current level, like this:
private var land:["vector_land"+theLevel] = new ["vector_land"+theLevel]();
..but that doesn't work. I get syntax errors ("expecting identifier before leftbracket") because you need to specify the location of the object, like in the first example:
root["myMC_"+"whatever"].x = 0;
..but this library item has no "location". So, how the heck do I dynamically load a vector from the library? It's not "on the root", or anywhere else. It has no location. I refuse to believe that the standard method for accomplishing this is to create 30 different classes or write a giant block of code with 30 "if" statements, but searching Google has found nothing. :(
It sounds like you're looking for getDefinitionByName(), which you could use to do something like this:
import flash.utils.getDefinitionByName;
private var LevelVectorClass:Class = getDefinitionByName("vector_land" + theLevel) as Class;
private var land:Object = new LevelVectorClass();
This is a horrible way to solve the situation, I don't recommend using square brackets anywhere but arrays. I recommend you putting the "lands" into a LandContainer MovieClip, each frame of that MovieClip would container 1 graphic. It is much cleaner, and you could create constants to store the "identity" of the frames.Example:
var land:LandContainer = new LandContainer();
land.gotoAndStop(FIRST_LEVEL); //FIRST_LEVEL is a constant integer
You can even reuse this LandContainer instance because you can set it's visibility, remove from the display list, set it's frame to the next level without creating another instance. On second thought, I would write a wrapper for this class. Aka link it to your own class which extends the MovieClip class and create custom functions, fields... etc..
This dynamic thing is horrible, hard to maintain, and not efficient at all. Don't know why did not they delete it from AS3... they should have.

Removing commas from multidimensional arrays

I'm having a bit of trouble removing commas from an array when I go to write it to a cell in google spreadsheets. array.join(''); doesn't seem to do the trick. I would appreciate any help. Also, anchor[i][j].join('') returns an error.
Here is a bit of code:
anchor[i][j].join('') returns an error
anchor[i].join('') doesn't seem to have an effect.
for (var i=0; i(less than) rangeKW.length-2;i++){
anchor[i] = [];
for (var j=0; j<rangeURL.length;j++){
anchor[i][j] = ahref + rangeKW[i] + ahref1 + rangeURL[j] + "</a>|";
}
}
cell.setValue("{" + anchor);
}
Suppose you have
var x = [[1,2,3],[4,5,6]]
Then either of these lines will give you "123456":
Array.prototype.concat.apply([], x).join('')
x.map(function(a){ return a.join(''); }).join('');
The first one constructs the array [1,2,3,4,5,6] and then joins it. The second one joins each inner array first, constructing ["123", "456"] and then joins that. I think the first one is likely to be a tiny bit more efficient, although we are talking peanuts here, but the second one gives you a bit more control if you want to put something different between rows and columns.
In both cases, this doesn't change the original value in x. You can assign the new value to x if that's what you want.
array.join() works with "normal" arrays, by normal I mean 1 dimension and applies to the array itself, not on an single element (error on [i][j]), beside that I don't really understand what you want to do and how your code is related to your question ...
concerning anchor[i].join('');// doesn't seem to have an effect. I don't know how many elements are in there and how they look like but the syntax is correct. You can also use toString() if you want to make it a CSV string.
EDIT : (thanks for the information in comments.)
I think the easiest way (or at least the most clear) would be to create a couple of new variables that you could log separately to see exactly what happens.
for example
var anchorString = anchor[i].join(); // or toString() they both return strings from 1D arrays
Logger.log(anchorString)
if every index i of anchor have to be in the same cell then write it like this in the i-loop :
var anchorString += anchor[i].join();
Logger.log(anchorString)

retrieving a variable value from lower level

well i created some variables in the main stage level, with something like this:
for(i=0,i<10,i++){
var var_name="var_num_"+i;
this[var_name]="some value";
}//<-----------------------------------------------------works
so i get 10 variables named "var_num0", "var_num1", "var_num2" each one with some value.
and i can acces them any where calling this
var second_var=MovieClip(root).var_num0;//<--------------works
my problem comes when i want to call all the variables from a lower level or in another frame or somewhere else using another loop:
var third_var;
for(j=0,j<3,j++){
third_var=this["MovieClip(root).var_num_"+j];//<---------DOSNT WORK
trace(this["MovieClip(root).var_num_"+j]);//<------------returns "undefined"
}
how can i make this work? i tried a lot of things and nothing...
thanks you all
In your case both "root" and "this" are the scope you want to access the vars from. so try this:
var third_var:MovieClip;
for(j = 0; j < 3; j++)
{
third_var = MovieClip(root)[var_num_ + j];
trace(third_var);
}
Also you should have semi-colons in your for loop rather than comers.
I'd like to preface my answer with a suggestion you use a 'Document Class' with AS3 to make things like namespaces and inheritance much clearer. You know exactly where things are accessible when using document based, object oriented programming versus the timeline programming available through the Flash IDE (its only there because of AS1/2). Tut: http://www.kirupa.com/forum/showthread.php?223798-ActionScript-3-Tip-of-the-Day/page14
On to the answer: You are trying to move two levels of inheritance in one set of [] Another way of writing your first "Doesn't work" line is:
this.myMovieClip["var_num"+j"];
You could also use: this["MovieClip"]["var_num"+j];
Basically, you need to take the "MovieClip(root)" out of the string you are using to call your variable because you are passing through two levels of inheritance: this->MovieClip->targetVar
You need to use two periods, a period and a set square bracket or two sets square brackets to move two levels of inheritance. A period . and a set of square brackets [] both accomplish the task of moving one level deeper, so putting the . inside the string used to call up your variable won't work.
Explanation:
The following three examples all return the same variable:
myMovieClip.my_variable
myMovieClip["my_variable"]
var str:String = "my_variable";
myMovieClip[str];