Setting default values for object properties in AS3 - actionscript-3

I'm an actionscript newbie so please bear with me. Below is a function, and I am curious how to set default property values for objects that are being created in a loop.
In the example below, these propeties are the same for each object created in the loop: titleTextField.selectable, titleTextField.wordWrap, titleTextField.x
If you pull these properties out of the loop, they are null because the TextField objects have not been created, but it seems silly to have to set them each time. What is the correct way to do this. Thanks!
var titleTextFormat:TextFormat = new TextFormat();
titleTextFormat.size = 10;
titleTextFormat.font = "Arial";
titleTextFormat.color = 0xfff200;
for (var i=0; i<arrThumbPicList.length; i++) {
var yPos = 55 * i
var titleTextField:TextField = new TextField();
titleTextField.selectable = false;
titleTextField.wordWrap = true;
titleTextField.text = arrThumbTitles[i];
titleTextField.x = 106;
titleTextField.y = 331 + yPos;
container.addChild(titleTextField);
titleTextField.setTextFormat(titleTextFormat);
}

There are basically three options here.
You could create a custom class that
acts as a proxy to a TextFormat.
TextFormatProxy, for instance, which
could create a TextFormat in it's
constructor and set each of your
default values. See this link
or google "AS3 proxy pattern."
You could write a custom class that
extends TextFormat and likewise, set
these default values in the
constructor, or in a function of
your choosing.
You could use a little helper
function like this
package {
import flash.display.Sprite;
public class DefaultProperties extends Sprite{
public var s:Sprite;
public function DefaultProperties() {
s = new Sprite();
s.graphics.beginFill(0x00ff00, 1);
s.graphics.drawRect(0, 0, 100, 100);
s.graphics.endFill();
this.setDefaults(s, {x:100, y:200, scaleX:.5});
this.addChild(s);
}
function setDefaults($obj:*, $properties:Object):void {
for (var i in $properties) {
$obj[i] = $properties[i];
}
}
}
}

Without knowing the surrounding code, I'd suggest putting any construction logic in a factory object. If that's overkill, then I'd say your code is fine. Pulling it out of the loop and into a helper method is really just adding another layer of indirection which is not only harder to read, but it's also less efficient since you're introducing another method call on the stack.
Using a factory object is good if your class is really not interested in how things are created, but rather just needs one or more instance of something. That way, the factory is responsible for the creation of the object and you get a nice separation of concerns.
I wouldn't recommend creating a proxy structure that only has the purpose of setting the properties of your instance. I think it's an anti pattern because it favors inheritance over composition and it does so solely for the purpose of code re-use. But doing this means you're locking yourself to that specific implementation, which is likely not what you want. Just because your textfield has certain value, doesn't mean that it is a different type.
This is how your code could look when using the factory pattern, first out, the format factory:
public interface FormatFactory
{
function getInstance():TextFormat;
}
public class TitleFormatFactory implements FormatFactory
{
public function getInstance():TextFormat
{
var format:TextFormat = new TextFormat();
format.size = 10;
format.font = "Arial";
format.color = 0xfff200;
return format;
}
}
Factories may or may not be parameterized:
public interface TextFieldFactory
{
function getInstance(text:String, position:Point, format:TextFormat):TextField;
}
public class TitleFactory implements TextFieldFactory
{
public function getInstance(text:String, position:Point, format:TextFormat):TextField
{
var title:TextField = new TextField();
title.selectable = false;
title.wordWrap = true;
title.text = text;
title.x = position.x;
title.y = position.y;
title.setTextFormat(format);
return title;
}
}
Lastly, this is how you'd use the code:
var formatFactory:FormatFactory = new TitleFormatFactory();
var titleFactory:TextFieldFactory = new TitleFactory();
var format:TextFormat = formatFactory.getInstance();
for (var i = 0; i < arrThumbPicList.length; i++)
{
var position:Point = new Point(106, 331 + 55 * i);
var title:TextField = titleFactory.getInstance(text, position, format);
container.addChild(title);
}
Besides being readable, a huge benefit is that you can now swap the implementations of the factories and thus changing what kind of components you're using, without having to change your actual logic. All you have to do is change the references to the factories.
Also, by separating the concerns you make it easier to focus on one aspect of your code and thus run less of a risk of introducing errors and if you still do, those are often easier to spot and fix. More-over, it's much easier to unit test code when you separate concerns and more importantly, creation logic from business logic.

If I were to approach the same problem I'd use the same as you posted, just because making the new data structure would be unnecessary. An alternative would be to create a function that accepts the textbox as a parameter:
for (var i=0; i<arrThumbPicList.length; i++) {
var titleTextField:TextField = new TextField();
setProperties(titleTextField,i);
}
function setProperties(txt:TextField,offset:int){
var yPos = 55 * offset;
txt.selectable = false;
txt.wordWrap = true;
txt.text = arrThumbTitles[offset];
txt.x = 106;
txt.y = 331 + yPos;
container.addChild(titleTextField);
titleTextField.setTextFormat(titleTextFormat);
i++;
}
Although I'd probably go with the way you posted unless you're adding things from multiple for loops.

Your code is ok for me. Simple and effective. You only have 3 fixed parameters, for me it's not necessary to do more :
titleTextField.selectable = false;
titleTextField.wordWrap = true;
titleTextField.x = 106;
Unlike the other answer, I would do a helper function to get the textfield with all fixed parameters (I would do that ONLY if there was a LOT of stuff to do).
function createMyContextTextField():TextField{
textfield:TextField = new textField();
textfield.selectable = false;
textfield.wordWrap = true;
textfield.x = 106;
return textfield;
}

Related

How can I translate keyword prototype in AS3 to Haxe?

I have the below AS3 code, and I want to translate it to Haxe. But I don't know how to deal with the keyword prototype. Who can help me? Thanks.
var style = new CSSStyleDeclaration();
style.defaultFactory = function():void
{
this.disabledOverlayAlpha = 0;
this.borderStyle = "controlBar";
this.paddingTop = 10;
this.verticalAlign = "middle";
this.paddingLeft = 10;
this.paddingBottom = 10;
this.paddingRight = 10;
};
if(chain == null) chain = {};
style.defaultFactory.prototype = chain;
chain = new style.defaultFactory();
style.defaultFactory = function():void
{
this.fontWeight = "bold";
};
style.defaultFactory.prototype = chain;
chain = new style.defaultFactory();
style.defaultFactory = function():void
{
this.backgroundSize = "100%";
this.paddingTop = 24;
this.backgroundColor = 8821927;
this.backgroundImage = ApplicationBackground;
this.horizontalAlign = "center";
this.backgroundGradientAlphas = [1,1];
this.paddingLeft = 24;
this.paddingBottom = 24;
this.paddingRight = 24;
};
style.defaultFactory.prototype = chain;
chain = new style.defaultFactory();
Ok, I poked this a bit, and now I kind of figured out, what that piece of code does. This knowledge won't help you to port your code to HAXE, but it will help you understand what it is about and to compose a decent HAXE-style alternative.
First, the part about instantiating, functions and working with prototypes. As it turned out, if you invoke the new operator on an unbound function (does not work on class methods):
The new empty class-less generic Object is created.
Its reference is passed to the said function as this.
The function can add and modify the object's fields and methods.
Ultimately, the reference to that Object is returned.
Then, it works (as I mentioned in my comments above) very much the way classes worked back then in AS1 and Flash 6.
If that function has a prototype and it is too a generic Object, then it is added to the newly created one as a... how to put it... a bottom layer Object which adds its fields to the top layer Object.
I understand that it sounds difficult, so there's an explanatory example that somehow sheds some light on it all:
public class Proton extends Sprite
{
public function Proton()
{
super();
var P:Function;
// Empty.
P = new Function;
create("First:", P);
// Empty with prototype.
P.prototype = {c:3, d:4};
create("Second:", P);
// Non-empty.
P = function():void
{
this.a = 1;
this.b = 2;
};
create("Third:", P);
// Non-empty with prototype.
P.prototype = {a:5, f:6};
create("Fourth:", P);
}
// Instantiates the F and outputs the result.
private function create(prefix:String, F:Function):void
{
var A:Object = new F;
trace(prefix + "\nJSON:" + JSON.stringify(A) + "\nREAL:" + explore(A) + "\n");
}
// Same as JSON.stringify, but also looks into the prototype.
private function explore(O:Object):String
{
var result:Array = new Array;
for (var akey:String in O)
{
result.push('"' + akey + '":' + O[akey]);
}
return "{" + result.join(",") + "}";
}
}
So, the output is:
First:
JSON:{}
REAL:{}
Second:
JSON:{}
REAL:{"d":4,"c":3}
Third:
JSON:{"b":2,"a":1}
REAL:{"b":2,"a":1}
Fourth:
JSON:{"b":2,"a":1}
REAL:{"b":2,"a":1,"f":6,"a":1}
As you can see, JSON.stringify exports only the top layer object, while direct for iteration goes through all the layers, top to bottom, and even processes the duplicate keys (but the top layer value shadows what's below).
Second, how it all is related to your code. These factory and defaultFactory functions are used in some CSS-related class to form an Object representation of the style: https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/styles/CSSStyleDeclaration.html
So, you can use that prototype hack to form a generic Object with a chain of layers upon layers of CSS declarations... probably. You saw that JSON doesn't perceive anything but the top layer, I have no idea if CSS classes act differently or not.
I think, working with CSS should be less hack-y and more straightforward.
Good luck figuring it out.

Loading images using the URLRequest

recently started to learn ActionScript 3 and already have questions.
question remains the same: I'm uploading a picture using the object Loader.load (URLRequest). Loaded and displayed a picture normally. But it is impossible to read the values of attributes of the image height and width, instead issued zero. That is, do this:
var loader:Loader=new Loader();
var urlR:URLRequest=new URLRequest("Image.jpg");
public function main()
{
loader.load(urlR);
var h:Number = loader.height;// here instead of the width of the image of h is set to 0
// And if you do like this:
DrawText(loader.height.toString(10), 50, 50); // Function which draws the text as defined below
// 256 is displayed, as necessary
}
private function DrawText(text:String, x:int, y:int):void
{
var txt:TextField = new TextField();
txt.autoSize = TextFieldAutoSize.LEFT;
txt.background = true;
txt.border = true;
txt.backgroundColor = 0xff000000;
var tFor:TextFormat = new TextFormat();
tFor.font = "Charlemagne Std";
tFor.color = 0xff00ff00;
tFor.size = 20;
txt.x = x;
txt.y = y;
txt.text = text;
txt.setTextFormat(tFor);
addChild(txt);
}
Maybe attribute values must be obtained through the special features, but in the book K.Muka "ActionScript 3 for fash" says that it is necessary to do so. Please help me to solve this. Thanks in advance.
Well it's simple.
Flash is focused on the Internet, hence such problems.
If you wrote loader.load (urlR); it does not mean loaded. Accordingly, prior to the event confirming the end of loading, in loadare Null
if, instead of certain functions would be more code that would perhaps tripped your approach.
Yeah plus still highly dependent on the size of the file that you read.
Well, in general it all lyrics. Listen event on loader.contentLoaderInfo.addEventListener (Event.INIT, _onEvent), onEvent and read properties.
You need to wait for your image to load to be able to get values out of it.
Attach an eventListener to your URLLoader.
var urlR:URLRequest = new URLRequest("Image.jpg");
loader.load(urlR);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_complete);
function loader_complete(e:Event): void {
// Here you can get the height and width values etc.
var target_mc:Loader = evt.currentTarget.loader as Loader;
// target_mc.height , target_mc.width
}
Loader

Adding a dynamically created DataGrid as child or element does not work

I am trying to develop an application in AS3. What I am really trying to achieve is to have only one datagrid and having it show, you say, three different set of datas. (the real count will be changing dynamically, and it does not matter as the problem is not relevant with this) Yes, it has to be only one datagrid because of you know, I need a compact interface.
The class "Sonuc" has three properties which are string versions of inputs from constructor. A typical "Sonuc" object is something like this.
var sonuc1:Sonuc = new Sonuc(1,1,false);
//sonuc1.num = "1"
//sonuc1.type = "1"
//sonuc1.isTrue = "No"
The reason that I have informed you about "Sonuc" class is that I wanted you to know that class was not something too complicated. And x.mxml is the test mxml where I only load the class for testing purposes.
This is what I have coded so far
public class ResultInterface extends UIComponent
{
private const desiredWidth:int = 250;
private const desiredHeight:int = 150;
private const sonuc1:Sonuc = new Sonuc(1,1,false);
public var tablo:DataGrid = new DataGrid();
public var kolonArray:Array = new Array ();
public var sonucArray:Array = new Array ();
public var currentIndex:int = new int ();
public var prevButon:Button = new Button();
public var nextButon:Button = new Button();
public function ResultInterface():void
{
currentIndex = 0;
super();
tablo = new DataGrid();
width=desiredWidth+40;
height=desiredHeight+60;
this.tablo.width = desiredWidth;
this.tablo.height = desiredHeight;
this.tablo.x = 20;
this.tablo.y = 40;
prevButon.x = 10;
prevButon.y = genislik/2 - 10;
prevButon.width =
prevButon.height = 10;
nextButon.x = genislik +20;
nextButon.y = genislik/2 -10;
nextButon.width =
nextButon.height = 10;
var referansColl:ArrayCollection = new ArrayCollection();
sonucArray.push(referansColl);
tablo.dataProvider = sonucArray[currentIndex];
var sampleCol:DataGridColumn = new DataGridColumn();
sampleCol.dataField = "num";
sampleCol.headerText = "Number";
var sampleCol2:DataGridColumn = new DataGridColumn();
sampleCol2.dataField = "type";
sampleCol2.headerText = "Type";
var sampleCol3:DataGridColumn = new DataGridColumn();
sampleCol3.dataField = "isTrue";
sampleCol3.headerText = "Is it true?";
kolonArray.push(sampleCol,sampleCol2,sampleCol3);
tablo.columns = kolonArray;
this.addElement(tablo); //**** this is the problematic line
this.addChild(oncekiButon);
this.addChild(sonrakiButon);
}
public function getNewSonuc(incoming:Sonuc):void
{
sonucArray[currentIndex].addItem(incoming);
}
public function newTablo():void
{
var newTablo:ArrayCollection = new ArrayCollection();
currentIndex = sonucArray.push(newTablo);
}
public function prev(evt:Event):void //I haven't written event listeners yet
{
if(currentIndex > 0)
currentIndex--;
nextButon.enabled = true;
if(currentIndex == 0)
prevButon.enabled = false;
}
public function birSonrakine(evt:Event):void
{
if(currentIndex < sonucArray.length)
currentIndex++;
prevButon.enabled = true;
if(currentIndex == sonucArray.length)
nextButon.enabled = false;
}
in this version, I get a syntax error "call to a possibly undefined method addElement"
I also tried having the base class as "Sprite" and "Canvas"
when I used addChild instead of addElement, then I get runtime error "addChild is not available to this class"
when I just commented the problematic line out, everything was loaded perfectly but the datagrid itself.
Note that error occurs before sending in some data (Sonuc) to datagrid.
and when I tried with canvas and with addelement, I get "Cannot access a property or method of a null object reference" with some weird functions and classes and packages.
1009: Cannot access a property or method of a null object reference.
at mx.styles::StyleProtoChain$/initProtoChainForUIComponentStyleName()[E:\dev\4.y\frameworks\projects\framework\src\mx\styles\StyleProtoChain.as:358]
at mx.styles::StyleProtoChain$/initProtoChain()[E:\dev\4.y\frameworks\projects\framework\src\mx\styles\StyleProtoChain.as:171]
at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::initProtoChain()[E:\dev\4.y\frameworks\projects\framework\src\mx\core\UIComponent.as:10926]
at mx.core::UIComponent/regenerateStyleCache()[E:\dev\4.y\frameworks\projects\framework\src\mx\core\UIComponent.as:10989]
at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::addingChild()[E:\dev\4.y\frameworks\projects\framework\src\mx\core\UIComponent.as:7465]
at mx.core::UIComponent/addChild()[E:\dev\4.y\frameworks\projects\framework\src\mx\core\UIComponent.as:7162]
at mx.controls.listClasses::ListBase/createChildren()[E:\dev\4.y\frameworks\projects\mx\src\mx\controls\listClasses\ListBase.as:3772]
at mx.controls::DataGrid/createChildren()[E:\dev\4.y\frameworks\projects\mx\src\mx\controls\DataGrid.as:1143]
at mx.core::UIComponent/initialize()[E:\dev\4.y\frameworks\projects\framework\src\mx\core\UIComponent.as:7634]
at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::childAdded()[E:\dev\4.y\frameworks\projects\framework\src\mx\core\UIComponent.as:7495]
at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::childAdded()[E:\dev\4.y\frameworks\projects\mx\src\mx\core\Container.as:3974]
at mx.core::Container/addChildAt()[E:\dev\4.y\frameworks\projects\mx\src\mx\core\Container.as:2618]
at mx.core::Container/addChild()[E:\dev\4.y\frameworks\projects\mx\src\mx\core\Container.as:2534]
at mx.core::Container/addElement()[E:\dev\4.y\frameworks\projects\mx\src\mx\core\Container.as:2981]
at genel.siniflar::ResultInterfaceArayuz()[C:\Users\Ege\Adobe Flash Builder\brainswift2\src\genel\siniflar\ResultInterface.as:95]
at x()[C:\Users\Ege\Adobe Flash Builder\brainswift2\src\x.mxml:27]
at _x_mx_managers_SystemManager/create()[_x_mx_managers_SystemManager.as:54]
at mx.managers.systemClasses::ChildManager/initializeTopLevelWindow()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\systemClasses\ChildManager.as:311]
at mx.managers::SystemManager/initializeTopLevelWindow()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\SystemManager.as:3057]
at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::kickOff()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\SystemManager.as:2843]
at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::preloader_completeHandler()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\SystemManager.as:2723]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.preloaders::Preloader/timerHandler()[E:\dev\4.y\frameworks\projects\framework\src\mx\preloaders\Preloader.as:542]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
I really need your help folks, please answer as soon as possible.
Well, I tried calling "addElement" from outside of the constructor, and it worked. However I don't know what did exactly cause this error and I know that my solution is not a legitimate one. And I would like to learn proper solution to this problem.
changes to resultInterface.as
// this.addElement(tablo); **** this is the problematic line, we have commented it out
this.addChild(oncekiButon);
this.addChild(sonrakiButon);
changes to x.mxml
public function onCreationComplete(evt:Event):void
{
showResult.addElement(showResult.tablo);
addElement(showResult);
}

AS3 multiple textfields made easy

I am working on a Results page for my game as well as upgrade page and looking for an easy way to do many textfields. I have a format for my text that takes care of font, colour, and size, but looking for an easy way to do the width and height of textfields to increase all at the same time.
I have been informed about a "with" keyword that may work but do not understand how to implement this within my program and essentially want to shorten my results class if possible.
Thank you,
The best way would be to create a custom function for generating textfield.
The example can be found in the livedocs itself.
So something like the following should suffice :
private function createCustomTextField(x:Number, y:Number, width:Number, height:Number):TextField {
var result:TextField = new TextField();
result.x = x;
result.y = y;
result.width = width;
result.height = height;
return result;
}
You may also set a default value to each attribute in the function.
private function createCustomTextField ( x:Number= <Default Value>, ...
Use it to add a textfield inside the container form.
var container:Sprite = new Sprite(); // New form container
container.addChild(createCustomTextField (20,20,50,50)); // Text Filed 1
container.addChild(createCustomTextField (20,50,50,50)); // Text Filed 2
addChild(container); // Add to current class
You may want to modify the function to accept a name so that each variable can be accessed later.
As far as I am aware, you can't use a "with" keyword to target multiple objects. Here's the documentation for it: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/statements.html#with
What I've done in the past is just make an array of all the targets, and then write a loop to apply properties to each:
var textFormat:TextFormat = generateMyCustomTextFormat();
var textField1:TextField = new TextField();
var textField2:TextField = new TextField();
//...
var textField3:TextField = new TextField();
var targets:Array = [textField1, textField2, textField3];
for(var i:int=0; i<targets.length; i++)
{
targets[i].defaultTextFormat = textFormat;
targets[i].width = 250;
//...
}

Add multiple movieclips, not replacing the old ones

So, in short, my problem is this. I am using a variable which is a movieclip loaded from an external swf. I want to "spawn" multiple instances of the movieclip that all react to the same code, so for example if I say var1.x = 100, they all are at 100x. But my problem is when I run addChild(var1) multiple times(I'm not actually typing in addChild(var1) over and over, I just have it set to add them at random times), the new child just replaces the old one, instead of making multiple movieclips. Should I do something like
var var1:MovieClip
var var2:MovieClip = new var1 ?(which doesnt work for me btw, gives me errors)
Oh, heres the code, and also, I am pretty new to as3 fyi, still don't even know how arrays work, which was my second guess to the problem.
var zombieExt:MovieClip;
var ldr2:Loader = new Loader();
ldr2.contentLoaderInfo.addEventListener(Event.COMPLETE, swfLoaded2);
ldr2.load(new URLRequest("ZombieSource.swf"));
function swfLoaded2(event:Event):void
{
zombieExt = MovieClip(ldr2.contentLoaderInfo.content);
ldr2.contentLoaderInfo.removeEventListener(Event.COMPLETE, swfLoaded2);
//zombieExt.addEventListener(Event.ENTER_FRAME, moveZombie)
zombieExt.addEventListener(Event.ENTER_FRAME,rotate2);
function rotate2 (event:Event)
{
var the2X:int = playerExt.x - zombieExt.x;
var the2Y:int = (playerExt.y - zombieExt.y) * 1;
var angle = Math.atan(the2Y/the2X)/(Math.PI/180);
if (the2X<0) {
angle += 180;
}
if (the2X>=0 && the2Y<0) {
angle += 360;
}
//angletext.text = angle;
zombieExt.rotation = (angle*1) + 90;
}
playerExt.addEventListener(Event.ENTER_FRAME,spawn1);
function spawn1 (event:Event)
{
if(playerExt.y < 417)
{
var someNum:Number = Math.round(Math.random()*20);
if(someNum == 20)
{
addChild(zombieExt)
zombieExt.x = Math.round(Math.random()*100)
zombieExt.y = Math.round(Math.random()*100)
}
}
}
}
addChild() does not create new instances. It is used to add an already created instance to the display list. If you call addChild() multiple times on the same instance then you are just readding itself.
Also each instance is unique, you can not globally change the x position of an instance by changing another one of them. What you would do is as Henry suggests and add each new instance of a MovieClip into an array, then whenever you change something you can loop through the array and apply the changes to each instance.
You can not go var2:MovieClip = new var1 either since var1 is an instance and not a class.
Here's a different method of receiving loaded MovieClips, which i use when i need many copies of the item.
in the swf you are loading, give the target movieclip a linkage name in the library, for this example i will use "foo"
private var loadedSwfClass:Class
private var newZombie:MovieClip;
private var zombieArray:Array = new Array();
function swfLoaded2(event:Event):void
{
loadedSwfClass = event.target.applicationDomain.getDefinition("foo");
for(var n:int = 0; n<100; n++){
newZombie = new loadedSwfClass()
zombieArray.push(newZombie);
addChild(newZombie);
}
}
as per this tutorial
http://darylteo.com/blog/2007/11/16/abstracting-assets-from-actionscript-in-as30-asset-libraries/
although the comments say that
var dClip:MovieClip = this;
var new_mc = new dClip.constructor();
this.addChild(new_mc);
will also work.
It sounds like you might be accessing the same instance some how in your code. It would be helpful to see your code to figure this one out.
If I wanted to load in one swf files and add a MovieClip multiple times I would place it in the library of that SWF file. And then instantiate it and store it into an object pool or a hash or some list.
// after the library were finished loading
var list:Array = [];
for(var i:int=0; i<10; i++) {
var myCreation:MySpecialThing = new MySpecialThing();
addChild(myCreation);
list.push(myCreation);
}
where my library would contain a linkage to the class MySpecialThing.
Calling addChild(var1) multiple times on the same parent doesn't have any effect (unless you have added another child to the same parent in between, in which case it will change the child index and bring var1 to the top). If you call it on different parents, it will just change the parent of var1, doesn't duplicate. Call addChild(new MovieClassName()) at random times instead to add new copies of it. Use an array as suggested here to access them later.
Wow, thanks there henry, just using an array did exactly what I needed, and made things alot simpler.
when you load in using a loader you only get 1 instance, however you can do some funky reflection to determine what class type the given loader.content is, and then instantiate them using that. For Example:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_completeHandler);
loader.load(new URLRequest("ZombieSource.swf"));
var classType:Class;
function loader_completeHandler(evt:Event):void
{
var loadInfo:LoaderInfo = (evt.target as LoaderInfo);
var loadedInstance:DisplayObject = loadInfo.content;
// getQualifiedClassName() is a top-level function, like trace()
var nameStr:String = getQualifiedClassName(loadedInstance);
if( loadInfo.applicationDomain.hasDefinition(nameStr) )
{
classType = loadInfo.applicationDomain.getDefinition(nameStr) as Class;
init();
}
else
{
//could not extract the class
}
}
function init():void
{
// to make a new instance of the ZombieMovie object, you create it
// directly from the classType variable
var i:int = 0;
while(i < 10)
{
var newZombie:DisplayObject = new classType();
// your code here
newZombie.x = stage.stageWidth * Math.random();
newZombie.x = stage.stageHeight * Math.random();
i++;
}
}
Any problems let me know, hope this helps.