A Flash Developer Resource Site

Results 1 to 12 of 12

Thread: How can I turn off event listeners in other classes?

  1. #1
    Member
    Join Date
    Jul 2005
    Location
    Calgary AB
    Posts
    54

    Question How can I turn off event listeners in other classes?

    To save anyone reverse engineering my reams of code, here it is in a nutshell.

    Two buttons, left and right, move the (full screen) backgrounds. If you click the right arrow, the current background moves left, the new background is added to the right, is also moved left, and the old background is faded out. Think of it as a long stream of backgrounds, being moved back and forth with the previously viewed one being faded out with a tween.

    The problem is that the arrows appear too soon, and clicking one breaks the whole thing.

    Main.as adds the arrows & adds the event listeners which then call the functions. The Main.as functions to move the backgrounds use background.moveLeft(); in the backgrounds class, which is where the fade out tweens happen.

    So - how do I turn OFF the buttons (added in Main.as) when the tween (in background.as) has finished? I've tried using something like " getNextRoom.addEventListener(TweenEvent.MOTION_FIN ISH, turnOff);" with turnOff referencing the arrows, but it complains that they don't exist (and in the backgrounds class they don't).
    Thanks!
    ~Nick

  2. #2
    Member
    Join Date
    Jul 2005
    Location
    Calgary AB
    Posts
    54
    Would code samples help?
    ~Nick

  3. #3
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Couldn't hurt.

    It sounds like your problem is one of scope. Instead of trying to reference children of another object, could you call methods in Main that accomplish the same goals? Or if you don't have a direct reference to Main, you could dispatch an event which Main listens for.

  4. #4
    Member
    Join Date
    Jul 2005
    Location
    Calgary AB
    Posts
    54

    Here is Main.as

    Actionscript Code:
    //Main
    package
    {
        import flash.display.MovieClip;
        import flash.events.Event;
        import flash.events.MouseEvent;


        public class Main extends MovieClip
        {
            var livingRoom_mc:MovieClip = new livingRoom();
            var mediaRoom_mc:MovieClip = new mediaRoom();
            var gallery_mc:MovieClip = new MovieClip;
            var musicRoom_mc:MovieClip = new MovieClip;
            var lastRoom:Number = new Number ();
            var oldRoom:Number = new Number ();
            var newRoom:Number = new Number ();
            var currentRoom:Number = 1; // between 1 and lastRoom
            var nextRoom:Number = new Number();
            var goLeft:Left;
            var goRight:Right;
            var moving:String = new String ();
            var room:Array = new Array();
           
            public function Main()
            {
                room[1] = livingRoom_mc;
                room[2] = mediaRoom_mc;
                room[3] = gallery_mc;
                room[4] = musicRoom_mc;
       
                addChild(livingRoom_mc);
                lastRoom = 2;
               
                goLeft = new Left();
                goRight = new Right();

                this.addEventListener(MouseEvent.MOUSE_MOVE, checkMouseOn);
                startListening();

               
                // add menu
               
            }
            public function checkMouseOn(event:MouseEvent):void
            {
                if (mouseX > 2700)
                {
                    goRight.arrowOn();
                    isMouseOff();
                   
                }
                else
                if (mouseX < 150)
                {
                    goLeft.arrowOn();
                    isMouseOff();
                }
               
            }
           
            public function checkMouseOff(event:MouseEvent):void
            {
                if (mouseX < 2700 && mouseX >150)
                {  
                    goLeft.arrowOff();
                    goRight.arrowOff();
                    isMouseOn();
                }
            }
           
            public function isMouseOff():void
            {
                this.removeEventListener(MouseEvent.MOUSE_MOVE, checkMouseOn);
                this.addEventListener(MouseEvent.MOUSE_MOVE, checkMouseOff);
            }
           
            public function isMouseOn():void
            {
                this.removeEventListener(MouseEvent.MOUSE_MOVE, checkMouseOff);
                this.addEventListener(MouseEvent.MOUSE_MOVE, checkMouseOn);
            }
       
           
            //Rooms Functions
            public function startListening():void
            {   trace('StartListening. currentRoom:'+currentRoom);
                //Get the previous/next buttons
                if (currentRoom > 1)
                {
                addChild(goLeft);
                goLeft.addEventListener(MouseEvent.CLICK, callPrevRoom);
                }
               
                if (currentRoom < lastRoom)
                {
                addChild(goRight);
                goRight.addEventListener(MouseEvent.CLICK, callNextRoom);
                }
            }
                       
            public function callPrevRoom(event:MouseEvent)
                {
                    goLeft.removeEventListener(MouseEvent.CLICK, callPrevRoom);
                    stopListening();
                    nextRoom = currentRoom -1;
                    room[currentRoom].moveRight(false);
                    addChild(room[nextRoom]);
                    room[nextRoom].moveRight(true);
                    removeChild(room[currentRoom]);
                   
                    currentRoom--;
                    startListening();
                }                                  
               
            public function callNextRoom(event:MouseEvent)
                {  
                    goRight.removeEventListener(MouseEvent.CLICK, callNextRoom);
                    stopListening();
                    nextRoom = currentRoom +1;

                    room[currentRoom].moveLeft(false);
                    addChild(room[nextRoom]);
                    room[nextRoom].moveLeft(true);
                    removeChild(room[currentRoom]);
       
                    currentRoom++;
                    startListening();



                }      



           
            public function stopListening():void
            {      
                    goLeft.arrowOff();
                    goRight.arrowOff();

            }
        }
    }
    ~Nick

  5. #5
    Member
    Join Date
    Jul 2005
    Location
    Calgary AB
    Posts
    54

    Rooms.as (used for the rooms, or backgrounds)

    Actionscript Code:
    package
    {
        import flash.display.MovieClip;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import fl.transitions.Tween;
        import fl.transitions.TweenEvent;
        import fl.transitions.easing.*;
        import flash.filters.BlurFilter;
       
        public class rooms extends MovieClip
        {

            public function rooms()
            {

               
                //hideNotes();
            }


           
           
            //Room Navigation
            public function moveLeft(New:Boolean):void
            {
                trace(this +' moving left, New Room? ' + New );

                if (New == true)
                {   this.alpha = 1;
                    var getNewRoom:Tween = new Tween(this,"x",Strong.easeOut,2880,0,2,true);
                    getNewRoom.addEventListener(TweenEvent.MOTION_FINISH, listenAgain);
                }
                else if (New == false)
                {
                    var moveOldRoom:Tween = new Tween(this,"x",Strong.easeOut,0,-2880,2,true);
                    moveOldRoom.addEventListener(TweenEvent.MOTION_FINISH, turnOffLights);
                }
            }
           
            public function moveRight(New:Boolean):void
            {
                trace(this +' moving right New Room? ' + New );

                if (New == true)
                {   this.alpha = 1;
                    var getNextRoom:Tween = new Tween(this,"x",Strong.easeOut,-2880,0,2,true);
                    getNextRoom.addEventListener(TweenEvent.MOTION_FINISH, listenAgain);
                   
                }
                else if (New == false)
                {
                    var movePrevRoom:Tween = new Tween(this,"x",Strong.easeOut,0,2880,2,true);
                    movePrevRoom.addEventListener(TweenEvent.MOTION_FINISH, turnOffLights);
                }          
            }
           
            public function listenAgain(event:TweenEvent):void
            {
                    trace('yay, listening again.');
            }

           
       
           
            public function turnOffLights(event:TweenEvent):void
            {
               
                    var fadeThisRoom:Tween = new Tween(this,"alpha",Strong.easeOut,1, 0, 1,true);
                    fadeThisRoom.addEventListener(TweenEvent.MOTION_FINISH, removeRoom);
           
            }

            public function removeRoom(event:TweenEvent):void
            {
                    //removeChild(this);
            }

           
       
        }
    }
    ~Nick

  6. #6
    Member
    Join Date
    Jul 2005
    Location
    Calgary AB
    Posts
    54
    Thanks 5Tons. Yes, scope does sound like the problem. Putting the methods in Main seems to make sense. I'm wondering if I should put the methods in the class that the objects belong to? Does it matter? Something like 'arrow.turnOff'?
    ~Nick

  7. #7
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    I don't understand the last sentence. Which methods are you talking about?

    It looks like your arrows are in goLeft and goRight. So you could have a method in Main like:
    Code:
    public function leftArrowOff():void{
      goLeft.arrowOff();
    }
    But to call that from background (assuming background is a child of your Main instance) you would have to cast background's parent to Main. You could use root instead and then it wouldn't have to be the direct parent, but you're just swapping one assumption for another, and still confusing the view with the logic.

    So make leftArrowOff and rightArrowOff event handlers for new events that your background will dispatch.

    Code:
    //probably in constructor or setup or something
    addEventListener("leftOff", leftArrowOff);
    
    //at instance method level.
    private function leftArrowOff(e:Event):void{
      goLeft.arrowOff();
    }
    And rely on event bubbling to go up the displayList. Actually, you can avoid event bubbling entirely by adding your listener directly to the dispatching instance, but you've got lots of those.

    In Rooms.as, when you want the left arrow off:
    Code:
    dispatchEvent(new Event("leftOff", true));
    Now, you can further refine this by creating constant values for your event types rather than typing the same String more than once. And you can make your own Event subclass. Maybe you could make a NavigationEvent class which has state (on, off), and direction (left, right) as properties.

  8. #8
    Member
    Join Date
    Jul 2005
    Location
    Calgary AB
    Posts
    54
    [Thanks so much for your help so far! By the way, I learned AS1, then AS3 procedurally, and am now trying to get a handle on OOP, so I'm a bit rusty here!]
    I actually have two other classes, left and right, that each extend the Arrow class, but it seems that you've got a good grasp of what's going on.
    I also misnamed a class - each of the rooms is in a class of its own, which extends 'rooms' class.
    When you talk of parenting, do you mean using 'public class rooms extends Main' ? Does that then mean I can refer to everything in Main from within the rooms class? I'm getting lots of 'possibly undefined method' errors when trying new things.
    I think what I'm looking for is a global way to refer to something in a class, such as 'leftArrowOff', so whenever I need to shut off the arrows I can ie. when the tween is finished. Is that what is happening with the addEventListener you listed in code example 2?
    The only addEventListener I have used so far is for mouse interactivity! Is the example 2 saying 'if leftOff changes, do leftArrowOff'? Which I presume would be triggered in example 3?

    Your question: I was referring to any methods I've used. For example, if I want arrows to turn off, should I put the methods (which I'm perceiving as functionality) in the arrows class?

    Want more code?!
    ~Nick

  9. #9
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    When I say "parent", I mean in the display list sense. When one class extends another, the extended class is called a "superclass".

    When you have a subclass/superclass relationship, your subclass will inherit all the fields and methods of your superclass, which means that it will have its own copies of those things. You do not automatically get access to any particular superclass instance or its properties.

    I strongly discourage trying to make global variables. Although you can make things globally available through the use of static properties, you almost never actually need global variables.

    In the second code example (which is both the 2nd and 3rd code blocks above), there is no global access going on. Instead communication between the instances occurs through the use of the event system. The room will dispatch an event which basically means "Hey anyone who cares, I'm ready for navigation again!" (in fact, I suggest using something which describes what just happend rather than "leftOff" which describes how you want things to react). And the Main timeline is listening for that event so that it can react to it appropriately by setting the navigation ui.

    Regarding where to put methods, put them where they make sense. A method of an object should act on that object and/or its properties.

  10. #10
    Member
    Join Date
    Jul 2005
    Location
    Calgary AB
    Posts
    54
    That all makes sense - thanks. As you can see I'm still grappling a little with the concepts but the fog is clearing!
    I'll try the dispatchEvent hopefully tomorrow nite and report back.
    Cheers!
    ~Nick

  11. #11
    Member
    Join Date
    Jul 2005
    Location
    Calgary AB
    Posts
    54
    Here's my new Rooms.as
    Actionscript Code:
    package
    {
        import flash.display.MovieClip;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import fl.transitions.Tween;
        import fl.transitions.TweenEvent;
        import fl.transitions.easing.*;
        import flash.filters.BlurFilter;
       
        public class rooms extends MovieClip
        {

            public function rooms()
            {

               
                //hideNotes();
            }


           
           
            //Room Navigation
            public function moveLeft(New:Boolean):void
            {

                if (New == true)
                {   this.alpha = 1;
                    var getNewRoom:Tween = new Tween(this,"x",Strong.easeOut,2880,0,2,true);
                    getNewRoom.addEventListener(TweenEvent.MOTION_FINISH, newRoomIn);
                }
                else if (New == false)
                {
                    var moveOldRoom:Tween = new Tween(this,"x",Strong.easeOut,0,-2880,2,true);
                    moveOldRoom.addEventListener(TweenEvent.MOTION_FINISH, turnOffLights);
                }
            }
           
            public function moveRight(New:Boolean):void
            {

                if (New == true)
                {   this.alpha = 1;
                    var getNextRoom:Tween = new Tween(this,"x",Strong.easeOut,-2880,0,2,true);
                    getNextRoom.addEventListener(TweenEvent.MOTION_FINISH, newRoomIn);
                   
                }
                else if (New == false)
                {
                    var movePrevRoom:Tween = new Tween(this,"x",Strong.easeOut,0,2880,2,true);
                    movePrevRoom.addEventListener(TweenEvent.MOTION_FINISH, turnOffLights);
                }          
            }
           
            public function listenAgain(event:TweenEvent):void
            {
                dispatchEvent(new Event("hearing", true));
            }
           
            public function newRoomIn(event:TweenEvent):void
            {
                trace('new room is in.');
            }
           

           
            public function turnOffLights(event:TweenEvent):void
            {
                trace('Turning off lights in ' + this);
                    var fadeThisRoom:Tween = new Tween(this,"alpha",Strong.easeOut,1, 0, 1,true);
                    fadeThisRoom.addEventListener(TweenEvent.MOTION_FINISH, listenAgain);
            }

    and my new Main.as -

    Actionscript Code:
    //Main
    package
    {
        import flash.display.MovieClip;
        import flash.events.Event;
        import flash.events.MouseEvent;


        public class Main extends MovieClip
        {
            var livingRoom_mc:MovieClip = new livingRoom();
            var mediaRoom_mc:MovieClip = new mediaRoom();
            var gallery_mc:MovieClip = new MovieClip;
            var musicRoom_mc:MovieClip = new MovieClip;
            var lastRoom:Number = new Number ();
            var oldRoom:Number = new Number ();
            var newRoom:Number = new Number ();
            var currentRoom:Number = 1; // between 1 and lastRoom
            var nextRoom:Number = new Number();
            var goLeft:Left;
            var goRight:Right;
            var moving:String = new String ();
            var room:Array = new Array();
           
            public function Main()
            {
                room[1] = livingRoom_mc;
                room[2] = mediaRoom_mc;
                room[3] = gallery_mc;
                room[4] = musicRoom_mc;
       
                addChild(livingRoom_mc);
                lastRoom = 2;
               
                goLeft = new Left();
                goRight = new Right();

                this.addEventListener(MouseEvent.MOUSE_MOVE, checkMouseOn);
                startListening();
               
                //when to stop listening -
                addEventListener("hearing", startListeningAgain);

               
                // add menu
               
            }
            public function checkMouseOn(event:MouseEvent):void
            {
                if (mouseX > 2700)
                {
                    goRight.arrowOn();
                    isMouseOff();
                   
                }
                else
                if (mouseX < 150)
                {
                    goLeft.arrowOn();
                    isMouseOff();
                }
               
            }
           
            public function checkMouseOff(event:MouseEvent):void
            {
                if (mouseX < 2700 && mouseX >150)
                {  
                    goLeft.arrowOff();
                    goRight.arrowOff();
                    isMouseOn();
                }
            }
           
            public function isMouseOff():void
            {
                this.removeEventListener(MouseEvent.MOUSE_MOVE, checkMouseOn);
                this.addEventListener(MouseEvent.MOUSE_MOVE, checkMouseOff);
            }
           
            public function isMouseOn():void
            {
                this.removeEventListener(MouseEvent.MOUSE_MOVE, checkMouseOff);
                this.addEventListener(MouseEvent.MOUSE_MOVE, checkMouseOn);
            }
       
           
            //Rooms Functions
            public function startListening():void
            {   trace('StartListening. currentRoom:'+currentRoom);
                //Get the previous/next buttons
               


                if (currentRoom > 1)
                {trace('startListening - left arrow added')
                addChild(goLeft);
                goLeft.addEventListener(MouseEvent.CLICK, callPrevRoom);
                goRight.arrowOff();

                }
               
                if (currentRoom < lastRoom)
                {trace('startListening - right arrow added')
                addChild(goRight);
                goRight.addEventListener(MouseEvent.CLICK, callNextRoom);
                goLeft.arrowOff();
                }
            }
                       
            public function callPrevRoom(event:MouseEvent)
                {
                    goLeft.removeEventListener(MouseEvent.CLICK, callPrevRoom);
                    stopListening();
                    nextRoom = currentRoom -1;
                    room[currentRoom].moveRight(false);
                    addChild(room[nextRoom]);
                    room[nextRoom].moveRight(true);
                    removeChild(room[currentRoom]);
                    currentRoom--;
                }                                  
               
            public function callNextRoom(event:MouseEvent)
                {  
                    goRight.removeEventListener(MouseEvent.CLICK, callNextRoom);
                    stopListening();
                    nextRoom = currentRoom +1;

                    room[currentRoom].moveLeft(false);//move current room first...
                    addChild(room[nextRoom]);
                    room[nextRoom].moveLeft(true); // ...then get new room
                    removeChild(room[currentRoom]);
                    currentRoom++;
                   
                }      



           
            public function stopListening():void
            {      
                    goLeft.arrowOff();
                    goRight.arrowOff();
               
            }
           
            public function startListeningAgain(e:Event):void
            {   trace('Listening Again');
                startListening();
           
            }
        }
    }

    Arrow.as -
    Actionscript Code:
    package
    {
        import flash.display.MovieClip;
        import flash.events.Event;
        import flash.events.MouseEvent;
        // Flash - import Tween class
        import fl.transitions.Tween; //added to as
        import fl.transitions.TweenEvent;//added to as
        import fl.transitions.easing.*;//added to as
        import flash.filters.BlurFilter;
       
        public class Arrow extends MovieClip
        {
           
           
            public function Arrow()
            {
                this.alpha = 0;
                this.buttonMode = true;

            }
            public function arrowOn():void
            {  
                this.alpha = 1;
            }
           
            public function arrowOff():void
            {  
                this.alpha = 0;
            }



        }
    }
    I wrote some pseudo code to figure out what I need to happen when a button (arrow) is clicked:
    1. turn off arrow event listener
    2. turn off the arrows
    3. move the current room left
    4. get the next room and move it left
    5. fade out the current (now previous) room
    6. NOW start listening again, but only when the room has finished fading out


    Using trace statements I found that the dispatch event in rooms.as doesn't call startListeningAgain (in Main) when the room has finished fading, even though listenAgain does run. Any idea why?
    ~Nick

  12. #12
    Member
    Join Date
    Jul 2005
    Location
    Calgary AB
    Posts
    54
    Is there any code I'm missing to make this make more sense?
    ~Nick

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center