I get this error: 1021: Duplicate function definition.
Rich,
> I get this error: 1021: Duplicate function definition.
Ah, that means AS3 treats scenes differently. That's good to know.
Sorry about the confusion.
You have two approaches, then. The error you're seeing is because AS3
doesn't allow more than one variable, function, etc. declared in the same
scope, and it looks like scenes have the same scope now (they're in the same
timeline, presumably). Think of scope as a point of view. It's a special
compartment in which code executes. Movie clips have their own scopes,
partly because movie clip symbols have their own independent timelines (any
frame of which can hold ActionScript). It used to be that scenes were
separate too.
Quick analogy: I may have a dog named Finnegan who lives in my house.
From the point of view of my household -- in the Stiller scope, so to
speak -- I can refer to my dog as "Finnegan" and everything works. If my
neighbor also has a dog named Finnegan, and if I'm talking about my
neighbor's dog, then I have to refer to that one as "Joe's Finnegan" to
distinguish the reference from my own pet. I certainly can't have *two*
dogs named Finnegan -- not in the same house -- because it would quickly get
confusing which dog I meant by that name.
In this case, Flash is confused because you're feeding it two function
definitions with the same name (that's my fault, of course). Solution One
is to simply rename the second (and subsequent) occurrences of your
function:
function gotoPage2(event:MouseEvent):void {
var targetURL:URLRequest = new URLRequest("URL 2");
navigateToURL(targetURL, "_parent");
}
buttonTwo.addEventListener(MouseEvent.CLICK, gotoPage2);
function gotoPage3(event:MouseEvent):void {
var targetURL:URLRequest = new URLRequest("URL 3");
navigateToURL(targetURL, "_parent");
}
buttonThree.addEventListener(MouseEvent.CLICK, gotoPage3);
... which leads to the redundancy I mentioned earlier. If you have a dozen
of these, it's a headache to revise in the future. Solution Two involves
writing the function once only, then referring back to the same function
with each button.
This can be done with something called parameters, which are pieces of
information you feed into a function. In the case of gotoAndPlay(), for
example, you can feed in (in fact, you must feed in) a number:
gotoAndPlay(15);
... which tells Flash *where* to goto and play. Here, you could write your
gotoPage() function to accept its own sort of "where" parameter.
function gotoPage(url:String):void {
var targetURL:URLRequest = new URLRequest(url);
navigateToURL(targetURL, "_parent");
}
... in which case, you could call this function with any number of CLICK
event handlers:
buttonOne.addEventListener(MouseEvent.CLICK, clickHandler1);
function clickHandler1(event:MouseEvent):void {
gotoPage("http://www.adobe.com/");
}
buttonTwo.addEventListener(MouseEvent.CLICK, clickHandler2);
function clickHandler2(event:MouseEvent):void {
gotoPage("http://www.googlecom/");
}
buttonThree.addEventListener(MouseEvent.CLICK, clickHandler3);
function clickHandler3(event:MouseEvent):void {
gotoPage("http://www.friendsofed.com/");
}
But if you think about it, that hasn't shifted the redundancy issue all
that much: you still have a series of intermediary functions,
clickHandler1(), clickHandler2(), and clickHandler3(). To get around that,
you could use an instance of the Dictionary class and make a quick list of
the operative information:
function gotoPage(event:MouseEvent):void {
var targetURL:URLRequest = new URLRequest(urlList[event.target]);
navigateToURL(targetURL, "_parent");
}
var urlList:Dictionary = new Dictionary();
urlList[buttonOne] = "http://www.adobe.com/";
urlList[buttonTwo] = "http://www.google.com/";
urlList[buttonThree] = "http://www.friendsofed.com/";
buttonOne.addEventListener(MouseEvent.CLICK, gotoPage);
buttonTwo.addEventListener(MouseEvent.CLICK, gotoPage);
buttonThree.addEventListener(MouseEvent.CLICK, gotoPage);
In this case, the gotoPage() function shifts nearly back to its original
format. Yes, it still receives a parameter -- just as it always did -- but
this time, the parameter is something that gets passed in automatically, by
virtue of its being an event handler. What it receives, instead of an
arbitrary URL or frame number, is an instance of the MouseEvent class, which
in this case is an object representation of the mouse click that occurs on
the button in question.
The difference is that here, the expression inside the new URLRequest()
expression has changed. It's not a hard-coded URL, as before. This time,
it's the expression urlList[event.target]. What does that mean? The word
"event" in that expression refers to the incoming "event" parameter, which
is typed as a MouseEvent instance. That makes perfect sense, because that's
what it *is.* It's the mouse click ... represented as an object, and it's
variable name, just by coincidence, is "event" (could just as easily be
"pizzaHead"). The "target" part after the "event" parameter reference is a
property of the MouseEvent class. This variable, "event", features all the
functionality spelled out in the MouseEvent class listing of the Help docs.
One of the characteristics of a MouseEvent object is a property called
target, which points to the object that dispatched this event in the first
place; namely, whatever button was clicked.
The "urlList" part refers to the Dictionary instance. So let's say
buttonOne was clicked. In that case, the expression urlList[event.target]
refers to the buttonOne entry in the urlList dictionary. Consulting your
dictionary, you see that the value of the buttonOne entry is Adobe's URL.
Bingo. So, back in the gotoPage() function, Adobe's URL gets passed into
the new URLRequest() expression, which creates a URLRequest instance, and
that instance (in turn) gets passed as a parameter to the navigateToURL()
function.
Again, the choice is yours. You might find it easier to just rename the
second occurrence of gotoPage() to gotoPage2().
David Stiller
Co-author, Foundation Flash CS3 for Designers
http://tinyurl.com/2k29mj
"Luck is the residue of good design."
don't worry, found it. Boy this is difficult stuff for the no code type.
I wish there where a few really basic functions that the poor old designer
like me code use.
How do I stop the time line and how do I go to the next frame on click! Off to
trawl the forums AGAIN!
Thanks fr your help.