23 Replies Latest reply on Aug 21, 2006 9:12 AM by Newsgroup_User

    Tween Issues - onMotionFinished() loops

    Level 7
      Using Flash 8, AS2

      I'm having an issue using scripted tweens.

      I have a tween that runs and an onMotionFinished() event handler that calls
      a continueTo() method. The problem is that the original tween continuously
      calls the onMotionFinished() method, which produces undesired results.

      I know I can use the stop() method to stop the animation, but I don't know
      what even to listen to.

      I suppose I could create a temp variable to count the number of times
      onMotionFinished() was called and then invoke the stop() method, but it
      seems that there is a better way to do this.

      Any help is appreciated.

      Sincerely,

      Chris Hayes


        • 1. Re: Tween Issues - onMotionFinished() loops
          Level 7
          Christopher,

          > I have a tween that runs and an onMotionFinished()
          > event handler that calls a continueTo() method. The
          > problem is that the original tween continuously calls
          > the onMotionFinished() method, which produces
          > undesired results.

          Isn't that what you want to happen, given the continueTo() method?

          > I know I can use the stop() method to stop the
          > animation, but I don't know what even to listen to.

          I guess I'm confused what you're after, then. :) If you want to stop,
          call the stop() method when handling the onMotionFinished event -- right?
          (Forgive me if I'm failing to see something obvious ... I believe the reason
          the event keeps getting dispatched is because of that continueTo() method,
          which you seem to want.)

          > I suppose I could create a temp variable to count the
          > number of times onMotionFinished() was called and
          > then invoke the stop() method, but it seems that there
          > is a better way to do this.

          If you want to continueTo() a set number of times, then stop(), that
          sounds like a great way to me. ;) The onMotionFinished event gets called
          every time the tween is finished, period.


          David Stiller
          Adobe Community Expert
          Dev blog, http://www.quip.net/blog/
          "Luck is the residue of good design."


          • 2. Re: Tween Issues - onMotionFinished() loops
            aniebel Level 2
            I have a similar post today on this topic. I need to figure out how to set up the tween to run for a set number of times but what I've done has caused my computer to bog down while testing. I will keep an eye on this post....
            • 3. Re: Tween Issues - onMotionFinished() loops
              kglad Adobe Community Professional & MVP
              aniebel, try:

              • 4. Re: Tween Issues - onMotionFinished() loops
                Level 7
                aniebel,

                > I have a similar post today on this topic. I need to figure out
                > how to set up the tween to run for a set number of times but
                > what I've done has caused my computer to bog down while
                > testing.

                Hmm. I'll look for your post.

                > I will keep an eye on this post....

                The Tween class isn't dynamic, so it can't have properties added to it
                at runtime, otherwise I would suggest something like this:

                // NOTE: Incorrect sample ActionScript!
                import mx.transitions.Tween;
                import com.robertpenner.easing.*;
                var tw:Tween = new Tween(ball, "_xscale", Circ.easeInOut, 800, 100, 12);
                tw.count = 0;
                var listener:Object = new Object();
                listener.onMotionFinished = function() {
                tw.count++;
                if (tw.count < 5) {
                tw.start();
                }
                };
                tw.addListener(listener);

                You still have to come up with a way to keep track of the counting, but
                at least the variable isn't "loose," somehwere. But again -- the Tween
                class is not open to having properties added to its instances at runtime.
                So ... you could put that property in the movie clip itsef (that would be
                ball.count = 0 above, and so on).

                Or you could write your own class, say Tween2, that extends Tween and
                adds a property for counting. That may not be a bad idea, actually, if you
                needed this sort of functionality often. The simplest fix-it-quick
                approach, though, would be to store the count value in a variable.


                David Stiller
                Adobe Community Expert
                Dev blog, http://www.quip.net/blog/
                "Luck is the residue of good design."


                • 5. Re: Tween Issues - onMotionFinished() loops
                  aniebel Level 2
                  Thanks to you both. Kglad, I'm going to give that a shot...
                  David, could you explain further what you mean by adding properties at runtime? I have successfully created functions such as the following which have properties added.

                  //in frame 1
                  function fSlide(mcName:MovieClip, begin:Number, end:Number, sec:Number):Void {
                  new Tween(mcName, "_x", Strong.easeOut, begin, end, sec, true);
                  }
                  //in frame 5
                  fSlide(about_btn, 300, 200, 1);


                  I just REREAD your post and noticed you said INSTANCES at runtime.... my bad.
                  • 6. Re: Tween Issues - onMotionFinished() loops
                    Level 7
                    aniebel,

                    > David, could you explain further what you mean by
                    > adding properties at runtime?

                    The MovieClip class is dynamic, which means you may add properties to
                    movie clips at runtime. For example, open a new FLA and create a quick
                    movie clip. Give that clip an instance name -- say, mcTest -- and enter the
                    following into your Actions panel.

                    mcTest.testProperty = "test value";

                    Test that SWF and you'll see no errors. Debug it, and you'll see the
                    mcTest instance with a new property, testProperty, attached to it.

                    Now add another line beneath that first one.

                    import mx.transitions.Tween;
                    var tw:Tween = new Tween();
                    tw.testProperty = "test value";

                    Test again and you'll see an error:

                    **Error** Scene=Scene 1, layer=Layer 1, frame=1:Line 4: There is no property
                    with the name 'testProperty'.
                    tw.testProperty = "test value";

                    Total ActionScript Errors: 1 Reported Errors: 1

                    Which means the compiler doesn't like it that you're trying to add a
                    property to that Tween instance. The Tween class isn't dynamic.

                    > I have successfully created functions such as the
                    > following which have properties added.
                    >
                    > //in frame 1
                    > function fSlide(mcName:MovieClip, begin:Number,
                    > end:Number, sec:Number):Void {
                    > new Tween(mcName, "_x", Strong.easeOut, begin, end, sec, true);
                    > }
                    > //in frame 5
                    > fSlide(about_btn, 300, 200, 1);

                    I think you might be talking about the parameters (or arguments) passed
                    into the fSlide() function, right? That's perfectly allowed, because your
                    fSlide() function passes those arguments right into the Tween constructor,
                    which *excepts* those arguments. Make sense?


                    David Stiller
                    Adobe Community Expert
                    Dev blog, http://www.quip.net/blog/
                    "Luck is the residue of good design."


                    • 7. Re: Tween Issues - onMotionFinished() loops
                      aniebel Level 2
                      Yeah, thanks! I realized after I sent that last post that you were speaking of the instance of the Tween class... not a function that includes it. As usual, you and kglad are a wealth of information and are patient enough to explain it in a manner that makes sense. Worth more than a million tutorials. :)

                      I haven't had a chance yet to try kglad's recommendation but I will and reply with results.
                      • 8. Re: Tween Issues - onMotionFinished() loops
                        Level 7
                        aniebel,

                        > I haven't had a chance yet to try kglad's
                        > recommendation but I will and reply with results

                        kglad's code is always good stuff. :) I keep a number of his more
                        popular samples in a function library to refer to sometimes.


                        David Stiller
                        Adobe Community Expert
                        Dev blog, http://www.quip.net/blog/
                        "Luck is the residue of good design."


                        • 9. Re: Tween Issues - onMotionFinished() loops
                          aniebel Level 2
                          wow.

                          Ok, maybe I should not be going this route. I want to try to do this only with AS but now that I see it working I wonder if I should just set my tween manually in the leaf mc. I got the code to work as you suggested, kglad, with a few edits to my main movie AS but... it runs reeeeeally slow. I don't think it's the code, I just think that there are too many mc's to react quickly. Maybe I should have explained better what I'm trying to do.

                          I have over 100 instances of this leaf mc on the stage and I want each of them to react when the wind mc runs across them. Like I said, it works but very slowly. My only other thought is that maybe I shouldn't be using onEnterFrame at all??? It's the only way I could get it to detect a hittest and I don't know what other event would work. I am using David Stiller's method for applying one function to multiple mcs.

                          Here is the code in my movie:

                          onEnterFrame = function(){
                          var allLeaves:MovieClip;
                          for(var i:Number=0; i<120; ++i){
                          allLeaves = this["leaf" + i ];
                          allLeaves.flutter(wind1_mc, 6);
                          }
                          if(wind1_mc._x ==736)
                          delete onEnterFrame;
                          };
                          • 10. Re: Tween Issues - onMotionFinished() loops
                            kglad Adobe Community Professional & MVP
                            if you eliminated the onEnterFrame in your flutter() method, your coding is fine: animating many movieclips will be noticable and lag most pcs. however, if you're using flash 8 you can enable the cacheAsBitmap property of your leaf movieclips and realize a significant efficiency built into the flash 8 player.

                            if you're still using an onEnterFrame handler in your flutter() method, you could be coding more efficiently.

                            • 11. Re: Tween Issues - onMotionFinished() loops
                              aniebel Level 2
                              Thanks, I've read up on cacheAsBitmap but it doesn't seem to help. Good thing to know though! I am beginning to think that this just won't work for me... that I'm asking too much of Flash and processors.

                              Are you saying not to use the onEnterFrame in the method within the Leaf class? If you are, I have taken those all out. The only onEnterFrame is in frame 1 of my movie and I'm not sure I applied the cacheAsBitmap properly but this is the edited code in frame one:
                              • 12. Re: Tween Issues - onMotionFinished() loops
                                aniebel Level 2
                                Just wanted to update... I replaced all my leaves with a mc that has a tween in it and trashed the Leaf class altogether. This works much faster. I am guessing at this (I don't truly understand how flash player processes things) but I think the Tween class was slowing it down.

                                I would love to understand why this didn't work. I really wanted it to be all scripted animation since I'm trying to learn these things but sometimes we need to do what's quickest. Thanks to you both!
                                • 13. Re: Tween Issues - onMotionFinished() loops
                                  kglad Adobe Community Professional & MVP
                                  you weren't enabling the cacheAsBitmap property of your movieclips. try:

                                  • 14. Re: Tween Issues - onMotionFinished() loops
                                    aniebel Level 2
                                    Forgive me if I'm being daft but wouldn't the clips be instantiated already if they are placed on the stage and given instance names? I know it may sound unnecessary but I manually placed each mc and gave each one a different instance name. I want to do it dynamically but I want to be sure I can get this to work first.

                                    • 15. Re: Tween Issues - onMotionFinished() loops
                                      kglad Adobe Community Professional & MVP
                                      you're correct and not crazy: placing your movieclips on-stage in the authoring environment does instantiate them.

                                      did you notice the difference in your code and my correction for the cacheAsBitmap property? did you notice any difference in performance when you used the cacheAsBitmap property correctly?
                                      • 16. Re: Tween Issues - onMotionFinished() loops
                                        aniebel Level 2
                                        Yes, I noticed a difference in the placement of the cachesAsBitmap but no, I did not notice any difference in performance. Do you mind looking at my FLA?

                                        File here

                                        Again, here is my class:
                                        • 18. Re: Tween Issues - onMotionFinished() loops
                                          aniebel Level 2
                                          Thanks, that does work a bit better. I'm not sure this is going to do the trick though. It still is not as quick as the version I've created with a tween done at authoring. But just to understand what you've done... It looks like you've set it so that the cache occurs only to those not yet hit. How does the "alreadyHit" method work? Did you just make it up to toggle? I didn't realize you could do that.
                                          • 19. Re: Tween Issues - onMotionFinished() loops
                                            kglad Adobe Community Professional & MVP
                                            with your code you were repeatedly calling your flutter() method on the same leaf movieclips.

                                            that caused an effect you did't want on-stage and utilized the tween class more often than necessary. that is, you were creating several tween objects per leaf.
                                            • 20. Re: Tween Issues - onMotionFinished() loops
                                              aniebel Level 2
                                              Thank you, I'm going to look into doing something similar but without the tween class. Thanks for all your help!
                                              • 22. Re: Tween Issues - onMotionFinished() loops
                                                Level 7
                                                > Isn't that what you want to happen, given the continueTo() method?

                                                The problem is that the end of the continueTo() method calls the
                                                onMotionFinished() event, which loops the whole process and the animation
                                                never stops

                                                > If you want to continueTo() a set number of times, then stop(), that
                                                > sounds like a great way to me. ;) The onMotionFinished event gets called
                                                > every time the tween is finished, period.

                                                This is what i'll have to do, but it just seems that you would be able to
                                                detect the onMotionFinished of a continueTo(), but I realize that since it's
                                                the same instance of the tween, all of the original events get triggered and
                                                create that loop. To fix it I could NOT use the continueTo() and just
                                                create a new Tween with it's own onMotionFinished event handler.

                                                Thanks for your help.

                                                Sincerely,

                                                Chris Hayes


                                                • 23. Re: Tween Issues - onMotionFinished() loops
                                                  Level 7
                                                  Chris,

                                                  >> The onMotionFinished event gets called every time
                                                  >> the tween is finished, period.
                                                  >
                                                  > This is what i'll have to do, but it just seems that you
                                                  > would be able to detect the onMotionFinished of a
                                                  > continueTo()

                                                  That would be nice, I agree.

                                                  > but I realize that since it's the same instance of the tween,
                                                  > all of the original events get triggered and create that loop.

                                                  You got it.

                                                  > To fix it I could NOT use the continueTo() and just
                                                  > create a new Tween with it's own onMotionFinished
                                                  > event handler.

                                                  That sounds like a good approach. Frankly -- this is just me -- I find
                                                  the Tween class to be a mixed bag. It can be very useful, but it also has a
                                                  few restrictions I don't care for. I'd like to be able to animate more than
                                                  one property (width *and* height, for example) with the same Tween
                                                  instance -- or more than one movie clip with the same instance.

                                                  But, it is what it is. And it certainly does make certain things very
                                                  easy.


                                                  David Stiller
                                                  Adobe Community Expert
                                                  Dev blog, http://www.quip.net/blog/
                                                  "Luck is the residue of good design."