2

I've been fumbling with this issue for a bit. I've got a lovely little tooltip movieclip that follows the user's mouse for a few seconds before it removes itself. My problem is that if there is one already there I remove it, however, I cannot seem to remove the MOTION_FINISH event and it still fires and possibly deletes a new tooltip.

What I want is to essentially put in a line item such as var tween(smallhelp_panel).deleteAll(); I saw a tweenlight function killtweensof(mc); However I've used the tweens I've incorporated below throughout my 30k lines of AS3 code.

Here is my tooltip handler. I call it with a simple

Main_Warning("Please don't forget to save!",5);

My movieclip is a 'smallhelp_panel' and I check if it already exists and remove it. However, the alpha and MOTION_FINISH tweens still exist and cause issues with any new smallhelp_panels.

public function Main_Warning( the_text:String, myTimer:int = 4){
        if(smallhelp_panel != null){
                stage.removeChild( smallhelp_panel );
                removeEventListener(Event.ENTER_FRAME, trackmouse);
                smallhelp_panel = null;
            }
        smallhelp_panel = new small_help();
        smallhelp_panel.name = "myWarning";
        smallhelp_panel.x = mouseX - 50;
        smallhelp_panel.y = mouseY + 15;
        smallhelp_panel.helptext.text = the_text;
        stage.addChild( smallhelp_panel );
        addEventListener(Event.ENTER_FRAME, trackmouse);
        var myTween:Tween;

        myTween = new Tween(smallhelp_panel, "alpha", None.easeOut, 1, 0, myTimer, true);
        tweenholder = myTween;
        tweenArray.push(tweenholder);
        myTween.addEventListener(TweenEvent.MOTION_FINISH, removeTween);
    }

That is my Tooltip handler.

for reference purposes my tween remover is:

public function removeTween(e:TweenEvent = null):void{
        e.target.removeEventListener(TweenEvent.MOTION_FINISH, removeTween);
        if(smallhelp_panel != null){
            removeEventListener(Event.ENTER_FRAME, trackmouse);
            stage.removeChild( smallhelp_panel );
            smallhelp_panel = null;
        }
    }

and my mouse tracker that moves the tooltip with the mouse is a simple:

public function trackmouse(e:Event):void{
        smallhelp_panel.x = mouseX - 50;
        smallhelp_panel.y = mouseY + 15;
    }
Charles
  • 50,943
  • 13
  • 104
  • 142
jc.021286
  • 220
  • 1
  • 4
  • 15

2 Answers2

0

That's because you've added your MOTION_FINISH event listener to the tween, not to the panel. You remove the panel, if one already exists, but the tween still exists in the tweenholder and tweenArray variables - and fires a MOTION_FINISH event, when its calculations are finished. Your event listener method doesn't know which tween the event came from, and correctly removes the help panel.

To fix this, either remove the tween and event listener along with the help panel in your Main_Warning function, or modify the removal block in your event listener method:

public function removeTween(e:TweenEvent = null):void{
    e.target.removeEventListener(TweenEvent.MOTION_FINISH, removeTween);
    // --- this will check if the Tween belongs to the panel on the stage!
    if (smallhelp_panel && e.target.obj == smallhelp_panel ) { 
    // ---
        removeEventListener(Event.ENTER_FRAME, trackmouse);
        stage.removeChild( smallhelp_panel );
        smallhelp_panel = null;
    }
    // --- NOW remove the tween from the array (all of them should be removed after use)
    tweenArray.splice (tweenArray.indexOf (e.target), 1); 
}

I don't understand exactly why you would need both a tweenholder and a tweenArray variable, though ;)

weltraumpirat
  • 22,544
  • 5
  • 40
  • 54
  • I tried this out and that works perfectly. I had issues for a while where my tweens were being garbage collected and I tried using the object and the holder. The object worked for instances where I had only 1 tween ever present, but adding multiple I found I needed the an array. So my rationale was if the object worked, placing that object into the array would store it. It was a beginner mistake that carried through. However, when I exit a section, I clear out the arrays & objects to free up those resources. This worked like a charm, I cannot say thank you enough. – jc.021286 Dec 17 '11 at 01:42
  • Once is plenty :) You're welcome. And might I suggest that for the future, you use TweenLite/TweenMax ( http://www.greensock.com/greenlite/ ) or another tweening library? They usually perform much better than the fl.transitions.Tween, are easier to manage, and also come with a convenient API. – weltraumpirat Dec 17 '11 at 07:57
  • I probably will for future projects. I had thought about it, but when you look back and see how much code you'd have to rip it out of... the undertaking of such a task looks too burdensome. I will however use it in any future projects. – jc.021286 Dec 17 '11 at 16:36
0

Your TweenEvent is still being listened for. You never remove the previous listener, so it will fire when the tween calculations are complete.

I assume tweenholder is declared somewhere global? (Like the other answer here, I'm confused as to your need of declaring a new tween, storing it in another reference and adding that reference to an array...) If so, try this:

public function Main_Warning( the_text:String, myTimer:int = 4){
    tweenholder.removeEventListener(TweenEvent.MOTION_FINISH,removeTween); 
    if(smallhelp_panel != null){
        ...
Prpl_Ppl_Etr
  • 131
  • 1
  • 7
  • I tried this out as well and it also works great at resolving the issue I was experiencing. So both solutions work just fine in my experience. I was thinking I might need to reference my tweenholder and go dig it out. But I did not know it would have been as easy as you outlined. Thank you, – jc.021286 Dec 17 '11 at 01:47