捣蛋鬼 - 如何处理补间?附测试案例+截图

时间:2012-08-17 23:05:24

标签: actionscript-3 flex actionscript tween greensock

大多数社交游戏(如CastleVille(c)Zynga或Magic Land(c)Wooga)都有 doobers - 硬币,星星等奖励给玩家一些简单的动作,比如砍掉一个树。

doobers似乎执行了几个补间:

  1. 首先他们跳出来,弹跳。它们的尺寸也会反弹。
  2. 之后,他们以更加贝塞尔曲线飞到比分栏。
  3. 我准备了一个非常简单的测试用例和我的问题的截图。测试用例是在Flex中,因为这是我最近一直在使用的,但我的问题更为通用(ActionScript,Tween)。我正在使用com.greensock.TweenMax库。

    我的问题:我已经想出如何做第二个更好的部分。但我不知道,如何做第一个,弹跳部分?

    enter image description here

    MyApp.mxml (不一定是Flex,可以是Flash):

    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                   xmlns:s="library://ns.adobe.com/flex/spark" 
                   xmlns:mx="library://ns.adobe.com/flex/mx" 
                   applicationComplete="init()">
    
        <fx:Script>
            <![CDATA[
                import mx.collections.ArrayList;
                import spark.core.SpriteVisualElement;
                import com.greensock.TweenMax;
                import com.greensock.easing.Cubic;
    
                private function init():void {
                    var g:Graphics = myComp.graphics;
                    g.clear();
                    g.beginFill(0xCCCCCC);
                    g.drawRect(0, 0, myComp.width, myComp.height);
                    g.endFill();                
                }           
    
                private function handleClick(event:MouseEvent):void {
                    var star:SpriteVisualElement = new Star();
                    star.x = event.localX;
                    star.y = event.localY;
                    myComp.addChild(star);
    
                    TweenMax.to(star, 1, {
                        delay: 2,
                        ease:  Cubic.easeOut,
                        bezier: [
                            {x: myComp.width - star.width, y: Math.max(event.localY, myComp.height/2)}, 
                            {x: myComp.width - star.width, y: 0}
                        ]
                    });
                }
    
            ]]>
        </fx:Script>    
    
        <mx:UIComponent id="myComp" width="100%" height="100%" click="handleClick(event)" />
    
    </s:Application>
    

    Star.fxg:

    <?xml version='1.0' encoding='UTF-8'?>
    <!-- fxg/star.fxg -->
    <fxg:Graphic xmlns:fxg="http://ns.adobe.com/fxg/2008" version="2">    
        <fxg:Path x="9.399" y="10.049" data="M 82.016 78.257 L 51.895 69.533 L 27.617 89.351 L 26.621 58.058 L 0.231 41.132 L 29.749 30.52 L 37.714 0.241 L 56.944 24.978 L 88.261 23.181 L 70.631 49.083 Z">
            <fxg:fill>
                <fxg:SolidColor color="#FFFFFF"/>
            </fxg:fill>
            <fxg:stroke>
                <fxg:SolidColorStroke 
                    caps="none" 
                    color="#4769C4" 
                    joints="miter" 
                    miterLimit="4" 
                    weight="20"/>
            </fxg:stroke>
        </fxg:Path>
    </fxg:Graphic>
    

    另外我想知道,如何在最后添加“宝丽来相机闪光灯”效果?

    更新

    借助LondonDrugs_MediaServices帮助(谢谢!),doobers现在挤压并跳转(代码如下),但我仍然有3个未解决的问题:

    1. 如何在鼠标悬停事件上运行flyTween?
    2. 如何在最后添加“宝丽来闪电战”补间?
    3. 最后不知道如何将鼠标移到处理程序上 - 因为它是一个非常封闭的
    4. 我也在the GreenSock forum发布了我的问题。

      感谢您提供任何提示

      <?xml version="1.0" encoding="utf-8"?>
      <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                     xmlns:s="library://ns.adobe.com/flex/spark" 
                     xmlns:mx="library://ns.adobe.com/flex/mx" 
                     applicationComplete="init()">
      
          <fx:Script>
              <![CDATA[
                  import com.greensock.TweenMax;
                  import com.greensock.easing.Bounce;
                  import com.greensock.easing.Cubic;
                  import spark.core.SpriteVisualElement;
      
                  private function init():void {
                      var g:Graphics = myComp.graphics;
                      g.clear();
                      g.beginFill(0xCCCCCC);
                      g.drawRect(0, 0, myComp.width, myComp.height);
                      g.endFill();                
                  }           
      
                  private function handleClick(event:MouseEvent):void {
                      var star:SpriteVisualElement = new Star();
                      star.x = event.localX;
                      star.y = event.localY;
                      myComp.addChild(star);
      
                      TweenMax.to(star, 2, {
                          bezier: [
                              {x:star.x + 10, y:star.y - 20, scaleX: 1,   scaleY: 1}, 
                              {x:star.x + 20, y:star.y + 20, scaleX: 1.2, scaleY: .8}, 
                              {x:star.x + 20, y:star.y + 30, scaleX: 1,   scaleY: 1}], 
                          orientToBezier: false, 
                          ease: Bounce.easeOut
                      });
      
                      var flyTween:TweenMax = TweenMax.to(star, 1, {
                          delay: 10,
                          ease:  Cubic.easeOut,
                          bezier: [
                              {x: myComp.width - star.width, y: Math.max(event.localY, myComp.height/2)}, 
                              {x: myComp.width - star.width, y: 0}
                          ],
                          onComplete: function():void {
                              myComp.removeChild(star);
                              // XXX how to remove the mouse over handler here?
                          }
                      });
      
                      star.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
                          // XXX how to force flyTween to execute right now, without the delay?
                          flyTween.complete();
                      });
                  }
              ]]>
          </fx:Script>    
      
          <mx:UIComponent id="myComp" width="100%" height="100%" click="handleClick(event)" />
      
      </s:Application>
      

      UPDATE2:谢谢LondonDrugs_MediaServices,这里再次更新截图+代码。

      与doobers一起玩很有趣,但仍有2个小问题:

      1. 我真的要杀死(延迟)补间飞行吗?我不能以某种方式修改它在鼠标上的延迟(设置为0)?
      2. 最后有“相机闪光”效果会很好。我只是不记得它是如何完成的 - 一些标准的Flash MX效果......
      3. enter image description here

        myApp.mxml在

        <?xml version="1.0" encoding="utf-8"?>
        <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx" 
                       applicationComplete="init()">
        
            <fx:Script>
                <![CDATA[
                    import com.greensock.TweenMax;
                    import com.greensock.easing.Bounce;
                    import com.greensock.easing.Cubic;
                    import flash.filters.GlowFilter;
                    import spark.core.SpriteVisualElement;
        
                    private function init():void {
                        var g:Graphics = myComp.graphics;
                        g.clear();
                        g.beginFill(0xCCCCCC);
                        g.drawRect(0, 0, myComp.width, myComp.height);
                        g.endFill();                
                    }           
        
                    private function goFlyTween(star:DisplayObject, delay:Number = 0):void {
                        TweenMax.to(star, 1, {
                            delay: delay,
                            ease:  Cubic.easeOut,
                            bezier: [
                                {x: myComp.width - star.width, 
                                 y: Math.max(star.y, myComp.height/2)}, 
                                {x: myComp.width - star.width, y: 0}
                            ],
                            onComplete: function():void {
                                if(star.parent)
                                    star.parent.removeChild(star);
                            }
                        });
                    }
        
                    private function handleClick(event:MouseEvent):void {
                        var star:SpriteVisualElement = new Star();
                        star.filters = [
                            new GlowFilter(0xffffff, 1, 4, 4, 10, 2), 
                            new GlowFilter(0x0, 1, 1.5, 1.5, 10, 2)
                        ];
                        star.x = event.localX;
                        star.y = event.localY;
                        myComp.addChild(star);
        
                        TweenMax.to(star, 2, {
                            bezier: [
                                {x:star.x + 10, y:star.y - 20, scaleX: 1,   scaleY: 1}, 
                                {x:star.x + 20, y:star.y + 20, scaleX: 1.2, scaleY: .8}, 
                                {x:star.x + 20, y:star.y + 30, scaleX: 1,   scaleY: 1}], 
                            orientToBezier: false, 
                            ease: Bounce.easeOut,
                            onComplete: goFlyTween,
                            onCompleteParams: [star, 3]
                        });
        
                        star.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
                            // instead of killing + recreating, can't we just reset the delay?
                            TweenMax.killTweensOf(star);
                            goFlyTween(star);
                        }, false, 0, true);
                    }
                ]]>
            </fx:Script>    
        
            <mx:UIComponent id="myComp" width="100%" height="100%" click="handleClick(event)" />
        
        </s:Application>
        

1 个答案:

答案 0 :(得分:1)

您可以采用与第二部分相同的基本方式。只需使用Bounce缓动函数,并向补间添加一些scaleX修改:(当然,您需要根据您的场景设置相应的x / y值)

TweenMax.to(star, 3, {bezier:[{x:star.x + 20, y:star.y - 10, scaleX: 1}, {x:star.x + 40, y:star.y + 20, scaleX: 2}, {x:star.x + 40, y:star.y + 30, scaleX: 1}], orientToBezier:false, ease:Bounce.easeOut});

修改

在编辑中还有其他问题:

我建议为你的flyTween制作一个单独的功能,但这并不是必要的,但在我看来,它可以让生活更清洁。 mouseOver处理程序上的弱侦听器将使其成为非问题,请参阅下面的代码中的更新。我不知道'Poloroid Blitz'是什么意思,所以你需要进一步解释。

      private function goFlyTween(star:DisplayObject, delay:Number = 0):void {
           TweenMax.to(star, 1, {
               delay: delay,
               ease:  Cubic.easeOut,
               bezier: [
                   {x: myComp.width - star.width, y: Math.max(event.localY, myComp.height/2)}, 
                   {x: myComp.width - star.width, y: 0}
               ],
               onComplete: function():void {
                    if(star.parent){
                        star.parent.removeChild(star);
               }
           });
       }



       private function handleClick(event:MouseEvent):void {
            var star:SpriteVisualElement = new Star();
            star.x = event.localX;
            star.y = event.localY;
            myComp.addChild(star);

            TweenMax.to(star, 2, {
                bezier: [
                    {x:star.x + 10, y:star.y - 20, scaleX: 1,   scaleY: 1}, 
                    {x:star.x + 20, y:star.y + 20, scaleX: 1.2, scaleY: .8}, 
                    {x:star.x + 20, y:star.y + 30, scaleX: 1,   scaleY: 1}], 
                orientToBezier: false, 
                ease: Bounce.easeOut,
                onComplete: goFlyTween,
                onCompleteParams: [star, 3]
            });

            star.addEventListener(MouseEvent.MOUSE_OVER,function(event:MouseEvent):void {
                TweenMax.killTweensOf(star);
                goFlyTween(star);
            },false,0,true); //use a weak listener (last parameter true on addEventListener), then you don't have to worry about removing the listener.  OR just don't use an anonymous function for this...
        }

对于您的退回补间,请使用onComplete参数: