AS3, variables outside event handler function? - actionscript-3

I have searched arond, but cant seem to find a proper answer to this. Lets say we have a super basic program which adds two numbers from 2 input text fields togehter and prints them out. Why cant i accses variables outside the event handler function? And what do i have to do in order to achieve this? The code is on a frame.
Why does this example not work? :
btn.addEventListener(MouseEvent.CLICK, cal);
var fnum:Number = Number(txt1.text);
var snum:Number = Number(txt2.text);
function cal(evt:MouseEvent){
txtOutput.text = String(fnum + snum);
}
And this example work?:
btn.addEventListener(MouseEvent.CLICK, cal);
function cal(evt:MouseEvent){
var fnum:Number = Number(txt1.text);
var snum:Number = Number(txt2.text);
txtOutput.text = String(fnum + snum);
}

I hate to be this guy, but I can't get it to replicate whats happening for you..
The only assumption that I can make is that the txt1.text & txt2.text aren't set yet when the button is clicked in example 1. Feel free to zip your project and dropbox it to me if you want me to investigate further :)

Related

Get selected index of Datagrid

I want to know, how do I get the selected index, if I change the selection of a datagrid row. I´ve searched a lot and have found only the Adobe site
This is what I think is the right way:
myGrid.addEventListener(DataGridEvent.ITEM_FOCUS_IN, datagridchanged);
//DataGrid Changed Listener function
private function datagridchanged (e:DataGridEvent):void{
trace(e.selectedIndex); //Don`t know if .selectedIndex is correct
}
But nothing works, if someone could help me please?
Thanks in advance
If you simply want to know which item has been selected, you can listen to Event.CHANGE on your DataGrid.
Like this, for example:
mygrid.addEventListener(Event.CHANGE, onGridSelectedItem);
function onGridSelectedItem(e:Event):void{
var selected:int = mygrid.selectedIndex;
var item:Object = mygrid.selectedItem;
}

How can I make a function to make a child of an object in the library based on the variables supplied?

I'm trying to do a little project for my class and though I know how to do it the long way I'd prefer to do it in a more intuitive way so that I can avoid having to copy and paste a load of essentially the same code. The idea is to have a function which will create an instance of a class object with it's own unique name, set it's position/size/etc, and then add that child to the stage. Looking at this (what I have now) might help out a little bit.
//Set up variables for all deco pieces
var decoGreen:GreenBall;
var decoRed:RedBall;
var decoStar:Star;
var decoFlower:Flower1;
var decoYellow:YellowBall;
var decoBlue:BlueBall;
//Functions to allow easier object placement
function makeDeco(posX:Number, posY:Number, decoName:String, rootClass:Object):void
{
decoName = new (rootClass)();
decoName.x = posX;
decoName.y = posY;
addChild((decoName));
}
makeDeco(90,320,"greenBall",GreenBall)
Now obviously this code doesn't work and it's pretty rough right now but I think it's sufficient to understand what I'm trying to accomplish here. Thanks for any and all who attempt to decipher my mess! :D
You are pretty close from what I can tell and if I understand your question, it would simply be using the getDefinitionByName class
function makeDeco(posX:Number, posY:Number, decoName:String):void
{
var DecoClass:Class = getDefinitionByName(decoName) as Class;
var deco:DisplayObject = new DecoClass();
deco.x = posX;
deco.y = posY;
addChild((deco));
}
makeDeco(90,320,"greenBall")
You don't need to define the variables initially like you did, granted they've all set to "Export as actionscript" in the library. For example calling a string of "greenBall" would mean you have a movie clip in the library with a class name of greenBall

AS3 - e:MouseEvent = null?

I was reading a tutorial on how you can make a turret follow the mouse, for a game, and I stumbled across something I've never seen before.
private function showGhostTurret(e:MouseEvent = null):void
{
var target_placeholder:Sprite = e.currentTarget as Sprite;
ghost_turret.x = target_placeholder.x;
ghost_turret.y = target_placeholder.y;
ghost_turret.visible = true;
}
I've never seen someone set the (e:Event) to null, like in the first line. Could someone please explain the purpose of doing this? Let me know if you need more information to answer.
Thanks.
That is a default parameter value. What it means is that the parameter e is optional so you can opt to not include it in a call to showGhostTurret() and e will be assigned the value null.
I'm not sure how that's useful in this particular case since, looking at the body of the function, e is most definitely required. You said this was part of a tutorial -- maybe it becomes useful later on?

Dynamic Variable Name

I need to create a variable:
var numDots0:Number=0;
But when a button is clicked the variable numDots0 becomes numDots1, then numDots2 on a second click, and so on. I then need to be able to grab that new variable name and use it in a function.
That's a really, really weird request, but anyways:
You can use the key name of an Object to store the property and then change that:
var obj:Object = { numDots0: 0 };
And then when you want to change the name:
delete obj.numDots0;
obj.numDots1 = 1;
Or to easily increment you can use this:
var i:int = 0;
function increase():void
{
delete obj["numDots" + i];
obj["numDots" + (++i)] = i;
}
To access:
trace(obj.numDotsX); // where X is the most recent variable name.
I see absolutely no benefit or need for this, so I strongly suggest taking a look at what you're trying to do and making sure it makes sense and doesn't have a different application.
I am pretty sure you are going the wrong way about the problem you are trying to solve. Dynamic variable names are not something you read in the best practices book.
Anyway to answer your question in AS2 you could use the command eval which would evaluate a string as ActionScript, so you would use something like:
function onClicked(e:MouseEvent):void
{
counter++;
eval("var numDots" + counter +"+:Number=0;");
}
In AS3 that command has been removed (because it leads to bad coding practices - like the things you are trying to do), nevertheless someone implemented an evaluator in AS3:
http://eval.hurlant.com/
With this evaluator add the library to your project and add the following to the snippet above:
function eval(expression:String):void
{
var evaluator:com.hurlant.eval.Evaluator = new com.hurlant.eval.Evaluator();
var bytes:ByteArray = evaluator.eval(expression);
bytes = ByteLoader.wrapInSWF([bytes]);
var context:LoaderContext = null
var loader:Loader = new Loader();
loader.loadBytes(bytes, context);
}
the answer is to not do what you are trying to do and use an array, hash or vector instead. give us a bit more context, or the reason you want to achieve exactly what you want to and why you might believe you'd need a dynamic variable name like that. you shouldn't be using evals or anything that changes variable name at runtime because the gods of programming will strike you down where you stand. i.e., your program is going to break, and when it does, it's going to be harder to debug for sure.
if you are sure this is what you want to do, then i'm wrong, haha. good luck!

ActionScript 3 name property is not returning the right name...?

I experienced a problem with the name property in as3, I created this "dot" movieclip and I exported to a class,
then I anonymously created a bunch of dots using a loop. I assigned numbers as name to each dots
private function callDots(num:Number):void
{
for (var i = 0; i < subImagesTotal[num]; i++)
{
var d:Dot = new Dot();
d.x = i*23;
d.y = 0;
d.name = i;
dotContainer.addChild(d]);
}
}
so far so good, I checked that if I trace the name here, I will get the number I want.
However, it's not giving me the numbers if I trace it in other functions.
I added all of my dots to "dotContainer", and if I click on one of the dots, it will call this function
private function callFullSub(e:MouseEvent):void
{
var full_loader:Loader = new Loader();
var temp:XMLList = subImages[sub];
var full_url = temp[e.target.name].#IMG;
full_loader.load(new URLRequest(full_url));
full_loader.contentLoaderInfo.addEventListener(Event.INIT, fullLoaded);
}
e.target.name is suppose to be numbers like 1 or 2, but it's giving me "instance66" "instance70" and I
have no idea why. Because I did the same thing with loaders before and it totally worked.
Any ideas? Thanks.
christine
The e.target returns the inner most object clicked on, this could be a TextField, another MovieClip or posibly a shape (I'm not 100% of the last one) inside the "Dot".
To prevent this you could try to set the mouseChildren property to false on the Dot's when you add them. This should insure that nothing inside the dots can dispatch the click event, and thus the Dot's should do it.
Perhaps you could also in the event handler verify the target type with code like this:
private function callFullSub(e:MouseEvent):void
{
if(!e.target is Dot)
throw new Error("target in callFullSub is not Dot but: " + e.target.toString());
//The rest of you code here
}
The answer is [e.currentTarget.name] I perform this all the time!
Should return "Dot1" "Dot2", etc.
If the value you wish to return is a number or other data type other than a string (name of object) use [e.currentTarget.name.substr(3,1).toString()]
Should return 1, 2, etc.
Navee
I tried to reproduce your problem first with Flex using runtime created movieClips and then with Flash using Dot movieClip symbols exported for ActionScript. Neither application exhibited the problem.
You may already know names like "instance66" "instance70" are default enumerated instance names. So, whatever is dispatching the MouseEvent is NOT the dot instance. Perhaps you are unintentionally assigning callFullSub to the wrong targets, maybe your containers? Try assigning it to dot instance right after you create them, like this:
private function callDots(num:Number):void
{
for (var i = 0; i < subImagesTotal[num]; i++)
{
var d:Dot = new Dot();
d.x = i*23;
d.y = 0;
d.name = i;
d.addEventListener(MouseEvent.CLICK, callFullSub);
dotContainer.addChild(d]);
}
}
Be sure to temporarily comment out your original assignment.
Try this might work,..
d.name = i.toString();
You have not shown enough of your code for me to be able to give you a DEFINATE answer, I will however say this.
//After you create each loader you need to set its mouseEnabled
//property to false if you do not want it to be the target of
//Mouse Events, which may be superseding the actual intended target;
var full_loader:Loader = new Loader();
full_loader.mouseEnabled = false;
//Also you could name the loaders and see if what comes back when you click is the same.
ALSO! Add this to your Mouse Event handler for CLICK or MOUSE_DOWN:
trace(e.target is Loader); //If traces true you have an answer
I believe that the mouse events are being dispatched by the Loaders.
please provide more of your code, the code where the Loader.contentLoaderInfo's COMPLETE handler fires. I assume this is where you adding the loaders to the display list as I cannot see that now.