AS3 - Get and Set - actionscript-3

Why does the get and set keywords exist? They seem to be useless for me...
For example:
public function set player_X(x:Number):void
{
player.x = x;
}
public function setPlayerX(x:Number):void
{
player.x = x;
}
These two functions does the same thing right? And the second one does not use the set keyword.

The difference is that the set method is implicitly called when you set a property of the same name.
You do not have to type the ( ) that do the function call but assign the value via =.
player_X = 5;
vs.
setPlayerX(5);
It can help with information hiding as to the user of a class, this is appears to be a property and can be used as such.

Related

Assign function argument to global variable of the same name

Is it possible to set a global variable from within a function that takes that same variable name as an argument?
var a:int = 0;
function test(a:int)
{
a *global* = a *local*;
}
test(1);
trace(a) // traces 0 but I'd like it to trace 1
(The reason why I'd like to do this, is to avoid constantly coming up different variables names for the same things)
Thanks in advance.
You could refer to it explicitly as this.a = a; in your function test
In this case this is the class instance that holds this variable. In case of a static variable, you can use ClassName.a = a.

Call a function if String number is inferior to 0?

I've got this code in my Toolbar.as :
var money = 9999;
argent.text = String(money);
trace(money);
How do I do to say
if (money < 0){
callFunction();
}
?
Thank you very much for your answers
EDIT
I've tried everything.
Here's what I did :
var money:int = 9999;
argent.text = money.toString();
trace(money);
stageRef.addEventListener("checkingMoney", checkMoney, false, 0, true);
I've add the EventListner in order to check the money (as nothing was triggering the condition if money<0 before).
And then :
public function checkMoney(event):void{
var money;
trace("checking");
if (parseInt(money) < 0){
trace("dangerous");
}
}
So the function is well triggered (the trace "checking" is on), but even the number is under 0 (-4600), the trace "dangerous" do NOT appear..
I don't understand.
You need to read up on how datatyping works. It works similarly in all OOP-based languages, so an AS3-specific article really isn't necessary. Avoid anything regarding PHP datatypes, though.
For what you have posted, though, you have done a few things incorrectly.
First off, every object (whether it be a variable, function, or class), should always have the datatype declared. You can get away with not doing it, but your app will run slightly faster if you do and there is less chance of compiler warnings.
So
var money = 9999;
should be
var money:int = 9999; // could also use Number (AS3's float) or uint
You should avoid hard-casts such as String(money), as well. This can be slow and can cause errors. For casting a Number to a String, you should always use Number.toString(), as that is its intended purpose and I believe it is optimized whereas other cast types are not.
if (money < 0) is actually correct. It may have been throwing IDE warnings because you didn't set the type of money. If you need to compare a numeric String value, you need to cast it back to a number using Number(var). Note that casting a String to Number is one of the few times you want to use a hard cast DataType(object) instead of a soft cast (object as DataType).
I don't get the problem.
1st of all money variable is missing a type.
If money is int here than:
var money:int = 9999;
argent.text = money.toString();
trace(money);
if (money < 0){
callFunction();
}
and that should work.
If for some reason money is String in here than:
var money:String = "9999";
argent.text = money;
trace(money);
if (Number(money) < 0){
callFunction();
}
I don't usually do this, but I'm posting a second answer because your edit is drastically different than what you originally posted. For future reference, please post the entire code that is relevant. You seemed to have missed some context originally and forced us to solve the wrong problem (don't get me wrong, it still needed to be fixed but it was not the issue at hand)
So what you are seeing is a scope issue. Basically, an object declared in an object (be it a Class, Function, loop, or conditional) is only available within that object and within child objects. Additionally, all objects declared in the top-level scope of a class must have an access modifier (public, private, internal, protected, etc).
So let's assume this class structure:
public class ClassName {
public function ClassName();
public function checkMoney();
}
An object declared in the constructor (ClassName()) is not available in checkMoney(). So you need to do one of two things:
Declare the object in top-level scope:
public class ClassName {
private var money:int;
public function ClassName(){
money = 9999;
checkMoney()
}
public function checkMoney() {
// you now have access to money
}
}
or pass the object into the function:
public class ClassName {
public function ClassName(){
var money:int = 9999;
checkMoney(money);
}
public function checkMoney(value:Number) {
// check "value" here. Note that Numbers and Strings are NOT passed be reference, so changing the value will NOT change the original variable
}
}

Combining a variable with a number

I'm trying to make a inventory using an array in a game I'm making.
What I need is a way to combine a number with a variable, something like this:
itemBoxNumber = "itemBox" + currentItemBox;
//In this case itemBoxNumber would say itemBox1
that I could use to replace the itemBox1.
function itemsMenuUpdate():void
{
for (var a:int = 0; a<maxInventory; a++){
var currentItemBox:Number = 1;
if(~inventory.indexOf("Potion")){
mainMenu.itemBox1.gotoAndStop("Potion");
}
if(~inventory.indexOf("Hi-Potion")){
mainMenu.itemBox1.gotoAndStop("Hi-Potion");
}
}
}
I can only find working methods for AS2. Any help is appreciated with this.
If I remember right, you can call a method from a String in AS3.
For example, if you want to call the method itemBox1 on mainMenu you can do:
mainMenu["itemBox1"]
Which is the same as:
mainMenu.itemBox1
So in your example you could do this:
mainMenu[itemBoxNumber].gotoAndStop("Potion");
You can retrieve the child display object via a name (which you need to set prior). So:
var itemBoxNumber = "itemBox" + currentItemBox;
mainMenu.getChildByName(itemBoxNumber).gotoAndStop("Potion"); //TODO ensure the child was given such a name
Make a LabelNumber Class, which has both a String label and a Number. You can then add a method that returns a String of the label and the number combined, while keeping the values independent of one another.

AS3 Boolean seemingly not working

Ok, so this is obviously going to be something that I stupidly overlooked in my code, but I am having problems with a boolean check in as3. In the below if statement I set a boolean, I can confirm that the boolean is set in this if switch as I have run a trace to check that:
if(switchA && switchB){
if(Side == "LEFT"){
localAttachCoords.x = (-Parent.collision.SideLength - entity.collision.SideLength)/2
localAttachCoords.y = Parent.collision.SideLength/2 - (((TargNode-1)*8) + entity.collision.SideLength/2)
}
if(Side == "RIGHT"){
localAttachCoords.x = (Parent.collision.SideLength + entity.collision.SideLength)/2
localAttachCoords.y = -(Parent.collision.SideLength/2 - (((TargNode-1)*8) + entity.collision.SideLength/2))
}
if(Side == "UP"){
localAttachCoords.y = (Parent.collision.SideLength + entity.collision.SideLength)/2
localAttachCoords.x = -(Parent.collision.SideLength/2 - (((TargNode-1)*8) + entity.collision.SideLength/2))
}
if(Side == "DOWN"){
localAttachCoords.y = (-Parent.collision.SideLength - entity.collision.SideLength)/2
localAttachCoords.x = Parent.collision.SideLength/2 - (((TargNode-1)*8) + entity.collision.SideLength/2)
}
entity.attached = true
entity.Parent = Parent
}
This would all be well and good, but for the fact that in a function from another class, executed every frame, claims that the boolean was set to false, I confirmed this with another trace function.
This is the function, taken from the class whose instance is referred to as entity in the above switch:
public function update(){
if (physics) physics.update()
if (node && physics){
trace(attached)
if(attached){
physics.nodeUpdate()
}
}
}
This function claims in the trace that attached == false despite it being set true earlier with no other reference to the attached variable. Any help would be appreciated!
Pathing
There are some un-addressed variables in your issue, foremost being the pathing you're taking to check your variable. This is relevant because of namespaces/scope affect what each piece of code has access to.
If your functions and variables shared the same space (i.e., global/document/timeline), then any reference the the same named variable will always return the same value, unless (as LoremIpsum noted) it's being shadowed by a local variable by the same name.
Obviously, this is not the case since you're using public function which is a class-only declaration. If the boolean you're looking for is on the timeline, and the class wants to read that variable, you need to have a valid path to it. Instantiated classes that are DisplayObjects and have been added to the DisplayList have both parent and stage properties which you can use to access the timeline global namespace (thereby providing access to your boolean).
However, if the class is not a DisplayObject (e.g., it does not extend a Sprite, Shape, or MovieClip), then access to the timeline has to be provided manually, either by setting a property on the class, or passing an argument to a method on the class.
Further complicating the matter is if the Boolean exists in another class object (either instantiated or static), you'd then need a way to get between them. A case of A sees B, C sees B, but neither A or C see eachother.
Values
A boolean is always going to be false, even if the assigned value was null, so if your class is trying to reference a variable that it can't see, that value will always be false. For example...
var foo:Boolean = this["fiddlesticks"];
trace("foo = " + foo); // traces: "foo = false"
There is no property this.fiddlesticks, so while the resolved value is null, foo becomes false. Consider using hasOwnProperty(), which indicates whether an object has a specified property defined, and is a method available to all objects.
Switch
You don't have to manually create your own switch using if then else if, AS3 has its own switch statement.
switch (Side) {
case "LEFT":
// Do stuff for left
break;
case "RIGHT":
// Do stuff for right
break;
case "UP":
// Throw your hands up
break;
case "DOWN":
// Get down and boogie!
break;
}
I hope that all helps. I'd like to say exactly what's going on with the access to your Boolean, but there simply isn't enough information to say.
Cheers!

Create a Non-Database-Driven Lookup

Lots of references for creating lookups out there, but all seem to draw their values from a query.
I want to add a lookup to a field that will add items from a list of values that do not come from a table, query, or any other data source.
Such as from a string: "Bananas, Apples, Oranges"
..or a container ["Bananas", "Apples", "Oranges"]
Assume the string/container is a dynamic object. Drawing from an static enum is not a choice.
Is there a way to create lookups on the fly from something other than a data source?
Example code would be a great help, but I'll take hints as well.
There is the color picker.
Also in the Global you will find pickXxxx such as pickList.
There are others, pickUser, pickUserGroup etc.
Take a look on the implementation. I guess they build a temporary table then displays that. Tables are great!
Update:
To go on you own follow the rules.
For the advanced user, see also: Lookup form returning more than one value.
public void lookup()
{
SysTableLookup sysTableLookup;
TmpTableFieldLookup tmpTableFieldLookup;
Enumerator en;
List entitylist = new list(types::String);
entitylist.addend("Banana");
entitylist.addend("Apple");
en = entityList.getEnumerator();
while (en.moveNext())
{
tmpTableFieldLookup.TableName = en.current();
tmpTableFieldLookup.insert();
}
sysTableLookup = SysTableLookup::newParameters(tableNum(tmpTableFieldLookup), this);
sysTableLookup.addLookupfield(fieldNum(TmpTableFieldLookup, TableName));
//BP Deviation documented
sysTableLookup.parmTmpBuffer(tmpTableFieldLookup);
sysTableLookup.performFormLookup();
}
The above code helps in displaying strings as lookup.
I'm also guessing there's no way to perform a lookup without a table. I say that because a lookup is simply a form with one or more datasources that is displayed in a different way.
I've also blogged about this, so you can get some info on how to perform a lookup, even with a temporary table, here:
http://devexpp.blogspot.com.br/2012/02/dynamics-ax-custom-lookup.html
Example from global::PickEnumValue:
static int pickEnumValue(EnumId _enumId, boolean _omitZero = false)
{
Object formRun;
container names;
container values;
int i,value = -1,valueIndex;
str name;
#ResAppl
DictEnum dictEnum = new DictEnum(_enumId);
;
if (!dictEnum)
return -1;
for (i=1;i<=dictEnum.values();i++)
{
value = dictEnum.index2Value(i);
if (!(_omitZero && (value == 0)))
{
names += dictEnum.index2Label(i);
values += value;
}
}
formRun = classfactory.createPicklist();
formRun.init();
formRun.choices(names, #ImageClass);
formRun.caption(dictEnum.label());
formRun.run();
formRun.wait();
name = formRun.choice();
value = formRun.choiceInt();
if (value>=0) // the picklist form returns -1 if a choice has not been made
{
valueIndex = -1;
for (i=1;i<=conLen(names);i++)
{
if (name == conPeek(names,i))
{
valueIndex = i;
break;
}
}
if (valueIndex>=0)
return conPeek(values,valueIndex);
}
return value;
}
It isn't the most graceful solution, but this does work, and it doesn't override or modify any native AX 2012 objects:
Copy the sysLookup form from AX2009 (rename it) and import it into AX 2012.
We'll call mine myLookupFormCopy.
I did a find/replace of "sysLookup" in the XPO file to rename it.
Create this class method:
public static client void lookupList(FormStringControl _formStringControl, List _valueList, str _columnLabel = '')
{
Args args;
FormRun formRun;
;
if (_formStringControl && _valueList && _valueList.typeId() == Types::String)
{
args = new Args(formstr(myLookupFormCopy));
args.parmObject(_valueList);
args.parm(_columnLabel);
formRun = classFactory.formRunClass(args);
_formStringControl.performFormLookup(formRun);
}
}
In the lookup method for your string control, use:
public void lookup()
{
List valueList = new List(Types::String);
;
...build your valueList here...
MyClass::lookupList(this, valueList, "List Title");
super();
}