all groups > flash actionscript > october 2005 >
You're in the

flash actionscript

group:

Instance Names


Re: Instance Names Matthew Morvant
10/12/2005 3:59:47 PM
flash actionscript:
This is what I currently have in there that works. When I parsed the XML I
set variables with the name of the instance in them. On a side note can I
make a new "property" for the button rather than making setting local
variables?

on(rollOver)
{
vcStateName = get("_root.insCalifornia.display");
}
on(rollOut)
{
vcStateName = '';
}
on(release)
{
if(get("_root.insCalifornia.follow") == "1")
{
getURL(get("_root.insCalifornia.link"));
}
}


[quoted text, click to view]

Re: Instance Names David Stiller
10/12/2005 4:54:57 PM
matthew_morvant,

[quoted text, click to view]

Would you post the code for your event handler? Curious how you're
going what you're doing (using the on() handler? using dot notation?).

[quoted text, click to view]

It all depends on what "this" is scoped to. If it's scoped to a button
instance, you should be fine, because the Button class has a _name property.
This probably is easy, and is probably a scope issue, but let's see what
approach you're using.


David
stiller (at) quip (dot) net
"Luck is the residue of good design."

Instance Names matthew_morvant
10/12/2005 8:41:37 PM
I am making a Flash based map for a client. They want to use an XML file to
decide which states are shown and what links are followed once an active state
is clicked. I have worked out all of the XML part but want to streamline the
code in the buttons. I have a button called "btnCalifornia" it is placed on
the stage and given an instance name of "insCalifornia". How do I get the name
of the instance ("insCalifornia") from a button event? I have tried this._name
and many variations but can't seem to find something that works. This doesn't
seem like it should be difficult to do, but I am stuck anyway.

Thanks
Re: Instance Names Matthew Morvant
10/13/2005 3:54:52 PM
Anybody else have any ideas?

[quoted text, click to view]

Re: Instance Names David Stiller
10/13/2005 5:32:52 PM
Matthew

[quoted text, click to view]

Sorry for the delay. It has been a crazy couple of days.

Based on your sample code -- you're using the on() handler to capture
button events -- there is no "this" for the button instance. Since on() is
attached directly to the button, I guess the reasoning is it's obvious
enough which button instance the developer means. In fact, you don't even
have to provide an instance name for buttons (or movie clips) that use on()
(or onClipEvent()).

Start a new FLA, draw a quick circle, convert it to a button and give
the button an instance name in the Properties inspector. Using on(), attach
the following code to your button directly ...

on (release) {
trace(this);
}

Compile that SWF and watch the Output panel as you click the button.
You'll see only _level0 as often as you click, not the full path to your
button, as you might expect. Because you're using on(), the button has no
sense of self, even with an instance name. This is just one of the quirks
of using ActionScript.

Now, clear out that on() handler and leave *nothing* in the Actions
panel for that button. Instead, create a new layer in the main timline,
just above your button, and call that layer scripts. Since Flash MX, it has
been possible to assign functions to instance events via dot notation. This
is much, *much* more powerful and convenient, because A) all your code can
be in the same place (no more hunting and pecking ... where was that code
again?) and B) you can assign the same function to dozens of buttons, then
use each button's instance name to sort out how the function should act --
which is what it sounds like you're trying to do.

In a frame of your scripts layer, use the button's instance name (not
the sample name I'm using) and type the following ...

buttonInstanceName.onRelease = function() {
trace(this);
}

This time, when you test, you'll see the full path to your button,
including its instance name. The button has a sense of self! Change that
reference to "this" to ...

buttonInstanceName.onRelease = function() {
trace(this._name);
}

.... and see the button's instance name only. Now, in this function, you can
use switch() on that name (or whatever you like; maybe a series of if()s)
and have the function do your bidding. Only one function assignment, and
you're good to go.

[quoted text, click to view]

You bet.


David
stiller (at) quip (dot) net
"Luck is the residue of good design."

Re: Instance Names Matthew Morvant
10/14/2005 9:40:02 AM
Ok, thanks for your excellent explanation. You are certainly pushing me in
the right direction, but I am afraid I now have a new question.

Given the following code:

//Get the list of states
for (i=0; i<=nodRoot.childNodes.length -1; i++)
{
//InstanceName of the current state
tIns = nodRoot.childNodes[i].attributes["instance"];


if(nodRoot.childNodes[i].attributes["visible"] == "1")
{
setProperty(tIns,_visible,1);
tIns.rollOver = function() {trace('over');vcStateName =
nodRoot.childNodes[i].attributes["displayName"]};
tIns.rollOut = function() {vcStateName = ''};
}
else
{
setProperty(tIns,_visible,0);
}
}

Obviously this will not work because the variable tIns is not an object but
merely a string representing the name of an object. I tried using eval but
it appears to only be useful for simple values, not an operation.

Thanks once again
Matthew

[quoted text, click to view]

Re: Instance Names Matthew Morvant
10/14/2005 11:24:35 AM
I think I must have something wrong, let me paste some more code and debug
window text:

##########START CODE#############
//Load XML
xmlMapData = new XML();
xmlMapData.ignoreWhite = true;
xmlMapData.onLoad = go;
xmlMapData.load('xmlMapData.xml');
function go()
{
//Set the Root Node
nodRoot = xmlMapData.firstChild;

//loop through the states
for (i=0; i<=nodRoot.childNodes.length -1; i++)
{
//InstanceName
tInsName = nodRoot.childNodes[i].attributes["instance"];
var tIns:Button = _root[tInsName];
trace(tInsName);
trace(tIns._name);
trace(getProperty(tInsName,_x));

if(nodRoot.childNodes[i].attributes["visible"] == "1")
{
tIns._visible = 1;

}
else
{
tIns._visible = 0;
}
}

}

stop();
##########END CODE#############

##########SNIP DEBUG#############
insAlabama
undefined
427.15
insArizona
undefined
142.3
insArkansas
undefined
357.55
insCalifornia
undefined
67.3
##########END DEBUG#############

I don't really care about the _x property but just wanted to verify that I
had the correct instance name. Is there something else that I should do?
That is all of the actionscript wich is located in the same frame as the
button instances. I am sure I am just missing something simple, I just
can't see it.

Thanks again for all of your help, (and taking the time to explain the "why"
part)

[quoted text, click to view]

Re: Instance Names David Stiller
10/14/2005 11:54:43 AM
Matthew,

[quoted text, click to view]

This is a key realization that many people miss.

[quoted text, click to view]

You certainly should be able to use eval(), but there's another way, and
I happen to prefer it (not sure why ... it just looks cleaner). Obviously,
you need to reference an actual object path. Normally, this is done with
dot notation from some reference point (say, the _root, or this, or some
movie clip instance name).

You can use the array access operator [] to dynamically reference such
paths, because the brackets allow you to use strings (even variables) in
your path construction. So, assuming these instances are in the _root, you
might do something like this ...

tIns = _root[nodRoot.childNodes[i].attributes["instance"]];

.... and again, that assumes that the string returned by this XML node ...

nodRoot.childNodes[i].attributes["instance"]

.... is the name of an actual instance immediately in the _root. If these
instances were nested in yet another instance, your full path might be ...

tIns = _root.otherInstance[nodRoot.childNodes[i].attributes["instance"]];

Note carefully where the array access operator replaces a given dot in
the dot notation path.

While we're at it, here, let's update your syntax. I'm guess you've
been looking through old tutorials, because (for example) setProperty() has
been available since Flash 4, and dot notation is, again, a much cleaner way
to go, at least to my eyes.

Thus ...

if (nodRoot.childNodes[i].attributes["visible"] == "1") {
setProperty(tIns,_visible,1);
// ...

.... becomes ...

if (nodRoot.childNodes[i].attributes["visible"] == "1") {
tIns._visible = 1; // or true
// ...

Additionally, you may find it helpful to use the strong typing available
to ActionScript 2. By appending a colon and a type to your variables, the
compiler will expect those variables to be of a certain type ...

tIns = _root[nodRoot.childNodes[i].attributes["instance"]];

.... becomes ...

var tIns:MovieClip = _root[nodRoot.childNodes[i].attributes["instance"]];

.... so you get the benefit of better error messages at compile time, and
also better intellisense (code hinting) while writing your code. In the
Actions panel, since Flash now knows what datatype tIns is, you'll see
relevant properties/methods/etc. as soon as you type tIns and put the dot
after it.


David
stiller (at) quip (dot) net
"Luck is the residue of good design."

Re: Instance Names David Stiller
10/14/2005 2:31:03 PM
Matthew,

Obviously the error is in here, somewhere, because some of your traces
behave ...

//InstanceName
tInsName = nodRoot.childNodes[i].attributes["instance"];
var tIns:Button = _root[tInsName];
trace(tInsName);
trace(tIns._name);
trace(getProperty(tInsName,_x));

The first trace statement, trace(tInsName) outputs as expected. This
tells us that tInsName is a valid reference to something -- but what? The
third trace offers us a clue. I would drop that ancient getProperty() and
simply use this ...

trace(tInsName._x);

.... but in any case, since that trace() also behaves, we know that tInsName
is an instance of some class that features an _x property. Probably a movie
clip or button.

In this case, then, we have already demonstrated that we *have* a valid
path to an object. The valid path seems to be self-contained in the
contents of this node ...

nodRoot.childNodes[i].attributes["instance"]

.... so forget this line:

var tIns:Button = _root[tInsName];

.... because you already *have* your path. Simply trace ...

trace(tInsName._name);

Make sense? I know that differs when what I wrote last time, but I had
no idea what was in your attributes. If what's in there actually does give
you a valid reference, you're already done.

If you want to use the var keyword (I would) and strong typing, you
would change your line to this ...

var tInsName:Button = nodRoot.childNodes[i].attributes["instance"];

In fact, do that and see if the compiler complains (something to the
effect of expecting a Button but getting something else). Just curious.


David
stiller (at) quip (dot) net
"Luck is the residue of good design."

Re: Instance Names Matthew Morvant
10/14/2005 3:17:57 PM

[quoted text, click to view]

I only included the getProperty method to illustrate the problem,
getProperty & setProperty methods work whereas the more direct methods fail.

[quoted text, click to view]

I guess I am misunderstanding something fundamental here. Shouldn't the line
above be

var tInsName:String = nodRoot.childNodes[i].attributes["instance"];

I only dabble in Flash I do most of my work in C#; so I am used to
treating the name of an object much differently than the object. You
mentioned in your first response that the connection between object names
and the object itself were often misunderstood, but never said if "my"
understanding was incorrect or not. It would appear that the get/set
methods expect a name of an instance (which I have) and not an actual
object, therefore those methods work. The newer methods require an actual
object reference which I do not have.


[quoted text, click to view]

Re: Instance Names Matthew Morvant
10/14/2005 3:47:59 PM
MX 2004, but the original file is likely much older than that, let me check
that out.

[quoted text, click to view]

Re: Instance Names Matthew Morvant
10/14/2005 4:00:40 PM
D'Oh, I had the properties set to Actionscript 1.0 in the publish
properties....

Thanks for all of your help. I am not quite there yet, but things are
moving forward.

[quoted text, click to view]

Re: Instance Names David Stiller
10/14/2005 4:33:28 PM
Matthew,

It helps to know you program in C#. I'm just starting in that arena
(irrelevant side note). But the point is, you're a programmer. Good stuff.

[quoted text, click to view]

That's very interesting. They should be identical. I don't know if
you're concluding that because trace() #2 shows undefined, while trace() #3
shows a value. If so, I'd encourage you to try either version to make sure
the change doesn't ... change things.

[quoted text, click to view]

I don't mean to confuse you; sorry about that. To my understanding, the
type of tInsName should be whatever type is stored in that particular node
of your XML structure (which is almost certainly a String, as you suggest --
I haven't delved into it in a while, but I think the only types in an XML
object are Strings and other XMLNodes). I was curious if typing tInsName as
a Button would cause the compiler to complain.

I'm baffled as to how you were apparently able to get a Button (or
MovieClip?) instance from this ...

nodRoot.childNodes[i].attributes["instance"];

.... but since trace() #s 1 and 3 succeed, tInsName is clearly a Button (or
MovieClip) instance. You could run that object against typeof() and
instanceof() to see what information you can squeeze of it.

If tInsName is, indeed, already an instance of Button or MovieClip --
which I suggest because of the successful tracing of its _x property -- then
you already have the object you need in order to return its instance name.


David
stiller (at) quip (dot) net
"Luck is the residue of good design."

Re: Instance Names David Stiller
10/14/2005 4:41:20 PM
Matthew,

I just got your files via email. What version of Flash are you using?
None of my ActionScript 2 comments make any sense if this needs to be
published in ActionScript 1. Or maybe you're working with a copy of Flash
MX?


David
stiller (at) quip (dot) net
"Luck is the residue of good design."

Re: Instance Names David Stiller
10/14/2005 5:37:09 PM
Matthew,

[quoted text, click to view]

Rock on, Matthew. :) Everything worked out for me, too, when I changed
it to ActionScript 2.0.


David
stiller (at) quip (dot) net
"Luck is the residue of good design."

Re: Instance Names Matthew Morvant
10/16/2005 9:32:27 PM
OK, I have made it a little further but have run into something else that I
am not sure how to over come.

Below is the loop for my state list. I would expect this to trace out the
variable for "i" whenever the button is rolled over. However even though I
see the appropriate value while setting the onRollOver function the value
that appears when the actual rollOver happens is the last value of i. Is
there way to tell Flash to assign the current value and not the
present/future value? I have kludged a solution together using the instance
name (now available) and setting variables. I was just hoping to learn a
little more about the execution order of things.


for (i=0; i<=nodRoot.childNodes.length -1; i++)
{
//InstanceName
tInsName = nodRoot.childNodes[i].attributes["instance"];
var tIns:Button = eval(tInsName);

if(nodRoot.childNodes[i].attributes["visible"] == "1")
{
tIns._visible = true;
trace(i);
tIns.onRollOver = function(){trace(i)};
}
else
{
tIns._visible = false;
}
}


[quoted text, click to view]

Re: Instance Names David Stiller
10/17/2005 8:20:44 AM
Matthew,

[quoted text, click to view]

if (nodRoot.childNodes[i].attributes["visible"] == "1") {
tIns._visible = true;
trace(i);
tIns.onRollOver = function() {trace(i)};
}

I've seen results like this from time to time and am not sure I can
explain why it happens (here's hoping someone else is following this
thread). What about this?

if (nodRoot.childNodes[i].attributes["visible"] == "1") {
tIns._visible = true;
trace(i);
tIns.prop = i;
tIns.onRollOver = function() {trace(this.prop)};
}


David
stiller (at) quip (dot) net
"Luck is the residue of good design."

Re: Instance Names Matthew Morvant
10/17/2005 9:26:22 AM
Any attempt to set a "property" that isn't standard fails. Wouldn't I have
to create a new class that inherits Button and add any new properties to the
new class? Not that I know how to do that, it is just a theory. What I
have works, so I am certainly not complaining. It may just be time to
really dig in and start some serious reading into Flash object classes.


[quoted text, click to view]

Re: Instance Names David Stiller
10/17/2005 10:40:39 AM
Matthew,

[quoted text, click to view]

Hm. MovieClip instances are dynamic in this regard. Maybe Button
instances aren't?

[quoted text, click to view]

You could. You could also do that with MovieClips, but it isn't
necessary with the latter.

[quoted text, click to view]

It isn't hard. Check out Joey Lott's three-part ActionScript 2.0 Primer
here ...

http://www.person13.com/articles/

.... and if you're feeling ambitious (which you should -- why not, eh?) pick
up Colin Moock's Essential ActionScript 2.0.

[quoted text, click to view]

Anything that's worth doing is worth doing right. :) Hop in, the
water's fine!


David
stiller (at) quip (dot) net
"Luck is the residue of good design."

AddThis Social Bookmark Button