开发者

Actionscript 3 menu with active state

Ive got a simple menu that upon hover of each item, plays a movie clip, then on mouse_out it plays the movie clip in reverse. What I'm trying to do is to have a third state (active) that is shown upon clicking. I'm thinking I need to do something along the lines of:

When clicked, gotoAndStop(5) //Five being the location of my active frame Also remove the event listener that triggers the function to play the movie in reverse. Then when another menu item is clicked, re-add the event listener to the previous menu item so it's not stuck 'active'

I can't quite figure out how to do this though. My code is as follows:

// IMPORTS

import fl.transitions.*;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import flash.external.ExternalInterface;

// EVENT LISTENERS

//arrow
mcArrow.addEventListener(MouseEvent.MOUSE_OVER,mover);
mcArrow.addEventListener(MouseEvent.MOUSE_OUT,mout);

//dots
mcDots.addEventListener(MouseEvent.MOUSE_OVER,mover);
mcDots.addEventListener(MouseEvent.MOUSE_OUT,mout);

//music
mcMusic.addEventListener(MouseEvent.MOUSE_OVER,mover);
mcMusic.addEventListener(MouseEvent.MOUSE_OUT,mout);

//home
mcHome.addEventListener(MouseEvent.MOUSE_OVER,mover);
mcHome.addEventListener(MouseEvent.MOUSE_OUT,mout);

//padlock
mcPadlock.addEventListener(MouseEvent开发者_高级运维.MOUSE_OVER,mover);
mcPadlock.addEventListener(MouseEvent.MOUSE_OUT,mout);

// FUNCTIONS

function mover(e:MouseEvent):void {
    stopPlayReverse(e.currentTarget as MovieClip);
    e.currentTarget.play();
//var fadeIn:Tween = new Tween(mcToolTip, "alpha", Strong.easeOut, 0, 1, 0.5, true);
}

function mout(e:MouseEvent):void {
    var mc:MovieClip = e.currentTarget as MovieClip; 
    if (mc !== null) {
     mc.addEventListener(Event.ENTER_FRAME, playReverse, false, 0, true);
    }
    //var fadeOut:Tween = new Tween(mcToolTip, "alpha", Strong.easeOut, 1, 0, 0.5, true);
}

function playReverse(e:Event):void {
    var mc:MovieClip = e.currentTarget as MovieClip; 

    if (mc.currentFrame == 1) {
        stopPlayReverse(mc);
    } else {
        mc.prevFrame();
    }
}

function stopPlayReverse(mc:MovieClip):void {
  if ((mc!==null) && mc.hasEventListener(Event.ENTER_FRAME)) {
    mc.removeEventListener(Event.ENTER_FRAME, playReverse);
  }
}


First I would create a MenuItem class that sets up the event listeners and methods for the menu items. In the MenuItem class, create an 'isActive' property of type Boolean that keeps track of the current state of the menu item. Here's a quick mock-up of that class:

package {
    import flash.display.MovieClip;
    import flash.events.*;

    public class MenuItem extends MovieClip {
        public var isOver:Boolean = false;
        public var isActive:Boolean = false;
        public static var CLICK:String = 'menu_item_click';

        public function MenuItem() {
            addEventListener(MouseEvent.MOUSE_OVER, mover);
            addEventListener(MouseEvent.MOUSE_OUT, mout);
            addEventListener(MouseEvent.CLICK, mclick);
            addEventListener(Event.ENTER_FRAME, onFrame);
        }

        private function mover(e:MouseEvent):void {
            isOver = true;
        }

        private function mout(e:MouseEvent):void {
            isOver = false;
        }

        private function mclick(e:MouseEvent):void {
            isActive = true;
            goToAndStop(5); // go to active frame
        }

        private function onFrame(e:Event):void {
            if (isActive) return; // don't do anything if this menu item is active

            if (isOver) { // if the mouse is over the menu item
                if (currentFrame >= 4) { // make sure we don't go to frame 5, the active frame
                    nextFrame();
                }
            } else {
                prevFrame(); // or play in reverse. If at frame 1, prevFrame() won't do anything
            }
        }
    }   
}

The ENTER_FRAME listener will run continuously and perform actions based on the isActive and isOver states. This eliminates the need for removing listeners and creating additional methods for playReverse and stopPlayReverse.

Second, I would put all of the menu items in container class called MenuContainer. The easiest way to do this would be to create an empty movie clip in Flash, then drag all of your menu items into it. Export the container for Actionscript with the Class value of MenuContainer. Here is a mock-up of the MenuContainer class:

package {
    import flash.display.MovieClip;
    import flash.events.*;

    public class MenuContainer extends MovieClip {

        public function MenuContainer() {
            addEventListener(MenuItem.CLICK, onMenuItemClick);
        }

        private function onMenuItemClick(e:MouseEvent):void {
            var clickedMenuItem:MenuItem = MenuItem(e.target); // the clicked menu item
            for (var i:int = 0; i < this.numChildren; i++) { // loop through the menu items
                var menuItem:MenuItem = MenuItem(this.getChildAt(i)); // get the loop menu item
                if (menuItem != clickedMenuItem) { // if the loop menu item is not the clicked menu item
                    menuItem.isActive = false; // then isActive is false
                }
            }
        }

    }   
}


Another option, following your code, would be to have an auxiliary variable that indicates which menu item is currently active, so we can deactivate it once we click on another item... that means each of your menu items would execute this function on click:

private var activeMenuItem:MenuItem; //your auxiliary variable
private function onClick(e:MouseEvent):void {
   if(activeMenuItem) {
     //if there is an active menu item re-enable it
     activeMenuItem.gotoAndStop(1);
     activeMenuItem.mouseEnabled=true;
   }
   //set the active menu item to the clicked one
   activeMenuItem=e.currentTarget;
   //and set its state to active and mouse disabled
   activeMenuItem.gotoAndStop(5);
   activeMenuItem.mouseEnabled=false;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜