AS3 dynamic variable creation in DC - actionscript-3

Can variables be created dynamically without declaration when we write as Document class in AS3?
For example, from a library I'm importing sound files. Some 20 sound files.
If the code is in fla itself, we can assign in for loop like:
this["SOUND"+increasingNumber]
But in documentClass this is not working , since this refers the class here not the stage.
Any method to create variables?

When imported into your library, right click the sound file and go to its properties. Click the actionscript tab and check 'export for actionscript'. Give it a class name which you can then use in your document class to instantiate that sound.
If you named it Sound1:
var sound:Sound = new Sound1();
sound.play();
more detailed info here
[Edit to loxxy's reply] above shows how to create the variables in the document class.
To dynamically create all the sound variables, I'd recommend using an array, like so:
Suppose you named all your sounds in your library Sound1 to Sound20
import flash.utils.getDefinitionByName;
var sounds:Array = [];
var soundClass:Class;
for(var i:int = 1; i<21; i++){
soundClass = getDefinitionByName("Sound" + i) as Class;
sounds.push(new soundClass());
}

In fla when you add code, you add it into a framescript.
A framescript is a block of code repeated at a regular interval (framerate).
You can achieve that using addFrameScript like this.
However a better approach would be to not mix up framescript & the regular class methods.
You can access the 'stage' from the code but only after the added_to_stage event to be sure.
addEventListener(Event.ADDED_TO_STAGE, init);
function init(e:Event):void{
// Access 'stage' here
}

Related

As3 instances from imported swf not recognized

I have made something like a level in flash editor. made some classes inside the editor that inherited from the classes in my project. next I export my swf to later be loaded by my main code.
the thing is that once I have the swf loaded I try doing some traces to check if the instances are the correct class.
trace(map.getChildAt(i)+" D "+(map.getChildAt(i) as PointerImage));
witch outputs this: [object PointerBall] D null.
PointerBall(from flash) inherites from PointerImage(from my main code).
now if I trace this
trace((new PointerBall())+" Y "+(new PointerBall() is PointerImage));
witch outputs this: [object PointerBall] Y true
so the problem is only with instances imported from the swf.
This worked for me when I tried it. Assuming your referenced .swf is in the same application domain as the parent. The key is to have the classes that you're referencing be in a specific package. Classes that aren't in packages are in their own namespace, in both the loaded .swf and the parent. So PointerImage in your loaded .swf is not the same PointerImage that exists in your parent. It all has to do with namespace.
Just move these classes into a package folder named game and rename the package and you should be set.
package game{
import game.PointerImage
public class PointerBall extends PointerImage{
//Class code
}
}
This is what I'm working with:
function onLoad(evt:Event):void{
var c:MovieClip = evt.target.content as MovieClip;
addChild(c);
var t:BigTest = c.getChildAt(0) as BigTest;
trace(t); //[object LitteTest]
}
You have to use a LoaderContext and set the domain you want to use for either overriding the current class definitions or overriding the loaded swf ones:
var context:LoaderContext = new LoaderContext();
context.securityDomain = SecurityDomain.currentDomain;
context.applicationDomain = ApplicationDomain.currentDomain;
var ldr:Loader = new Loader();
ldr.load(urlRequest, context);
Working with class inheritance is ok but easier is working with Interface.

Flash AS3: How to create one function to play sounds from different buttons?

I am making a soundboard and I'm using actionscript. I would like to have one function with the code to play a different sound depending on which button is pressed. I will also be playing from the library rather than a URL. Here is some real code mixed with pseudo for what I want to do:
var soundEffect:SoundEffect = new SoundEffect();
sound1_btn.addEventListener(MouseEvent:CLICK, buttonName, playSoundEffect); //possible?
function playSoundEffect(e:Event, buttonName):void {
soundEffect.attachSound = buttonName + ".mp3" //pseudo code
soundEffect.play();
}
The SoundEffect class is just the name I used in Linkage. I don't know the best way to change the sound that a class represents, or the best way to do this in general. Ideally I'd like to not create 50 different classes with 50 different sound variables and 50 functions. I'd rather each button had some sort of identifier and within the function I can use the button name or identifier to assign the appropriate sound.
If you are using a Button symbol, you could use a naming convention that encodes the class name in your button name.
So if your sound effect class name was sfx_jump , you would name your instance :
sfx_jump_btn
You then set your event listener like this :
sfx_jump_btn.addEventListener(MouseEvent.CLICK, clickHandler);
What you want to do in the clickHandler function is to first generate your className String based on the buttons name property. Then you get the Class Definition via using getDefinitionByName so that you can create an instance of the sound, the following code is how you do that :
public function clickHandler(e:MouseEvent):void
{
var button:SimpleButton = e.target as SimpleButton;
// use replace to clip off the _btn suffix
var className:String = button.name.replace("_btn","");
var SoundClass:Class = getDefinitionByName(className) as Class;
var newSound:Sound = new SoundClass();
newSound.play();
}
You also need to add this import :
import flash.utils.getDefinitionByName;
Yes you can do it. Since you have multiple buttons attach a property to each button like below I attached 'soundToPlay' property to sound1_btn.
sound1_btn.soundToPlay = "1.mp3";
sound1_btn.addEventListener( MouseEvent.CLICK, handleBtnClick);
function handleBtnClick( e:Event ):void{
soundEffect.attachSound = e.target.soundToPlay;
soundEffect.play();
}
#hrehman have the answer for you, but if you button class don't have the property soundToPlay you could use the name property as an ID. and get back with the currentTargetproperty of the event.
sound1_btn.name = "Sound1";
sound1_btn.addEventListener(MouseEvent:CLICK, playSoundEffect);
function playSoundEffect(e:Event):void {
soundEffect.attachSound = e.currentTarget.name + ".mp3";
soundEffect.play();
}

multiple instance of class in as3

i have a function to load sound in main document class in as3,this function accept input link and begin to load this path for example same function :
private function loadSound(url:String):void{
var req:String = 'sound/'+url+'.mp3'
sound_path = new URLRequest(req)
main_sound = new Sound()
main_sound.load(sound_path)
main_sound.play()
}
when this function call, sound object multiple start playing,how i solve this problem for play only sound class in this time ?
Place this at beginning of your loadSound() function:
flash.media.SoundMixer.stopAll(); //Stops all music already playing
If you have this code in a keyframe make sure you are calling stop() to prevent it from executing the code over and over.
If you have it in a class file (.as) it sounds like it is getting called twice

How to duplicate loaded *.swf without setting a class name

I have read this article about abstracting assets from ActionScript:
Abstracting Assets from Actionscript in AS3.0 – Asset Libraries and DuplicateMovieClip
But it requires to set the Linkage Class name. How can I get the same result without setting the linkage class name?
What I want to do is to cache a loaded asset, and use the cached version every time I request the same URL. A solution is to clone the loaded DisplayObject, but I think it's unnecessary since I only want a new copy.
I think the way to do that is to use byte arrays
here's a quick sample
// once you load your data...
private function loaderComplete(event:Event):void
{
var loaderInfo:LoaderInfo = LoaderInfo(event.target);
var byteArray:ByteArray = loaderInfo.bytes; //<- this will create your byte array
}
you can then use byteArray.readObject(); to generate the new class;
look at senocular's post at http://www.kirupa.com/forum/showthread.php?p=1897368
where he's got a function like this:
function clone(source:Object):* {
var copier:ByteArray = new ByteArray();
copier.writeObject(source);
copier.position = 0;
return(copier.readObject());
}
//that you use with
newObjectCopy = clone(originalObject);
hope this gets you started
As of Flash 11.3, there's a function named getQualifiedDefinitionNames that tells me exactly what linkage names should I use with getDefinition, so there's no need to know the values beforehand.

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.