A Flash Developer Resource Site

Results 1 to 5 of 5

Thread: [RESOLVED] Problem with Tween class dispatching duplicate TweenEvent.MOTION_FINISH events?

  1. #1
    Senior Member
    Join Date
    Jan 2006
    Posts
    133

    resolved [RESOLVED] Problem with Tween class dispatching duplicate TweenEvent.MOTION_FINISH events?

    Hello All,

    I have several buttons on stage that, when pressed, moves and scales a MovieClip a predetermined amount. I used to do this "procedurally" in AS2 using Zeno's Paradox; however, it looks as though the Tween class in AS3 should accomplish what I need pretty easily. (I am a little confused about the logical/situational differences between using the Tween class and the TransitionManager class, but the Tween class just seemed more straight forward)

    Anyway, once the MovieClip has finished moving and reached the destination X/Y and Scale values, I would like to be able tell that MovieClip to do something. By adding a listener for the TweenEvent.MOTION_FINISH, I can accomplish this; however, the problem arises if the user clicks on a button, and then clicks a different button BEFORE the MovieClip finishes moving. i.e. If the MovieClip is moving from Point A to Point B, and the user clicks Button C, then the MovieClip starts moving toward Point C from the MovieClip's current position... which is a desireable effect.

    However; BEFORE the MovieClip even reaches Point C, it appears as though a TweenEvent.MOTION_FINISH event is dispatched (presumeably from the A to B Tween). And, ANOTHER TweenEvent.MOTION_FINISH is dispatched once the MovieClip finally reaches Point C. So it seems as if the first Tween is still "running in the background" even though it's not having an effect on the MovieClip's x/y or scale values.

    Is there a way to "overwrite" the "old" Tween with the "new" Tween?

    I need to have only 1 finish event dispatched, even if the user is constantly clicking buttons before the MovieClip has finished moving.
    Code:
    import fl.transitions.Tween;
    import fl.transitions.TweenEvent;
    import fl.transitions.easing.*;
    
    myButton1_btn.addEventListener(MouseEvent.CLICK, fOnClick);
    myButton2_btn.addEventListener(MouseEvent.CLICK, fOnClick);
    
    var myTweenX:Tween;
    var myTweenY:Tween;
    var myTweenScaleX:Tween;
    var myTweenScaleY:Tween;
    
    function fOnClick(evtClick:MouseEvent):void{
    	
    	switch(evtClick.target.name){
    		case "myButton1_btn":
    			myTweenX = new Tween(myClip_mc, "x", Regular.easeInOut, myClip_mc.x, 200, 1, true);
    			myTweenY = new Tween(myClip_mc, "y", Regular.easeInOut, myClip_mc.y, 200, 1, true);
    			myTweenScaleX = new Tween(myClip_mc, "scaleX", Regular.easeInOut, myClip_mc.scaleX, 0.5, 1, true);
    			myTweenScaleY = new Tween(myClip_mc, "scaleY", Regular.easeInOut, myClip_mc.scaleY, 0.5, 1, true);
    			break;
    		case "myButton2_btn":
    			myTweenX = new Tween(myClip_mc, "x", Regular.easeInOut, myClip_mc.x, 500, 3, true);
    			myTweenX = new Tween(myClip_mc, "y", Regular.easeInOut, myClip_mc.y, 500, 3, true);
    			myTweenScaleX = new Tween(myClip_mc, "scaleX", Regular.easeInOut, myClip_mc.scaleX, 2.0, 3, true);
    			myTweenScaleY = new Tween(myClip_mc, "scaleY", Regular.easeInOut, myClip_mc.scaleY, 2.0, 3, true);
    			break;
    		default:
    			break;
    	}
    	
    	myTweenX.addEventListener(TweenEvent.MOTION_FINISH, fOnFinish);
    }
    
    
    function fOnFinish(evtTweenFinish:TweenEvent):void{
    	trace("Tween Finished!");
    }
    If I click on Button1 and then quickly on Button2, "Tween Finished!" is output twice.

  2. #2
    AS3 Mod
    Join Date
    Sep 2007
    Location
    O-H-I-O
    Posts
    2,385
    The best and easiest way to do this is to not use the Tween class in flash and instead use TweenLite

  3. #3
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    Why is a third-party class like TweenLite the best?

    I would rather have a solution within Adobe's software package for various reasons, in a production environment, it's hard enough as it is for someone familiar with Flash and AS3 to sit down with an .FLA that they've never seen before, and written by an author who they've never worked with before... so, to introduce a third-party class just adds that much more of a headache. Also, it looks as though TweenLite has a "gs" folder that needs to live with the FLA... which presents another organizational problem.

    ANYWAY, in the future when I'm doing personal or one-off projects, TweenLite may work, but in this situation, the BEST solution is to work with what Adobe gives you. So, anyone who can give me some input as to how to solve my problem within the constructs of the software would be greatly appreciated!

  4. #4
    AS3 Mod
    Join Date
    Sep 2007
    Location
    O-H-I-O
    Posts
    2,385
    Everything is compiled into the swf, so the only file you will have to deploy into production is the swf file, not the gs folder or any other assets that are imported. TweenLite has a TON of features and will do exactly what you want to do natively with less cluttered code.

    Anyhow you can try this approach (un-tested):

    PHP Code:
    import fl.transitions.Tween;
    import fl.transitions.TweenEvent;
    import fl.transitions.easing.*;

    myButton1_btn.addEventListener(MouseEvent.CLICKfOnClick);

    var 
    myTweenX:Tween;
    var 
    myTweenY:Tween;
    var 
    myTweenScaleX:Tween;
    var 
    myTweenScaleY:Tween;

    function 
    fOnClick(evtClick:MouseEvent):void{
        
    // If the tween exists then stop and delete it
        
    if(myTweenX != null) {
            
    myTweenX.stop();
            
    myTweenX null;
            
            
    myTweenY.stop();
            
    myTweenY null;
            
            
    myTweenScaleX.stop();
            
    myTweenScaleX null;
            
            
    myTweenScaleY.stop();
            
    myTweenScaleY null;
        }
        
        switch(
    evtClick.target.name){
            case 
    "myButton1_btn":
                
    myTweenX = new Tween(myClip_mc"x"Regular.easeInOutmyClip_mc.x2001true);
                
    myTweenY = new Tween(myClip_mc"y"Regular.easeInOutmyClip_mc.y2001true);
                
    myTweenScaleX = new Tween(myClip_mc"scaleX"Regular.easeInOutmyClip_mc.scaleX0.51true);
                
    myTweenScaleY = new Tween(myClip_mc"scaleY"Regular.easeInOutmyClip_mc.scaleY0.51true);
                break;
            case 
    "myButton2_btn":
                
    myTweenX = new Tween(myClip_mc"x"Regular.easeInOutmyClip_mc.x5003true);
                
    myTweenX = new Tween(myClip_mc"y"Regular.easeInOutmyClip_mc.y5003true);
                
    myTweenScaleX = new Tween(myClip_mc"scaleX"Regular.easeInOutmyClip_mc.scaleX2.03true);
                
    myTweenScaleY = new Tween(myClip_mc"scaleY"Regular.easeInOutmyClip_mc.scaleY2.03true);
                break;
            default:
                break;
        }
        
        
    myTweenX.addEventListener(TweenEvent.MOTION_FINISHfOnFinish);
    }

    function 
    fOnFinish(evtTweenFinish:TweenEvent):void{
        
    trace("Tween Finished!");


  5. #5
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    That'll do it, thanks!

    It should've been obvious to me... but it just seems strange that I have to explicitly call a stop() method (when I didn't call the start() method) and set the Tween object to null, instead of just overwriting the myTweenX object by using the "new" constructor...

    But, I guess that's just another reason why TweenLite is preferable.

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