how to create a AS3 dynamic class and how to use it? - actionscript-3

What is a dynamic class and what are its uses and how to create and use a dynamic class?
Can anyone guide me to a good tutorial please?

Here You can find basic info : http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/statements.html#dynamic
Dynamic class allow You to add additional dynamic params to object in run-time .
For example : Sprite isnt dynamic , so You cannot do thing like :
var sprite:Sprite = new Sprite ();
sprite["value"] = 10; // this will throw ReferenceError
But MovieClip is dynamic instance that allow You to add dynamic params :
var mclip:MovieClip = new MovieClip();
mclip["value"] = 10;
To make class instance dynamic , You have to add 'dynamic' key word to declaration :
public dynamic class MyClass { ...

A dynamic class is basically one that can be modified at runtime. One of the main uses of this feature is when extending the Proxy class.
A couple of good examples:
http://manishjethani.com/archives/2008/08/25/jsonobject-for-reading-and-writing-json-in-actionscript
http://manishjethani.com/archives/2008/12/19/guaranteeing-enumeration-order-in-for-in-loops

Related

Declaring variable in different class not working as3

I have a public var called monster number in my monster class.
public var monsterNumber:int;
And in my document class, I want to give monsterNumber a number, lets say 5.
It's still tracing monsterNumber as 0 in my monster class, but 5 in my document class. Is there any way to change this var in my document class?
Here's an example of how you can create a instance of Monster and modify it's property monsterNumber :
// in your document class
var monster:Monster = new Monster();
monster.monsterNumber = 1;
You can define your variable as a static variable so you can change its value from anywhere you want.

As3 imported custom class won't access components at main stage

I have this situation. I was building all in code, but it's a little painful, so I made a interface with components using the Flash drawing capabilities.
I got a main class, as usual, with the interface in a MovieClip instance called "AreaEdit". In my custom class "EditorHTML" there is a Sprite:
private var dTela:Sprite;
So the constructor is like this:
public function EditorHTML(instEdit) {
this.Parags = new Array();
this.dTela = instEdit;
trace("dTela: "+this.dTela.width+" x "+this.dTela.height);
}
At the main class:
Escrit = new EditorHTML(AreaEdit);
So trace displays the dimensions of the box, as expected. However, at the custom class, if I try to access an instance inside like this:
this.dTela.cxEdit.addEventListener(Event.CHANGE, atualizar);
An error is returned: /Library/WebServer/Documents/as3/bibliotecas_externas/com/gustavopi/txt/EditorHTML.as, Line 49 1119: Access of possibly undefined property cxEdit through a reference with static type flash.display:Sprite.
I did a test and the same instance "cxEdit" is available in main class. So it seams the components instances are not available for a custom class. How do I solve this?
Try to call it like this:
Sprite( Sprite(this.dTela).getChildByName("cxEdit")).addEventListener(Event.CHANGE, atualizar);
In case that cxEdit is a Sprite too.
Edited: cxEdit must be a TextArea. So it can be done like this:
var cxEdit:TextArea = TextArea(Sprite(this.dTela).getChildByName("cxEdit"));
cxEdit.addEventListener(Event.CHANGE, atualizar);
To make it easier for the rest of the code...
From what I can see, you are trying to access the "cxEdit" as a property of Sprite (dTela), which is not a Sprite property, hence the error.
Could you perhaps pass in AreaEdit.cxEdit as the argument instead of just AreaEdit?

Overriding public method in dynamically loaded class with AS3 and getDefinitionByName()

I have two SWFs: main.swf and external.swf. main.swf needs to access some methods in external.swf, so it loads external.swf into itself and uses getDefinitionByName("package.Class") to access the class and one of its methods:
var ExternalClass = getDefinitionByName("package.Class") as Class;
var ClassInstance = new ExternalClass();
var NeededFunction:Function = ClassInstance["NeededFunction"] as Function;
var response:String = NeededFunction(param);
Now, I need to extend the functionality of NeededFunction (which is a public method)... I know it's possible to override public methods, but how would I go about this with a dynamically loaded class?
I was thinking I could do something like this, but it doesn't work:
var ClassInstance["NeededFunction"] = function(param1:uint):String {
var newString = "Your number is: "+param1.toString(); //New functionality
return newString;
}
Another way to deal with this could be to have the classes in a package that's accessible by both SWFs. Just add the classes' root folder to your Actionscript path .
Instead of getting a class by using getDefinitionByName , you simply import it. As for overriding , you can create a Class that overrides one of the classes , or you can create an Interface.
import com.yourlocation.ExternalClass;
var external:ExternalClass = new ExternalClass();
Using FlashDevelop this is pretty simple to fix.
Right click your included swc from the Project list.
Choose options then "include library (complete library)".
..you can now use getDefinitionByName to get a unreferenced class from your swc file.

ActionScript Accessing Functions/Vars From Outside Of Class

how can i call public functions or vars of a sprite class from another class (or frame script)? i keep getting 1061: Call to a possibly undefined method getSide through a reference with static type flash.display:Sprite.
//Framescript
var a:Sprite = new customRect();
addChild(a);
a.getSide();
//.as file
package
{
import flash.display.Sprite;
public class customRect extends Sprite
{
public var side:Number;
private function customRect()
{
var box:Sprite = new Sprite();
box.graphics.beginFill();
box.graphics.drawRect(0, 0, 200, 200);
box.graphics.endFill();
side = box.width;
}
public function getSide():void
{
trace(side);
}
}
}
You'll need to type the other class as whatever type of class it is. Sprite doesn't, by default, have whatever property you're trying to access, so you can't just do mysprite.myRandomVariableName. However, if you happen to know mysprite is really of type MyClass then you can do MyClass(mysprite).myRandomVariableName or (mysprite as MyClass).myRandomVariableName. When using the as keyword, note that the typed mysprite will evaluate to null if mysprite is not really of type MyClass. Trying to type mySprite to MyClass using the prior method will throw an error if mysprite is not of type MyClass.
Alternatively, I believe you can use square brackets to access a sprite's dynamic properties (i.e. mysprite['myRandomVariableName'], however it's really better practice to strongly type your objects.
//edit, since you posted a code sample:
All you need here is:
var a:CustomRect = new CustomRect();//note that since CustomRect is a class name, it should be captialized.
Are you trying to call actual methods of the Sprite class or ones that you've added to a subclass of Sprite? My guess is that you need to cast the variable to the actual class that you are using. So instead of:
someReference.yourFunction();
you could try:
YourClass(someReference).yourFunction();
... this is only needed if you do not control the typing of someReference - if you do you can simply define it using var someReference:YourClass to make it known to the compiler that is is a var of YourClass type, and not of Sprite.
UPDATE after your code example was added, change:
var a:Sprite = new customRect();
to
var a:customRect = new customRect();
so the compiler knows it is a customRect and not a 'general' Sprite.
as an aside: it is custom to start classnames with an uppercase letter: so use CustomRect instead of customRect.

AS3 - How to assign names or tags to loader?

I have a list of images that i’ve loaded with the Loader class, but I’m having a tough time assigning them unique names.
I need unique names because I want to remove certain images after a while.
Is there a way to assign loaders a name or some unique tag so i can remove them later? thanks.
Here's part of my code
for (var i = startnum; i < endnum; i++){
var thumb = panels[i].#THUMB;
var thumb_loader = new Loader();
thumb_loader.load(new URLRequest(thumb));
thumb_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, thumbLoaded);
thumb_loader.name = i;
thumb_loader.x = (thumb_width + 20)*i;
}
I tried to use getChildByName in another function..
var myLoader:Loader = getChildByName( "1" ) as Loader;
myLoader.unload();
But it's giving me
Error #1009: Cannot access a property or method of a null object reference.
I tried to put thumb_loader as global variable, and do this
var myLoader:Loader = thumb_loader.getChildByName( "1" ) as Loader;
But it's still not working.
Thanks.
All display objects in ActionScript 3 have a name property. Whenever you create a Loader object you can assign a name to it like so:
var myLoader:Loader = new Loader();
myLoader.name = "myUniqueName";
myLoader.load( .... );
addChild( myLoader );
If you'd like to refer to the loader by the name you gave it, use the getChildByName() method.
var myLoader:Loader = getChildByName( "myUniqueName" ) as Loader;
myLoader.unload();
Please be mindful that getChildByName() will only work after you've added the Loader(s) to the display list using addChild(). Otherwise, you'll have to create something to store the references to the Loader objects in, such as an Array and refer to the loaders via that Array. For example, outside your loop you could create an Array named loadersArr. In your loop you would do:
loadersArr["uniqueName"] = thumb_loader;
Then you can refer to your loaders with your unique name through the loadersArr Array.
var loaderToUnload:Loader = loadersArr["uniqueName"];
loaderToUnload.unload();
Without seeing more of your code, its difficult to understand the scope in which this code resides and where any other code that may try to reference these Loaders resides.
Not sure I 100% understand your problem, but why not put them in an object map rather than a list and generate unique names for them if you don't have them...
var img:Image;
var img_map:Object = new Object();
var last_added:int = 0;
for each (img in yourListOfImages)
{
img_map["img_"+last_added] = img;
last_added++;
}
Depending on your environment (Flex or Flash) you can use a UID generator instead of my simplistic unique names above.
package
{
import flash.display.Loader;
public dynamic class DynamicLoader extends Loader
{
public function DynamicLoader()
{
super();
}
}
}
I believe the Loader class is a sealed class so you would want to create this class and use it instead of the normal Loader class to give it any attribute you want. I also believe that without using this DynamicLoader instead of the normal Loader, the Loader class does have the name property available to it.