一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Flash基礎(chǔ)理論課 第八章 緩動與彈性運動Ⅰ

 kunzhu 2015-03-05

返回“Flash基礎(chǔ)理論課 - 目錄”

很難相信我們居然用了七章才把基礎(chǔ)的內(nèi)容介紹完,現(xiàn)在進(jìn)入第八章,這里是高級內(nèi)容的起點。從這里開始內(nèi)容也開始變得越來越有趣了,前面的章節(jié)都是些常用的概念與技術(shù)。從今天開始,每章只著重介紹一兩種特殊的運動。

本章將介紹緩動運動(成比例速度)與彈性運動(成比例加速度),不用擔(dān)心它們只是兩個名詞術(shù)語,這章可以快速地略讀。我會給出很多例子程序,可以使大家充分了解這項技術(shù)的強(qiáng)大。

成比例運動

緩動(ease)與彈性(spring)聯(lián)系緊密。這兩種方法都是將對象(通常指 Sprite或MovieClip)從某一點移動到目標(biāo)點。使用緩動運動(Easing),如同讓影片滑動到目標(biāo)并停止。使用彈性運動(Springing),會產(chǎn)生向前或向后的反彈,最終停止在目標(biāo)點位。兩種方法具有一些共同點:

■需要一個目標(biāo)點;

■確定到目標(biāo)點的距離;

■成比例地將影片移動到目標(biāo)點——距離越遠(yuǎn),移動速度越快。

緩動運動(easing)與彈性運動(springing)的不同之處在于移動的比例。緩動運動時,速度與距離成正比,離目標(biāo)越遠(yuǎn),物體運動速度越快。當(dāng)物體與目標(biāo)點非常非常接近時,就幾乎不動了。

彈性運動時,加速度與距離成正比。如果物體與目標(biāo)離得很遠(yuǎn),再用上加速度,會使移動速度非???。當(dāng)物體接近目標(biāo)時,加速度會減小,但依然存在!物體會飛過目標(biāo)點,隨后再由反向加速度將它拉回來。最終,用摩擦力使其靜止。

下面,我們分別看一下這兩種方法,先從緩動(easing)開始。

緩動(Easing)

首先說明緩動的種類不只有一種。在 Flash IDE 中,制作補間動畫時,我們就可以看到 “緩動輸入”(ease in)和“緩動輸出”(ease out)。下面所討論的緩動類型與運動補間的“緩動輸出”相似。在本章后面的“高級緩動”一節(jié),將會給大家一個網(wǎng)站連接,在那里可以學(xué)習(xí)制作所有緩動的效果。

簡單緩動

簡單緩動是個非?;A(chǔ)概念,就是將一個物體移到別處去。創(chuàng)建這個“運動效果”時,希望物體能在幾幀內(nèi)慢慢移動到某一點。我們可以求出兩點之間的夾角,然后設(shè)置速度,再使用三角學(xué)計算出 vx和vy,然后讓物體運動。每一幀都判斷一下物體與目標(biāo)點的距離,如果到達(dá)了目標(biāo)則停止。這種運動還需要一定條件的約束才能實現(xiàn),但如果要讓物體運動得很自然,顯然這種方法是行不通的。

問題在于物體沿著固定的速度和方向運動,到達(dá)目標(biāo)點后,立即停止。這種方法,用于表現(xiàn)物體撞墻的情景,也許比較合適。但是物體移動到目標(biāo)點的過程,就像是某個人明確地知道他的目的地,然后向著目標(biāo)有計劃地前進(jìn),起初運動的速度很快,而臨近目標(biāo)點時,速度就開始慢下來了。換句話講,它的速度向量與目標(biāo)點的距離是成比例的。

先來舉個例子。比如說我們開車回家,當(dāng)離家還有幾千米的距離時,要全速前進(jìn),當(dāng)離開馬路開進(jìn)小區(qū)時速度就要稍微慢一點兒。當(dāng)還差兩座樓時就要更慢一點兒。在進(jìn)入車庫時,速度也許只有幾邁。當(dāng)進(jìn)入停車位時速度還要更慢些,在還有幾英尺的時候,速度幾乎為零。

如果大家注意觀察就會發(fā)現(xiàn),這種行為就像關(guān)門、推抽屜一樣。開始的速度很快,然后逐漸慢下來。

在我們使用緩動使物體歸位時,運動顯得很自然。簡單的緩動運動實現(xiàn)起來也非常簡單,比求出夾角,計算 vx,vy 還要簡單。下面是緩動的實現(xiàn)策略:

1. 確定一個數(shù)字作為運動比例系數(shù),這是個小于 1的分?jǐn)?shù);

2. 確定目標(biāo)點;

3. 計算物體與目標(biāo)點的距離;

4. 用距離乘以比例系數(shù),得出速度向量;

5.將速度向量加到當(dāng)前物體坐標(biāo)上;

6. 重復(fù) 3到5 步。圖 8-1 解釋了這一過程。

500x285

圖8-1 簡單緩動

我們先來解釋一下這個過程,看看在 ActionScript. 中是怎樣實現(xiàn)的。

首先,確定一個分?jǐn)?shù)作為比例系數(shù)。我們說過,速度與距離是成比例的。也就是說速度是距離的一部分。比例系數(shù)在 0和1 之間,系數(shù)越接近 1,運動速度就會越快;系數(shù)越接近0,運動速度就會越慢。但是要小心,系數(shù)過小會使物體無法到達(dá)目標(biāo)。開始我們以 0.2 作為系數(shù),這個變量名就叫 easing。初始代碼如下:

var easing:Number = 0.2;

接下來,確定目標(biāo)。只需要一個簡單的x,y 坐標(biāo),選擇舞臺中心坐標(biāo)再合適不過了。

var targetX:Number = stage.stageWidth / 2;
var targetY:Number = stage.stageHeight / 2;

下面,確定物體到達(dá)目標(biāo)的距離。假設(shè)已經(jīng)有一個名為 ball 影片,只需要從ball的x,y 坐標(biāo)中減去目標(biāo)的x,y。

var dx:Number = targetX - ball.x;
var dy:Number = targetY - ball.y;

速度等于距離乘以比例系數(shù):

vx = dx * easing;
vy = dy * easing;

下面,大家知道該怎么做了吧:

ball.x += vx;
ball.y += vy;

最后重復(fù)步驟 3 到步驟 5,因此只需加入enterFrame. 處理函數(shù)。

讓我們再看一下這三個步驟,以便將它們最大程度地簡化:

var dx:Number = targetX - ball.x;
var dy:Number = targetY - ball.y;
vx = dx * easing;
vy = dy * easing;
ball.x += vx;
ball.y += vy;

把前面四句簡化為兩句:

vx = (targetX - ball.x) * easing;
vy = (targetY - ball.y) * easing;
ball.x += vx;
ball.y += vy;

如果大家覺得還不夠精簡,還可以進(jìn)一步縮短:

ball.x += (targetX - ball.x) * easing;
ball.y += (targetY - ball.y) * easing;

在開始學(xué)習(xí)使用緩動時,也許大家會比較喜歡用詳細(xì)的句型,讓程序看上去更加清晰。但是當(dāng)你使過幾百次后,就會更習(xí)慣用第三種寫法。下面,我們選用第二種句型,以加強(qiáng)對速度的理解。

現(xiàn)在就來看一下腳本動作,依然延用Ball 類。以下是文檔類 Easing1.as:

package {
 import flash.display.Sprite;
 import flash.events.Event;
 public class Easing1 extends Sprite {
  private var ball:Ball;
  private var easing:Number=0.2;
  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  ;
   addChild(ball);
   addEventListener(Event.ENTER_FRAME,onEnterFrame);
  }
  private function onEnterFrame(event:Event):void {
   var vx:Number=(targetX - ball.x) * easing;
   var vy:Number=(targetY - ball.y) * easing;
   ball.x+= vx;
   ball.y+= vy;
  }
 }
}

試改變easing的值,觀察運動效果。

下面,大家可以讓小球變成可以拖拽的,與第七章所做的拖拽與拋落效果很像。在點擊小球時開始拖拽,同時,刪除 enterFrame. 處理函數(shù)并且用stage 偵聽 mouseUp。在 mouseUp 函數(shù)中,停止拖拽,刪除 mouseUp 方法,并重新開始 enterFrame。下面是文檔類 Easin2.as :

package {
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.events.MouseEvent;
 public class Easing2 extends Sprite {
  private var ball:Ball;
  private var easing:Number=0.2;
  private var targetX:Number=stage.stageWidth / 2;
  private var targetY:Number=stage.stageHeight / 2;
  public function Easing2() {
   init();
  }
  private function init():void {
   ball=new Ball  ;
   addChild(ball);
   ball.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
   addEventListener(Event.ENTER_FRAME,onEnterFrame);
  }
  private function onMouseDown(event:MouseEvent):void {
   ball.startDrag();
   removeEventListener(Event.ENTER_FRAME,onEnterFrame);
   stage.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
  }
  private function onMouseUp(event:MouseEvent):void {
   ball.stopDrag();
   addEventListener(Event.ENTER_FRAME,onEnterFrame);
   stage.removeEventListener(MouseEvent.MOUSE_UP,onMouseUp);
  }
  private function onEnterFrame(event:Event):void {
   var vx:Number=(targetX - ball.x) * easing;
   var vy:Number=(targetY - ball.y) * easing;
   ball.x+= vx;
   ball.y+= vy;
  }
 }
}

緩動何時停止

在物體緩動運動到目標(biāo)點時,物體最終會到達(dá)目標(biāo)點并且完成緩動效果。但是,即使不顯示該對象,緩動代碼仍在執(zhí)行中,這一來浪費了 CPU 資源。當(dāng)物體到達(dá)目標(biāo)時,應(yīng)該停止執(zhí)行代碼。判斷物體是否到達(dá)目標(biāo)的方法非常簡單,就像這樣:

if(ball.x == targetX && ball.y == targetY) {
  // code to stop the easing
}

但是這里要注意一些技巧。

我們所討論的緩動類型涉及到了著名的Xeno悖論。Xeno也是位希臘人,愛好測量實驗。Xeno將運動分解為下面幾個步驟:物體要從A 點到達(dá) B 點,它首先要移動到兩點間一半的距離。然后物體再從該點出發(fā),到達(dá)與 B 點距離一半的距離。然后再折半。每次只移動離目標(biāo)一半的距離,但永遠(yuǎn)無法準(zhǔn)確地達(dá)到目標(biāo)。

這個悖論聽起來是非常符合邏輯的。但是很明顯,我們確實將物體從一點移動到了另一點,這樣看來他的說法有些問題。到 Flash 中看看,影片在 x 軸上的位置為 0,假設(shè)要將它移動到 x 軸為 100的位置。按照悖論所說,設(shè)緩動系數(shù)為 0.5,這樣每次運動到離目標(biāo)一半的距離。過程如下:

■從0 點開始,經(jīng)過 1 幀,到達(dá) 50。

■第 2 幀,到達(dá) 75。

■剩下的距離是 25。它的一半是 12.5 ,所以新的距離就是 87.5。

■按照這種順序,位置將變化為 93.75, 96.875, 98.4375 等等。20 幀以后,將到達(dá) 99.999809265。

從理論上講位置越來越接近目標(biāo),但是永遠(yuǎn)無法準(zhǔn)確地到達(dá)目標(biāo)點。然而,在代碼中進(jìn)行試驗時,結(jié)果就發(fā)生了一些微妙的變化。歸根結(jié)底問題就在于“一次最少能移動多少個像素”,答案是 1/20。事實上,二十分之一像素有個特有的名字:twip (緹)。在 Flash 內(nèi)部計算單位都采用twip 像素,包括所有 Sprite 影片,影片剪輯和其它舞臺對象。因此,在顯示影片位置時,這個數(shù)值永遠(yuǎn)是 0.05的倍數(shù)。

下面舉個例子,一個影片要到達(dá) 100的位置,而它所到達(dá)的最接近的位置事實上是 99.5。再分隔的距離,就是加上 (100 – 99.95) /2。相當(dāng)于加上了 0.025,四十分之一像素。超出了 twip 是能夠移動的最小值,因此無法加上“半個 twip”,結(jié)果是只增加了 0 像素。如果大家不信的話,可以親自試一下(提示:將代碼放入框架類中的init 方法):

var sprite:Sprite;
sprite = new Sprite();
addChild(sprite);
sprite.x = 0;
var targ:Number = 100;
for(var i:Number = 0; i < 20; i++) {
    trace(i + ": " + sprite.x);
    sprite.x += (targ - sprite.x) * .5;
}

循環(huán)20次,將影片移動離目標(biāo)一半的距離,這是基本緩動應(yīng)用。將代碼放入for循環(huán),只是為了測試其位置,并不在于觀察物體運動。循環(huán)到第 11次時,影片已經(jīng)到達(dá)了 99.95,這已經(jīng)是它能夠到達(dá)的最遠(yuǎn)的地方了。

長話短說,影片并非無限地接近目標(biāo),但是它確實永遠(yuǎn)無法準(zhǔn)確地到達(dá)目標(biāo)點。這樣一來,緩動代碼就永遠(yuǎn)不會停止。我們要回答的問題是 “哪里才是物體最接近的目標(biāo)位置?”,這需要確定到目標(biāo)點的距離是否小于某個范圍。我發(fā)現(xiàn)在很多軟件中,如果物體與目標(biāo)點的距離相差在一個像素以內(nèi),就可以說它已經(jīng)到達(dá)了目標(biāo)點,即可停止緩動了。

在處理二維坐標(biāo)時,可以使用第三章所介紹的公式來計算點間距離:

distance = Math.sqrt(dx * dx + dy * dy)

如果只處理一維坐標(biāo)點,如只移動一個軸的位置,就需要使用距離的絕對值,因為它有可能是個負(fù)數(shù),使用Math.abs 方法。

OK,說得很多了,來寫代碼吧。這個簡單的文檔類,演示了如何關(guān)閉緩動運動(EasingOff.as):

package {
 import flash.display.Sprite;
 import flash.events.Event;
 public class EasingOff extends Sprite {
  private var ball:Ball;
  private var easing:Number = 0.2;
  private var targetX:Number = stage.stageWidth / 2;
  public function EasingOff() {
   init();
  }
  private function init():void {
   ball = new Ball();
   addChild(ball);
   ball.y = stage.stageHeight / 2;
   addEventListener(Event.ENTER_FRAME, onEnterFrame);
  }
  private function onEnterFrame(event:Event):void {
   var dx:Number = targetX - ball.x;
   if (Math.abs(dx) < 1) {
    ball.x = targetX;
    removeEventListener(Event.ENTER_FRAME, onEnterFrame);
    trace("done");
   } else {
    var vx:Number = dx * easing;
    ball.x += vx;
   }
  }
 }
}

此例中,將緩動公式分解使用,首先計算出距離,因為我們需要知道是否該停止緩動。大家應(yīng)該知道為什么要使用dx的絕對值了吧。如果小球在目標(biāo)點的右邊,dx的值總是負(fù)的,if (dx < 1)的結(jié)果永遠(yuǎn)為真,這就會使緩動停止。而使用Math.abs,就可以判斷實際距離是否小于 1。

記住,如果將拖拽與緩動相結(jié)合,要在放開小球時,將運動代碼重新啟用。

移動的目標(biāo)

上面例子中的目標(biāo)點都是單一且固定的,這些似乎還不能滿足我們的要求。事實上,F(xiàn)lash 并不關(guān)心物體是否到達(dá)目標(biāo),或目標(biāo)是否還在移動。它只會問 “我的目標(biāo)在哪里?距離有多遠(yuǎn)?速度是多少?”,每幀都如此。因此,我們可以很容易將目標(biāo)點改為鼠標(biāo)所在的位置,只需將原來 targetX和targetY的地方,改成鼠標(biāo)的坐標(biāo) (mouseX和mouseY)。以下是一個比較簡單的版本(EaseToMouse.as):

package {
 import flash.display.Sprite;
 import flash.events.Event;
 public class EaseToMouse extends Sprite {
  private var ball:Ball;
  private var easing:Number = 0.2;
  public function EaseToMouse() {
   init();
  }
  private function init():void {
   ball = new Ball();
   addChild(ball);
   addEventListener(Event.ENTER_FRAME, onEnterFrame);
  }
  private function onEnterFrame(event:Event):void {
   var vx:Number = (mouseX - ball.x) * easing;
   var vy:Number = (mouseY - ball.y) * easing;
   ball.x += vx;
   ball.y += vy;
  }
 }
}

移動鼠標(biāo)觀察小球跟隨情況,是不是距離越遠(yuǎn)速度越快。

試想還有沒有其它可移動的目標(biāo)。當(dāng)然還可以是一個影片向著另一個影片緩動。在早先的Flash 時代,鼠標(biāo)追蹤者(mouse trailers)——即一串影片跟蹤者鼠標(biāo)的效果——曾經(jīng)風(fēng)靡一時。緩動就是制作這種效果的方法之一。第一個影片緩動到鼠標(biāo)上,第二個影片緩動到第一個影片上,第三個再緩動到第二個上,依此類推。大家不妨一試。

緩動不僅限于運動

本書中,有很多簡單的例子程序。在這些例子中,我們主要是計算影片所用變量的值。通常,使用x,y 屬性控制物體的位置。不過別忘了 Sprite 影片,影片剪輯以及各種顯示對象還有很多其它可以操作的屬性,而且基本都是用數(shù)字表示的。所以在讀例子程序時,也應(yīng)該試用其它屬性代替這個例子中的屬性。下面給大家一些啟發(fā)。

透明度

將緩動用在 alpha 屬性上。開始設(shè)置為 0 ,目標(biāo)設(shè)置為 1 :

ball.alpha = 0;
var targetAlpha:Number = 1;

在 enterFrame. 函數(shù)中,使用緩動可以實現(xiàn)影片淡入效果:

ball.alpha += (targetAlpha - ball.alpha) * easing;

若將 0和1 顛倒過來就可以實現(xiàn)影片的淡出效果。

旋轉(zhuǎn)

設(shè)置一個 rotation 屬性和一個目標(biāo) rotation。當(dāng)然,還需要一個能夠表現(xiàn)旋轉(zhuǎn)對象,比如一個箭頭(arrow):

arrow.rotation = 90;
var targetRotation:Number = 270;
arrow.rotation += (targetRotation - arrow.rotation) * easing;

顏色

如果大家想挑戰(zhàn)一下,可以在 24 位色彩中使用緩動。設(shè)置好 red,green,blue的初始值,使用緩動單獨表現(xiàn)每一色彩元素的值,然后將它們再組合成 24 位色彩值。例如,我們可以從red 緩動到 blue。初始顏色如下:

red = 255;
green = 0;
blue = 0;
redTarget = 0;
greenTarget = 0;
blueTarget = 255;

在 enterFrame. 處理函數(shù)中的每一幀執(zhí)行緩動。這里只表現(xiàn)一個 red 值:

red += (redTarget - red) * easing;

再將這三個數(shù)值組合為一個數(shù)(如第四章介紹的):

col = red << 16 | green << 8 | blue;

最后可以在 ColorTransform. (見第四章),線條顏色或填充色中使用該顏色值。

高級緩動

現(xiàn)在我們已經(jīng)看到簡單的緩動效果是如何實現(xiàn)的了,大家也許正在考慮如何使用更復(fù)雜的緩動公式制作一些效果。例如,在開始時比較緩慢,然后漸漸開始加速,最后在接近目標(biāo)時再將速度慢下來?;蛘呦M谝欢螘r間或若干幀內(nèi)完成緩動效果。

Robert Penner 以收集、編制和實現(xiàn)緩動公式而出名。我們可以在 www.robertpenner.com 中找到他的緩動公式。在他寫這些內(nèi)容時 AS 3 版本還沒有出現(xiàn),但是用我們前面幾章所學(xué)知識,將它們轉(zhuǎn)化為 AS 3 版本的也是件非常容易的事。

OK,下面進(jìn)入Flash 中我最喜歡的一個主題:彈性運動(Springing)。

聲明:該文章系網(wǎng)友上傳分享,此內(nèi)容僅代表網(wǎng)友個人經(jīng)驗或觀點,不代表本網(wǎng)站立場和觀點;若未進(jìn)行原創(chuàng)聲明,則表明該文章系轉(zhuǎn)載自互聯(lián)網(wǎng);若該文章內(nèi)容涉嫌侵權(quán),請及時向上學(xué)吧網(wǎng)站投訴>>

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    久一视频这里只有精品| 久久精品国产亚洲熟女| 丰满人妻熟妇乱又伦精另类视频| 六月丁香六月综合缴情| 少妇熟女精品一区二区三区| 色一情一伦一区二区三| 大香蕉网国产在线观看av| 国产成人精品资源在线观看| 亚洲最新的黄色录像在线| 国产又色又粗又黄又爽| 色婷婷人妻av毛片一区二区三区| 日韩性生活视频免费在线观看| 日本欧美在线一区二区三区| 少妇视频一区二区三区| 国产亚洲二区精品美女久久| 日本国产欧美精品视频| 国产精品午夜一区二区三区| 黄色三级日本在线观看| 好吊日在线观看免费视频| 免费久久一级欧美特大黄孕妇| 免费精品一区二区三区| 日韩一区二区三区高清在| 俄罗斯胖女人性生活视频| 美女露小粉嫩91精品久久久| 美女黄色三级深夜福利| 欧美一区日韩一区日韩一区| 国产成人亚洲欧美二区综| 亚洲国产精品国自产拍社区| 欧美同性视频免费观看| 国产女高清在线看免费观看| 国产三级不卡在线观看视频| 久久精品国产熟女精品| 欧美日韩国产综合在线| 国产成人精品国内自产拍| 国产精品一区二区不卡中文 | 国产午夜精品福利免费不| 加勒比系列一区二区在线观看| 免费在线播放不卡视频 | 韩国日本欧美国产三级| 青青操日老女人的穴穴| 亚洲欧美日本国产有色|