Greetings to all!
Why this article"
Simple. Many of you have used with Actionscript 2.0, forms and techniques which with the version 3.0, would only create varied errors and would bring negative result.
Often, I receive e-mails with strange questions such as:
- how do I create the name of a variable in runtime"
It is typical of whom still thinks the following way: this['nome'+i]" and would like to realise something such as: var 'nome'+i:MovieClip=new MovieClip();
My opinion:
- this ['name' + the]... it is obsolete and indeed not very good mannered.
- var 'name' + i:MovieClip=new MovieClip (); with Actionscript, it is not possible
Then I have seen in some Italian"s forums that some "misunderstood genius" (perhaps too much misunderstood) answers to this type of questions with eccentric solutions.
Since I don't like to create polemic and respect other people's job, I never said a word about it.
What I have seen in these last few days however, has pushed me to write this article in how much at least, I will have the certainty that who wants to correctly learn Actionscript 3.0 will have available another technique, a more valid technique from my point of view.
A lot of solutions to these types of problems are found using the Array class of Actionscript 3.0.
We have already seen a few things in this article, but I wanted to get deeper in one of the many virtue of the array class.
Let us see a concrete example"
To create an object in runtime with Actionscript 3.0, it does not mean to create instances of the Object class, such as for example:
var obj:Object=new Object();
obj.nome='filippo';
obj.cognome='lughi';
obj.eta=35;
In this case, I created an instance of the Object class and I assigned a few properties to the instance itself and values to each properties.
This solution is valid but limited.
What should I do if I decided, as example, to tell "obj" to rotate on itself" Or if I wanted to create a text field and view the value of each one of its property"
A loss of time as it is not possible to assign methods to an Object.
Creating object in runtime means:
- to create and instantiate Classes with properties and methods.
- to insert in an Array, every instances of the class so that we can recall the instance and access its properties and/or methods as needed in the best and simplest way.
- to keep track of every instances and working with modulation.
I create a FLA and I save it as "main.fla".
I create a Document Class, an AS file saved as "Main.as", implemented the following way:
Code:
package
{
import flash.display.MovieClip;
public class Main extends MovieClip
{
private var numItems:int=10;
private var items_array:Array=new Array();
public function Main()
{
createItems();
readArray();
}
private function createItems():void
{
for(var i:int=0;i < numItems;i++)
{
var item:Item=new Item('nome_'+i,'cognome_'+i,i,'eMail@me.com_'+i,'city_'+i,this);
items_array.push(item);
}
}
private function readArray():void
{
trace(items_array[2].getNome());
trace(items_array[items_array.length-1].getNome());
for(var i:int=0;i < items_array.length;i++)
{
trace(items_array[i].getEmail());
trace(items_array[i].getCitta());
}
items_array[5].write();
items_array[5].tf.x=stage.stageWidth/2-items_array[5].tf.textWidth/2;
items_array[5].tf.y=stage.stageHeight/2-items_array[5].tf.textHeight/2;
}
}
}
next, I create a class named "Item.as", implemented the following way:
Code:
package
{
import flash.display.MovieClip;
import flash.text.TextField;
public class Item
{
private var nome:String;
private var cognome:String;
private var eta:int;
private var eMail:String;
private var citta:String;
private var _fla:MovieClip;
public var tf:TextField;
public function Item(nm:String,cn:String,et:int,em:String,ci:String,fla:MovieClip)
{
nome=nm;
cognome=cn;
eta=et;
eMail=em;
citta=ci;
_fla=fla;
}
public function getNome():String
{
return nome;
}
public function getCognome():String
{
return cognome;
}
public function getEta():int
{
return eta;
}
public function getEmail():String
{
return eMail;
}
public function getCitta():String
{
return citta;
}
public function write():void
{
tf=new TextField();
tf.text=nome+'\n'+cognome+'\n'+eta+'\n'+eMail+'\n'+citta;
tf.width=tf.textWidth+10;
tf.height=tf.textHeight+10;
_fla.addChild(tf);
}
}
}
Now, we will see the point of this article:
In "Main.as", I have a numerical property named "numItems" equal to 10.
I also have an Array property named "items_array" into which I insert every instances of the Item class, created next.
I then call, the method "createItems" that will instantiate as many instances of "Item" as the value of "numItems".
Therefore, I create a cycle with the value of "numItems" as the maximum iteration
for(var i:int=0;i < numItems;i++)
I define and I instantiate "Item" passing to it the values required by "Item.as" (those values are random only for demonstration purpose of this example)
var item:Item=new Item('nome_'+i,'cognome_'+i,i,'eMail@me.com_'+i,'c ity_'+i,this);
We will clear up the fact that the name "item" of the variable, is cancelled soon after it has been created. It is a local variable that at the next iteration do not exist anymore and a new one will be created with exactly the same name. The important point is that each item is an instance of the Item class to which I can pass values to add them to its properties.
I will now, insert the instance of Item into an Array
items_array.push(item);
In the Item.as class:
I created the following properties:
Code:
private var nome:String;
private var cognome:String;
private var eta:int;
private var eMail:String;
private var citta:String;
private var _fla:MovieClip;
public var tf:TextField;
to the first fifth ones, I will assign a value returned by the building function (take a look at Lesson 1 in OOP if you have any doubt about the building function):
Code:
public function Item(nm:String,cn:String,et:int,em:String,ci:String,fla:MovieClip)
{
nome=nm;
cognome=cn;
eta=et;
eMail=em;
citta=ci;
_fla=fla;
}
so, when from the "Main.a"s I say var item:Item= new Item(...), Flash carries out the code from the building function of "Item" and it assigns the values to the properties passed by Main. As the properties are private (read lesson 4 in OOP for more details), they are not accessible from the class instances. I could have declared them public but it would have not help with this tutorial. So I instead declare the method public (accessible from the instance) that retrieve the values and return them:
Code:
public function getNome():String
{
return nome;
}
public function getCognome():String
{
return cognome;
}
public function getEta():int
{
return eta;
}
public function getEmail():String
{
return eMail;
}
public function getCitta():String
{
return citta;
}
Back to "Main.as" and more precisely to the method "readArray" used for a few traces and understand how to retrieve the property of every single instance of Item placed in "items_array".
The first trace:
trace(items_array[2].getNome());
retrieve the value of the property "nome" of the instance of "Item" placed at index 2 of "items_array" (meaning the third instance).
I obtain the following output:
nome_2
The second trace:
trace(items_array[items_array.length-1].getNome());
retrieve the value of the property "nome" of the instance of "Item" placed in the last index of
"items_array" (its number is equal to the array"s length minus 1).
I obtain the following output:
nome_9
Now, using a cycle with the length of "items_array" as maximum iteration, I retrieve the properties "email" and "citta" of every single instances:
Code:
for(var i:int=0;i < items_array.length;i++)
{
trace(items_array[i].getEmail());
trace(items_array[i].getCitta());
}
and I obtain the following output:
eMail@me.com_0
city_0
eMail@me.com_1
city_1
eMail@me.com_2
city_2
eMail@me.com_3
city_3
eMail@me.com_4
city_4
eMail@me.com_5
city_5
eMail@me.com_6
city_6
eMail@me.com_7
city_7
eMail@me.com_8
city_8
eMail@me.com_9
city_9
Back to "Item.as" and we notice that I implemented the method write:
Code:
public function write():void
{
tf=new TextField();
tf.text=nome+'\n'+cognome+'\n'+eta+'\n'+eMail+'\n'+citta;
tf.width=tf.textWidth+10;
tf.height=tf.textHeight+10;
_fla.addChild(tf);
}
that creates a text field. From the property "tf", I assign the text containing the value of the properties "nome, "cognome", "email" and "citta".
I assign the real dimensions of the text dimension plus 10.
I add the text field to the stage.
Everything will be carried out when an instance of "Item" will call this precise method.
Back to "Main.as" and to the last few lines of the method "readArray"
Code:
items_array[5].write();
items_array[5].tf.x=stage.stageWidth/2-items_array[5].tf.textWidth/2;
items_array[5].tf.y=stage.stageHeight/2-items_array[5].tf.textHeight/2;
I call the method "write" from the instance of "Item" placed to the index 5 of "items_array".
"Item.as" carries out the code of the method "write" and then position it to the centre of the stage using "tf" (the textField property which is contained in every instance) and acting on the text field properties: x, y, width and height.
I obtain the following result:
We saw how to create instance of a class and how to add methods and properties to the class itself but even more, we saw how to work in a correct and modulate way.
If something would not work as desired, we would know exactly where to look for and we would keep a complete control of what we are doing.
See you soon!
Bookmarks