04-07-2012, 07:30 PM
|
#1
|
|
Member
Join Date: Apr 2012
Posts: 52
|
Shortcut to adding listeners to many links?
Is there an easier way of adding mouse over/out & click listeners to many links on the page?
For example if I have 6 links on the page, each one is a static text movieclip with its own instance name:
- newStoryLink
- continueStoryLink
- selectChapterLink
- optionsLink
- charactersLink
- aboutLink
Is there any easier way than doing the following?
ActionScript Code:
newStoryLink.addEventListener(MouseEvent.MOUSE_OVER,mouseOverNewStory);
newStoryLink.addEventListener(MouseEvent.MOUSE_OUT,mouseOutNewStory);
continueStoryLink.addEventListener(MouseEvent.MOUSE_OVER,mouseOverContinueStory);
continueStoryLink.addEventListener(MouseEvent.MOUSE_OUT,mouseOutContinueStory);
selectChapterLink.addEventListener(MouseEvent.MOUSE_OVER,mouseOverChapters);
selectChapterLink.addEventListener(MouseEvent.MOUSE_OUT,mouseOutChapters);
charactersLink.addEventListener(MouseEvent.MOUSE_OVER,mouseOverNewStory);
charactersLink.addEventListener(MouseEvent.MOUSE_OUT,mouseOutNewStory);
optionsLink.addEventListener(MouseEvent.MOUSE_OVER,mouseOverNewStory);
optionsLink.addEventListener(MouseEvent.MOUSE_OUT,mouseOutNewStory);
aboutLink.addEventListener(MouseEvent.MOUSE_OVER,mouseOverNewStory);
aboutLink.addEventListener(MouseEvent.MOUSE_OUT,mouseOutNewStory);
function mouseOverNewStory(event:MouseEvent):void { //mouse over newstory link
newStoryLink.addEventListener(MouseEvent.CLICK,clickNewStory); //add listener for clicking this link
TweenMax.to(newStoryLink, 1, {glowFilter:{color:0xFFFFFF, alpha:1, blurX:30, blurY:30}}); //glow on mouseover
function clickNewStory(event:MouseEvent):void {
currentPage = "new_story";
trace("newStoryClicked");
}
}
function mouseOutNewStory(event:MouseEvent):void { //mouse out newstory link
TweenMax.to(newStoryLink, 1, {glowFilter:{color:0xFFFFFF, alpha:0, blurX:30, blurY:30}}); //remove blur
}
function mouseOverContinueStory(event:MouseEvent):void {
continueStoryLink.addEventListener(MouseEvent.CLICK,clickContinueStory); //add listener for clicking this link
TweenMax.to(continueStoryLink, 1, {glowFilter:{color:0xFFFFFF, alpha:1, blurX:30, blurY:30}}); //glow on mouseover
function clickContinueStory(event:MouseEvent):void {
currentPage = "continue_story";
trace("continueStoryClicked");
}
}
function mouseOutContinueStory(event:MouseEvent):void {
TweenMax.to(continueStoryLink, 1, {glowFilter:{color:0xFFFFFF, alpha:0, blurX:30, blurY:30}}); //remove blur
}
...
...
Then repeat those function pairs for the other 4 links on the page?
|
|
|
04-08-2012, 06:39 PM
|
#2
|
|
Senior Member
Join Date: Dec 2011
Location: Tucson, AZ
Posts: 1,898
|
Use an array and a for loop.
Use the button instance name as the currentPage. (rename the buttons if you have to)
ActionScript Code:
import com.greensock.*;
var array:Array =
[
newStory,
continueStory,
selectChapter,
options,
characters,
about
];
var currentPage:String;
for each (var mc:MovieClip in array)
{
mc.buttonMode = true;
mc.mouseChildren = false;
mc.addEventListener(MouseEvent.ROLL_OVER, onOver);
mc.addEventListener(MouseEvent.ROLL_OUT, onOut);
mc.addEventListener(MouseEvent.CLICK, onClick);
}
function onOver(e:MouseEvent):void
{
TweenMax.to(e.target, 1, {glowFilter:{color:0xFFFFFF, alpha:1, blurX:30, blurY:30}});
}
function onOut(e:MouseEvent):void
{
TweenMax.to(e.target, 1, {glowFilter:{color:0xFFFFFF, alpha:0, blurX:0, blurY:0, remove:true}});
}
function onClick(e:MouseEvent):void
{
currentPage = e.target.name;
trace(currentPage);
}
|
|
|
04-10-2012, 12:33 AM
|
#3
|
|
Member
Join Date: Apr 2012
Posts: 52
|
Thank you!
Works perfectly.
I adde this to the onClick function to go to various pages for various links, is it the correct way to add?
ActionScript Code:
function onClick(e:MouseEvent):void
{
currentPage = e.target.name;
trace(currentPage);
if (e.target.name == "newStoryLink") {
delegate.beginStory();
} else if (e.target.name == "continueStoryLink") {
//do something else
} else if ...
...
etc
}
|
|
|
04-10-2012, 03:08 AM
|
#4
|
|
Senior Member
Join Date: Dec 2011
Location: Tucson, AZ
Posts: 1,898
|
Not sure how your application is structured, but using a conditional statement for your primary navigation is almost certainly a bad idea.
Instead, you should include the destination pages in your primary dataset.
If your application is more complex than a simple Array (apparently, it is), use a more complex data source, such as XML or an associative array.
XML is probably the most common source for data in Flash projects. Can be external or internal.
|
|
|
04-10-2012, 05:09 PM
|
#5
|
|
Member
Join Date: Apr 2012
Posts: 52
|
Quote:
Originally Posted by [afz]snickelfitz
Not sure how your application is structured, but using a conditional statement for your primary navigation is almost certainly a bad idea.
Instead, you should include the destination pages in your primary dataset.
If your application is more complex than a simple Array (apparently, it is), use a more complex data source, such as XML or an associative array.
XML is probably the most common source for data in Flash projects. Can be external or internal.
|
I'm new to AS, don't really have any idea how XML works, and I don't really want to research into linking XML with AS for now. Creating if statements is pretty much the best I can do right now for creating a standard menu with lots of intersecting links.
But I ran into a problem: I can't access the links on anything other than frame 1. I laid out every single menu window in frames (got around 35 frames or so). The total number of different links is around 30 (lots of window use the same links, like "back to main menu"). For example, clicking "back to main menu" will go to frame 1 regardless of what window the user is currently on. I put all of these into the array:
ActionScript Code:
var mainMenuArray:Array =
[
//Main menu which is frame 1
menuRightSide.newStoryLink,
menuRightSide.continueStoryLink,
menuRightSide.selectChapterLink,
menuRightSide.optionsLink,
menuRightSide.charactersLink,
menuRightSide.aboutLink,
//chapters menu which is frame 2
menuRightSide.chapter1Link
menuRightSide.chapter2Link,
menuRightSide.chapter3Link,
menuRightSide.chapter4Link,
menuRightSide.chapter5Link,
...
...
]; //create array of links for menus
But obviously AS can't access instances in other frames other than frame 1. So is there any way to access those other links on the other 30-or-so frames? In order to keep it organized I want to put all the links into that array, then simply tell AS what to do when user clicks any of the links.
I don't want to do the following, since this is very messy:
ActionScript Code:
if (e.target.name == "selectChapterLink") {
menuRightSide.chapter1Link.addEventListener(MouseEvent.ROLL_OVER, onOverChapter1);
menuRightSide.chapter1Link.addEventListener(MouseEvent.ROLL_OVER, onOutChapter1));
menuRightSide.chapter1Link.addEventListener(MouseEvent.ROLL_OVER, onClickChapter1));
...//add 3 listeners for each chapter, which would be at least 15 lines of code
...
function onOverChapter1 ... {
...
//glow
}
function onOutChapter1 ... {
...
//fade out glow
}
function onClickChapter1 ... {
...
//go to destination chapter
}
As you can see the amount of duplicate code in this method would be ridiculous.
|
|
|
04-10-2012, 08:40 PM
|
#6
|
|
Senior Member
Join Date: Aug 2008
Location: Helsinki, Finland
Posts: 1,161
|
A small addition to check if links exist. Here's names of links in 3d array.
init() function will fire up checkFrame() function which checks the current frame.
checkFrame() (enterframe handler) function will call refreshLinks() function when ever frame changes.
refreshLinks() function will pick up sub array from mainMenuArray related to current frame number. Uses first element of the sub array as a container and transforms second element in it to containers object. Checks if there is no listeners yet set for that link and if not, set.
The very end of the code checks if app have just started if it have been running and depending on that declares "global" variables and initializes the app or just ignores them.
ActionScript Code:
import com.greensock.*;
var mainMenuArray:Array =
[
// all must exist in frame 1
[
[menuRightSide, "newStory"],
[menuRightSide, "continueStory"],
[menuRightSide, "selectChapter"],
[menuRightSide, "options"],
[menuRightSide, "characters"],
[menuRightSide, "about"],
],
// menuRightSide must exist in frame 1, chapters must exist in frame 2
[
[menuRightSide, "chapter1"],
[menuRightSide, "chapter2"],
[menuRightSide, "chapter3"],
[menuRightSide, "chapter4"],
[menuRightSide, "chapter5"]
]
// first value (MovieClip) must exist in frame 1 second value (String) in frame 3
[
...
...
]
];
function init():void
{
addEventListener(Event.ENTER_FRAME, checkFrame);
}
function refreshLinks(frame:int):void
{
var folders:Array = mainMenuArray[frame - 1];
for each(var folder:Array in folders)
{
var container:MovieClip = folder[0];
var name:String = folder[1];
var link:MovieClip = container[name];
// check if link isn't set yet.
if(!link.hasEventListener(MouseEvent.ROLL_OVER)){
link.buttonMode = true;
link.mouseChildren = false;
link.addEventListener(MouseEvent.ROLL_OVER, onOver, false, 0, true);
link.addEventListener(MouseEvent.ROLL_OUT, onOut, false, 0, true);
link.addEventListener(MouseEvent.CLICK, onClick, false, 0, true);
}
}
previousFrame = frame;
}
function onOver(e:MouseEvent):void
{
TweenMax.to(e.target, 1, {glowFilter:{color:0xFFFFFF, alpha:1, blurX:30, blurY:30}});
}
function onOut(e:MouseEvent):void
{
TweenMax.to(e.target, 1, {glowFilter:{color:0xFFFFFF, alpha:0, blurX:0, blurY:0, remove:true}});
}
function onClick(e:MouseEvent):void
{
currentPage = e.target.name;
trace(currentPage);
}
function checkFrame(e:Event):void
{
if(currentFrame != previousFrame)
{
refreshLinks(currentFrame);
}
}
if(!previousFrame){
var currentPage:String;
var previousFrame:int = -1;
init();
}
|
|
|
04-14-2012, 04:15 PM
|
#7
|
|
Member
Join Date: Apr 2012
Posts: 52
|
Hi thank you for your help lauri. Sorry for the late reply.
I'm a bit confused at the layout in the array. "MenuRightSide" is a class (with instance menuRightSide), inside this class there are a bunch of links like newStory and chapter1, each of these are movieclip instances. So normally in order to access newStory I'd have to write menuRightSide.newStory, but in your array these are separated.
Also if I understand the logic correctly, basically your function will keep advancing the frames until it finds the right frame that the instance being called is on? So for example if I click on "chapter1", since chapter1 is not on frame 1, it will keep searching through each frame until it finds "chapter1" on one of the frames, in this case frame 2? But what if I have links that are present in multiple frames? For example a "backToMenu" link, this is present on around 10 frames (pages), all with the same instance and class.
Thanks.
Last edited by LanLing; 04-14-2012 at 05:20 PM.
|
|
|
04-16-2012, 04:06 AM
|
#8
|
|
Member
Join Date: Apr 2012
Posts: 52
|
Up~
|
|
|
| Thread Tools |
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT. The time now is 08:25 AM.
///
|
|