understanding and using hasOwnProperty - actionscript-3

Can someone explain to me how to assign and use hasOwnProperty. I did search the web for a decent example but somehow didnt find any even at adobe( or maybe Im to "smart" to understand what it is saying )
so what Im trying to do is to set a propertie onto a MovieClip and after that to see if it exists.
var myMC:MovieClip = new MovieClip();
myMC.hasOwnProperty( "someRandomText" );
this.addChild( myMC );
if( myMC.hasOwnProperty( "someRandomText" ) ) trace(" yes it has it ")
else trace( "nothing here" )
output: nothing here
what am I doing wrong ?
and also :) how do I null/remove it after I add it to the MC

hasOwnProperty() checks whether an object has a property of that name. Basically, it'll return true if a property has an instance name matching the string.
The reason hasOwnProperty("someRandomText") returns false in your code is simply because myMC.someRandomText does not exist. Your second line seems to try making it but that's not what the function does.
A better test would be:
if( myMC.hasOwnProperty( "width" ) ) trace(" yes it has it ");
else trace( "nothing here" );
All MovieClips have a width property so this should return true. I haven't tested it but it should work.
The definition on the AS3 Reference is pretty much the best explanation you can get.

Related

Arma 3 - addAction with dynamic variables to specific Object

Playing around with custom composition spawning in Arma 3. I am currently using "LARs Composition Spawn Script" (https://forums.bistudio.com/forums/topic/191902-eden-composition-spawning/) to spawn a custom compostion. Spawning compositions around the map works like a charm.
In the composition there is one object (AI) whith varname "quest_giver". To this specific Object I want to add an Action. My current code is:
// SPAWN RANDOM COMPOSITION ON RANDOM POSITION
_spawned_composition = [ _random_composition, _pos, [0,0,0], random 360 ] call LARS_fnc_spawnComp;
// GET OBJECTS FROM THE SPAWNED COMP BACK (ARRAY)
_objects = [_spawned_composition] call LARs_fnc_getCompObjects;
// TRYING TO ITERATE THROUGH OBJECTS TO FIND "quest_giver"
// AND ADD ACTION TO IT.
{
_type = typeName _x;
if (_type == "GROUP") then {
_units = units _x;
{
_var = missionNamespace getVariable ["name", _x];
_name = typeOf _var;
if (_name == "quest_giver") then {
player globalChat format["%1",_name];
//_speak = _x addAction ["Speak", {hint format ["Hello, it works !"]}];
};
} forEach _units;
};
} forEach _objects;
Error at If(_name == "quest_giver") where _name is an OBJECT but "quest_giver" of course a STRING. So I get Error Generic error in expression.
However, _var = missionNamespace getVariable ["name",_x]; returns "quest_giver". But it as an OBJECT, since typeOf _var returns "OBJECT" not STRING.
I just can't figure out the most simpliest thing here I guess. Any idea, if this would even work in theory ?
What I am trying to achieve
Create various custom compositions, where on Object in it is always the "quest_giver". Works so far.
Choose random comp and spawn it on random position in the world. Works so far.
Add action to the quest giver so player can speak to him. Text Pop up with simple text, content would be a random quest ala bring me 5 x Water Bottles.
I know my way around before and after the add action part but can't figure out how to add action to this specific object. ...
unless I'm mistaken, you seem to be confused about how to get the unit's name?
it might be you want to get a name var from the unit's namespace (if the thing you're using does put it there):
_name = _x getVariable ["name" /*var name*/, "" /*default value*/];
if (_name == "quest_giver") then {
//...
or more likely (if it's about the name set via editor) with the name function:
if ((name _x) == "quest_giver") then {

AS3 Call a variable from a compound string

I don't know how to explain this good, I'll do my best :p
I have this code:
public function clickeado(MouseEvent):void{
if(getChildByName("placa") == null){
addChild(info);
}
trace(MouseEvent.target.name)
switch(MouseEvent.target.name){
case "_783":
info.circuito_tf.text = _783_circuito;
info.localidad_tf.text = _783_localidad;
info.responsable_tf.text = _783_responsable;
break;
I want that the text of "info.circuito_tf.text" to be the value of the variable called "_783_circuito". It's ok. Now I have 17 more cases, so I decided to do something like this:
switch(MouseEvent.target.name){
case "_783":
info.circuito_tf.text = MouseEvent.target.name + "_circuito";
info.localidad_tf.text = MouseEvent.target.name + "_localidad";
info.responsable_tf.text = MouseEvent.target.name + "_responsable";
break;
I wish I explained well, thanks!
ps: the value of info.circuito_tf.text in the second case it's "783circuito" instead of the value of the variable
You can address a variable through a string via this syntax:
info.circuito_tf.text = this[MouseEvent.target.name + "_circuito"];
Watch out for undefined values, though.
Yes, with this syntax you don't need the switch statement at all, just make sure your movie clips all have valid names and correct variables exist and are assigned values.

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!

AS3: Getting values of objects by referencing their name

I'm reading XML and attaching values to objects in two seperate movieclips. Like this
Map01:
Marker01.name = hello there
Marker01.short = hel
Marker01.value = 12
Map02:
Marker02.name = hello there
Marker02.short = hel
Marker02.value = 99
Now I'm clicking on Marker01 in Map01 and get its name and value. I want to compare its value to that of Marker01 in Map02, using the name, or better yet .short because the names are long and use special characters/spaces. How do I do this? I've pretty much tried everything that seemed logical!
EDIT: sample code for clarification
var marker01:mc_marker = new mc_marker();
marker01.name="hello there";
marker01.short="abc";
marker01.val="99";
marker01.x=10;
marker01.y=10;
this.mc_map01.addChild(marker01);
var marker02:mc_marker = new mc_marker();
marker02.name="hello there";
marker02.short="abc";
marker02.val="20";
marker02.x=10;
marker02.y=10;
this.mc_map02.addChild(marker02);
marker01.addEventListener(MouseEvent.MOUSE_UP, showMarkerInfo);
marker02.addEventListener(MouseEvent.MOUSE_UP, showMarkerInfo);
function showMarkerInfo(event:MouseEvent):void {
txt_ms.text=event.target.short;
txt_mv.text=event.target.val;
if (event.target.short==mc_map02.marker02.short){
txt_mvi.text="here should be the marker02 value";
}
}
You have a typo there. Map02 use Marker1 things.
If its a typo in Stackoverflow,
this.getChildByName( "Marker01" ) will return you the movieclip, buy its name. take care though, as "name" is what it searches for. You used "hello there" when you should put Marker01 as the name. I would suggest you put a property called "data" and put the xml info in it so it doesn't conflict.
In the end you have:
if( this.getChildByName( "Marker01" ).data.value == this.getChildByName( "Marker02" ).data.value ).
I assume this is because you generate Marker0X at runtime and you can't declare some variables and use them directly.
Browny points if you make "data" a instance of a custom class where you can compare two "data". If you need more help, add a comment ^_^

AS3: How to simplify Action Script 3 Code?

Here's a example that I've to use when I want to create a button with mouse-over effect:
this.buttonExample.buttonMode = true;
this.buttonExample.useHandCursor = true;
this.buttonExample.addEventListener(MouseEvent.CLICK,myaction);
I'm new to AS3 - is there any way, to simplify this code like this:
this.buttonExample.buttonMode = true;.useHandCursor = true;.addEventListener(MouseEvent.CLICK,myaction);
why does it not works ?
Its already as simple as it gets. Firstly
this.buttonExample.buttonMode = true;
this.buttonExample.useHandCursor = true;
this.buttonExample.addEventListener(MouseEvent.CLICK,myaction)
is much more readable than
this.buttonExample.buttonMode = true;.useHandCursor = true;.addEventListener(MouseEvent.CLICK,myaction);
Always go for readbility over anything else. And secondly,
this.buttonExample.buttonMode = true;
does not return an object so you can't interact with anything.
If you're using that pattern a lot, you can make a helper function:
public function setAsButton(button:Sprite, clickHandler:Function):void {
button.buttonMode = button.userHandCursor = true;
button.addEventListener(MouseEvent.CLICK, clickHandler);
}
Then call it somewhere:
setAsButton(this.buttonExample, myaction);
If you feel that typing this.buttonExample over and over again is too repetitive, simply assign that object to a variable and use that variable in the rest of the statements:
var b : Button = this.buttonExample;
b.buttonMode = true;
b.useHandCursor = true;
b.addEventListener(...);
As other's have mentioned, there's also the with statement, but it's use is discouraged since it makes the code harder to read, and may lead to weird results:
with (this.buttonExample) {
buttonMode = true;
useHandCursor = true;
addEventListener(...);
}
You can, of course, combine these suggestions with other tricks, like chaining assignments:
var b : Button = this.buttonExample;
b.buttonMode = b.useHandCursor = true;
b.addEventListener(...);
Be very careful to only chain assignments in this way if the assigned value is immutable (e.g. true, false, numbers and strings, but not arrays or most other objects), because the same object will be assigned to all variables on the left side. If the value is immutable this doesn't matter, but if it's mutable you can end up with weird results, like this in this example:
a = b = [ ];
a.push(1);
b.push(2);
trace(a); // outputs 1, 2
trace(b); // also outputs 1, 2
The reason for this result is that a and b both reference the same array, and since arrays are mutable it doesn't matter how you access the object, it will still be changed. a and b don't reference different arrays just because they are different variables.
You may think that you could do something like the following, but it will not work.
// this will NOT work
var b : Button = this.buttonExample;
(b.buttonMode = b.useHandCursor = true).addEventListener(...);
The reason why it works to say b.buttonMode = b.useHandCursor = true, but not to add .addEventListener(...) is that the value of an assignment expression (e.g. b.buttonMode = true) is the value assigned to the left hand side (e.g. true). If you add .addEventListener(...) to that you are essentially saying true.addEventListener(...), which clearly is not what you want. In other words
b.buttonMode = b.useHandCursor = false;
is equivalent to
b.useHandCursor = false;
b.buttonMode = b.useHandCursor;
Which should hopefully also make the caveats mentioned above plain.
you can use the with statement. however I'd not encourage you to do so, since it leads to a lot of ambiguity and unclearness.
also, you can have multiple assignments:
this.buttonExample.buttonMode = this.buttonExample.useHandCursor = true;
this sometimes is useful, but for the sake of readability, you shouldn't overuse it.
greetz
back2dos