Flash/Flex學習筆記(38):緩動動畫

來源:互聯網
上載者:User

緩動 與 勻變速 看上去很類似,但其實有區別:

勻變速的公式為 V = V0 + at --速度v與時間t是線性(正比)關係,而且這種運動不需要確定目標點,速度可以按照這種規律一直變下去

而緩動指的是物體越接近目標時速度越慢,速度跟距離成反比關係,用公式描述為 V = k S  (0<k<1),這種運動需要先確定一個目標點,比如車輛定點停車:先指定一個位置,然後汽車從遠處開過來,快到停車點時,逐漸慢下來,直到準確停在指定位置。

先看個示範:

代碼:

package {import flash.display.Sprite;import flash.events.Event;import flash.events.MouseEvent;import flash.ui.Mouse;import flash.ui.MouseCursor;public class Easing1 extends Sprite {private var ball:Ball;private var easing:Number=0.15;private var targetX:Number=stage.stageWidth/2;private var targetY:Number=stage.stageHeight/2;public function Easing1() {trace(targetX,targetY);init();}private function init():void {ball=new Ball(10)  ;ball.x = Math.random() * stage.stageWidth;ball.y = Math.random() * stage.stageHeight;addChild(ball);addEventListener(Event.ENTER_FRAME,EnterFrameHandler);ball.addEventListener(MouseEvent.MOUSE_DOWN,MouseDownHandler);stage.addEventListener(MouseEvent.MOUSE_UP,MouseUpHandler);ball.addEventListener(MouseEvent.MOUSE_OVER,function(){ Mouse.cursor = MouseCursor.HAND;});//在中心畫個十字架graphics.lineStyle(1);graphics.moveTo(targetX-15,targetY);graphics.lineTo(targetX+15,targetY);graphics.moveTo(targetX,targetY -15);graphics.lineTo(targetX,targetY +15);}private function EnterFrameHandler(e:Event):void {var vx:Number = (targetX - ball.x) * easing; //x軸速度與距離成正比縮小var vy:Number = (targetY - ball.y) * easing; //y軸速度與距離成正比縮小ball.x += vx;ball.y += vy;var dx = ball.x - targetX;var dy = ball.y - targetY;var dist = Math.sqrt(dx*dx + dy*dy);//當物體達到目標點時,停止處理,以節省CPU資源if (dist<=1){removeEventListener(Event.ENTER_FRAME,EnterFrameHandler);}}//開始拖動private function MouseDownHandler(e:MouseEvent):void{ball.startDrag();removeEventListener(Event.ENTER_FRAME,EnterFrameHandler);}//停止拖動private function MouseUpHandler(e:MouseEvent):void{ball.stopDrag();addEventListener(Event.ENTER_FRAME,EnterFrameHandler);Mouse.cursor = MouseCursor.AUTO;}}}

特別要注意的問題:

先來瞭解一下著名的"Xeno悖論",假如一個物體要從A點移動到B點,可以這樣處理:每次將物體移動一半的距離,然後再以物體所在新位置為A點,繼續前面的處理... 這樣物體會不斷向B點靠近,直到移動到B點;但從另一角度考慮,因為每次只移動一半的距離,所以永遠也不可能真正達到B點。

如果我們把上面代碼中的比例因素private var easing:Number=0.15;改成0.5,就形成了該悖論。同時再考慮另一個因素,Flash每次能將物體移動的最小距離為0.05象素(即1/20象素),比這個值再小的距離,Flash將不會處理。

這樣的話,假設物體要移動到 100的x座標位置,當前已經到了99.95,根據比例因素0.5的設定,下一次應該移動 (100 - 99.95)/2 = 0.025,這個值已經超出了Flash的處理能力,系統會把0.025當成0來處理,即不移動。

所以再回頭看上面的代碼,我們在判斷物體是否到達目標點時,不能用 ball.x == targetX 來精確判斷,因為這樣的條件也許永遠不會成立,從而導致後面的removeEventListener也永遠不會被執行到,合理的做法是達到一定的精度值時,就可以認為已經移動完成,從而做出相應的處理.

緩動滑鼠跟隨

相信大多數人都玩過“星際”,我最喜歡神族的航母艦隊:浩浩蕩蕩很是壯觀。這裡面有一個細節,我們可以在一隊航母中,指定一個為領隊,其它隨便挑一個跟著它,然後後面的再跟著第二個,第三個跟著第二個...,這樣出發時,其實就很接近下面要示範的緩動滑鼠跟隨

代碼:

package {import flash.display.Sprite;import flash.events.MouseEvent;import flash.events.Event;public class Easing3 extends Sprite {var arrBall:Array ;var targetX:Number ;var targetY:Number;var easing:Number = 0.3;var firstBall:Ball;public function Easing3():void{init();}private function init():void{arrBall = new Array(30);for(var i:uint=0,j:uint=arrBall.length;i<j;i++){arrBall[i] = new Ball(10,Math.random() * 0xffffff);addChild(arrBall[i]);}firstBall = arrBall[0];firstBall.x = Math.random() * stage.stageWidth;firstBall.y = Math.random() * stage.stageHeight;targetX = stage.stageWidth/2;targetY = stage.stageHeight/2;stage.addEventListener(MouseEvent.MOUSE_DOWN,MouseDownHandler);addEventListener(Event.ENTER_FRAME,EnterFrameHandler);}private function MouseDownHandler(e:MouseEvent):void{targetX = mouseX;targetY = mouseY;addEventListener(Event.ENTER_FRAME,EnterFrameHandler);}private function EnterFrameHandler(e:Event):void{firstBall.vx = (targetX - firstBall.x) * easing;firstBall.vy = (targetY - firstBall.y) * easing;firstBall.x += firstBall.vx;firstBall.y += firstBall.vy;for(var i=1,j=arrBall.length;i<j;i++){var ball:Ball = arrBall[i];ball.vx = (arrBall[i-1].x-ball.x)*easing;ball.vy = (arrBall[i-1].y-ball.y)*easing;ball.x += ball.vx;ball.y += ball.vy;}var lastBall:Ball = arrBall[arrBall.length-1];var dx = lastBall.x - targetX;var dy = lastBall.y - targetY;var dist = Math.sqrt(dx*dx + dy*dy);trace(dist);if (dist<=10){removeEventListener(Event.ENTER_FRAME,EnterFrameHandler);}}}}

如果把這個例子稍加改造,可能效果更cool:

最後:本文所提到的緩動均指越來越慢,實際上Flash/Silverlight的IDE介面提供的緩動類型更多(比如先慢慢啟動,再慢慢停止--即淡入淡出之類),對應的公式也有不少,www.robertpenner.com 大家可以到這上面找找,一定會發現不好好東西

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.