Hello!
Did you ever wanted to create a menu in Flash which can manage the different sections of your site"
I see that lots of Flash designers and webmasters with a minimal notion of Actionscript, has problems to control the events of a menu associated to different MovieClip nested in the main timeline.
I make an example using 5 buttons or MovieClip which once clicked will carry out a certain action on the timeline of a MovieClip and that the animation remains on the active state so that the user can understand easily into which section he is.
So, after having seen how to create a site loading external swf, with this tutorial we will see how to manage the menu and the sections of our Flash site from the Document Class.
To start with, I would like to point to the fact that it is better not to have animations on the main timeline.
Also, an important thing is the fact that with Flash CS3 we can not write anymore codes on the MovieClip itself and so we are obliged to use cycles and arrays to control a multiple menu such as the one explained next.
If you have any doubt about the cycle and the arrays, I recommend you to read the following articles:
- array in Actionscript
- loops in Actionscript
I create a FLA and I save it as "main.fla".
Into which, I create 6 levels, starting from the top, named: menu, section5, section4, section3, section2, section1.
I create the menu:
- I create a MovieClip named in library mc_menu
- I create 5 other MovieClip that will serve as buttons for our menu named in library: mc_menu1, mc_menu2, mc_menu3, mc_menu4, md_menu5.
- Into each one of those MovieClip, I create 2 key frames (so to have 3 of them in total) and I change the color of the button. This way, we can control its timeline with Actionscript from a mouse event.
- Also, each one of those MovieClip has 2 levels. On the first level, we will have the text as item menu and on the second level will have the graphic part of it into each keyframe so to recreate the different state of the button.
- I add the 5 MovieClip into mc_menu
- I drag mc_menu on stage and I assign to it an instance name "menu_mc"
- Into menu_mc, I assign the instance names to the 5 MovieClip: menu1_mc. menu2_mc, menu3_mc, menu4_mc, menu5_mc.
I create the sections:
- I create 5 MovieClip named in library mc_section1, mc_section2, mc_section3, mc_section4, mc_section5
- each one of those MovieClip has an animation inside it of 60 frames. In the first 30 frames, the animation does a fadeIn while from 30 to 60, the animation does a fadeOut
- On key frame 30 and 60, I open the action panel and I add a stop();
- I drag from the library the 5 MovieClip, each one in their respective level, and I assign to them the correspondent instance name: section1_mc, section2_mc, section3_mc, section4_mc, section5_mc.
Now, I can create the Document Class, an AS file saved as "Main.as", implemented the following way:
Code:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class Main extends MovieClip
{
private var menu_array:Array;
private var section_array:Array;
private var currentSection:int=0;
private var nextSection:int;
public function Main()
{
init();
}
private function init():void
{
menu_array=new Array(menu_mc.menu1_mc,menu_mc.menu2_mc,menu_mc.menu3_mc,menu_mc.menu4_mc,menu_mc.menu5_mc);
section_array=new Array(section1_mc,section2_mc,section3_mc,section4_mc,section5_mc);
stage.frameRate=31;
stopAll();
addMenuEvents();
hideCurrentSection();
}
private function stopAll():void
{
for(var i:int=0;i < menu_array.length;i++)
{
menu_array[i].stop();
section_array[i].stop();
}
}
private function addMenuEvents():void
{
for(var i:int=0;i < menu_array.length;i++)
{
menu_array[i].mouseChildren=false;
menu_array[i].buttonMode=true;
menu_array[i].id=i;
menu_array[i].isPressed=false;
menu_array[i].addEventListener(MouseEvent.MOUSE_OVER,setOver);
menu_array[i].addEventListener(MouseEvent.MOUSE_OUT,setOut);
menu_array[i].addEventListener(MouseEvent.MOUSE_DOWN,setDown);
menu_array[i].addEventListener(MouseEvent.MOUSE_UP,setUp);
}
}
private function setOver(evt:MouseEvent):void
{
if(evt.target.isPressed==false)
evt.target.gotoAndStop(2);
}
private function setOut(evt:MouseEvent):void
{
if(evt.target.isPressed==false)
evt.target.gotoAndStop(1);
}
private function setDown(evt:MouseEvent):void
{
nextSection=evt.target.id;
checkState(evt.target.id);
evt.target.gotoAndStop(3);
hideCurrentSection();
currentSection=evt.target.id;
}
private function setUp(evt:MouseEvent):void
{
if(evt.target.isPressed==false)
evt.target.gotoAndStop(1);
}
private function checkState(n:int):void
{
for(var i:int=0;i < menu_array.length;i++)
{
if(i==n)
menu_array[i].isPressed=true;
else
{
menu_array[i].isPressed=false;
menu_array[i].gotoAndStop(1);
}
}
}
private function hideCurrentSection():void
{
section_array[currentSection].gotoAndPlay(31);
showSection();
}
private function showSection():void
{
section_array[nextSection].gotoAndPlay(2);
}
}
}
Let us analyse the code
I import the needed classes
import flash.display.MovieClip;
import flash.events.MouseEvent;
Properties
Two Arrays into which I insert the MovieClip of the menu and the ones for the sections
private var menu_array:Array;
private var section_array:Array;
a numerical variable into which I insert the section"s number currently active
private var currentSection:int=0;
a numerical variable into which I will insert the section"s number based on the clicked menu voice
private var nextSection:int;
Constructor function
I call the method init
init();
Methods
init();
I populate the arrays with the names of the MovieClip placed on stage. I insert the menu"s MovieClip into menu_array and the section"s MovieClip into section_array
menu_array=new Array(menu_mc.menu1_mc,menu_mc.menu2_mc,menu_mc.me nu3_mc,menu_mc.menu4_mc,menu_mc.menu5_mc);
section_array=new Array(section1_mc,section2_mc,section3_mc,section4 _mc,section5_mc);
I impost the frame rate
stage.frameRate=31;
I call the method stopAll which will stop all the MovieClip placed on stage
stopAll();
I call the method addMenuEvents which will manage the listeners and the events for each menu"s MovieClip
addMenuEvents();
I call the method hideCurrentSection which will display the first section
hideCurrentSection();
stopAll();
using a loop I tell stop to the menu"s MovieClip and to the section"s MovieClip
for(var i:int=0;i < menu_array.length;i++)
{
menu_array[i].stop();
section_array[i].stop();
}
addMenuEvents();
still using an Actionscript loop I pass to the MovieClip a serial of action to take
for(var i:int=0;i < menu_array.length;i++)
{
I tell to the menu"s MoveClip to deactivate every mouse events on any object placed into it, otherwise the hand pointer would not be visible if the mouse is above the text field (see the trick of the day " mouseChildren )
menu_array[i].mouseChildren=false;
I use mouseButton=true for each MC, so the hand pointer is visible when passing over those MC
menu_array[i].buttonMode=true;
I create a property to each MC named id and I assign to it the value of i at the moment of the iteration of the cycle. When the user will act on that MC, I will know which section to call using that id as index of the array section_array
menu_array[i].id=i;
I create another property to each MC named isPressed and I assign to it the value false. This value will be true when the user click that MC and it will allow to start or not the timeline based on the value of isPressed
menu_array[i].isPressed=false;
I add the necessary listeners to the 4 main mouse events: MOUSE_OVER, MOUSE_OUT, MOUSE_DOWN, MOUSE_UP which will cal the respective functions: setOver, setOut, setDown and setUp
menu_array[i].addEventListener(MouseEvent.MOUSE_OVER,setOver);
menu_array[i].addEventListener(MouseEvent.MOUSE_OUT,setOut);
menu_array[i].addEventListener(MouseEvent.MOUSE_DOWN,setDown);
menu_array[i].addEventListener(MouseEvent.MOUSE_UP,setUp);
}
setOver();
I check if the value of the clicked MC"s property isPressed is false(retrieved with evt.target).
If that MC has already been clicked, I do not need to start its timeline as it needs to stay in the active state
if(evt.target.isPressed==false)
If the value is false, I move its timeline to frame2
evt.target.gotoAndStop(2);
setOut();
same thing as for setOver, I check if isPressed of the clicked MC is false
if(evt.target.isPressed==false)
I move its timeline to frame 1
evt.target.gotoAndStop(1);
setDown();
I impost the value of the variable nextSection equal to the value of id of the clicked section
nextSection=evt.target.id;
I call the function checkState passing to it the value of id of the clicked MC
checkState(evt.target.id);
I move its timeline to frame 3 (active state)
evt.target.gotoAndStop(3);
I call the function hideCurrentSection which will hide the current section and display the next one
hideCurrentSection();
I impost the value of the variable currentSection equal to the value of id for that clicked section
currentSection=evt.target.id;
setUp();
I check if isPressed of the clicked MC is false
if(evt.target.isPressed==false)
I move its timeline to frame 1
evt.target.gotoAndStop(1);
checkState(n:int):void
Using a cycle, I check the menu"s MC. If the value of i for the iteration at that moment is equal to the MC"s id passed by the function setDown, I impost isPressed = true to the element i in the array menu_array ( one of the menu"s MC, to be exact the one clicked )
for(var i:int=0;i < menu_array.length;i++)
{
if(i==n)
menu_array[i].isPressed=true;
If the i is not equal to n, I impost isPressed = false to the MC placed in the array menu_array at index i and I move its timeline to the normal state.
else
{
menu_array[i].isPressed=false;
menu_array[i].gotoAndStop(1);
}
}
hideCrentSection();
I start the animation of the MC which needs to disappear
section_array[currentSection].gotoAndPlay(31);
I callthe method showSection
showSection();
showSection();
I start the animation of the MC which needs to appear
section_array[nextSection].gotoAndPlay(2);
Source files:
Bookmarks