2009年01月12日 21:20

【心得】用Tweener模擬重力彈跳運動

  彈跳簡單說就是有加速度的運動方式,一種實作方式是在每次frame更新時,用加速度來重新計算速度與位置,檢查是否觸地,觸地後反向減速,直到速度為零…反覆動作,但其實彈跳的運動軌跡是有跡可循的,Tweener就有內建"easeInBounce"模式,可以用來模擬彈跳運動,只是較為制式,只能固定彈跳四下,用起來方便但不夠實用,不過只要用Tweener其它的模式,稍微換算一下,就可以達到很好的彈跳效果,而且參數皆可自訂。

easeInBounce模式:

easeInQuad+easeOutQuad模式:

  後者可以自行設定耗損的動能比,根據動能公式,E=(MV^2)/2,求得動能正比於速度平方,而在初速度為0且加速度固定的條件下,速度正比於時間,時間平方正比於距離,這樣就可以估計出從某個高度落下所需時間,也就能直接套用在Tweener上囉,寫了一堆,其實只要會用就好~

以下程式碼加上橫向的速度當參數,才不會單調地原地跳動,可帶入負值。

使用內建easeInBounce的程式碼:
import caurina.transitions.Tweener;

BounceDown(circle_mc, 5, 120, 50);

function BounceDown(target:Object, time:Number, heightY:Number, speedX:Number = 0, enerageReduceRatio:Number = 1) {
	Tweener.addTween(target, {x:target.x + speedX * time, time:time, transition:"linear"});
	Tweener.addTween(target, {y:target.y + heightY, time:time, transition:"easeOutBounce"});
}
easeInQuad+easeOutQuad模式:
import caurina.transitions.Tweener;

fallDown(circle_mc, 1, 120, 50, 0.5);

function fallDown(target:Object, time:Number, heightY:Number, speedX:Number = 0, energyReduceRatio:Number = 1) {
	Tweener.addTween(target, {x:target.x + speedX * time, time:time, transition:"linear"});
	Tweener.addTween(target, {y:target.y + heightY, time:time, transition:"easeInQuad", onComplete:goUp, onCompleteParams:[target, Math.sqrt(energyReduceRatio)*time, energyReduceRatio*heightY, speedX, energyReduceRatio]});
}

function goUp(target:Object, time:Number, heightY:Number, speedX:Number = 0, energyReduceRatio:Number = 1) {
	if (Math.abs(heightY) < 0.01) return; // 不加會堆疊溢位
	Tweener.addTween(target, {x:target.x + speedX * time, time:time, transition:"linear"});
	Tweener.addTween(target, {y:target.y - heightY, time:time, transition:"easeOutQuad", onComplete:fallDown, onCompleteParams:[target, time, heightY, speedX, energyReduceRatio]});
}

circle_mc是舞台上的某個MovieClip,當hightY<0.01時,可以加入其它程式碼,例如讓球繼續往橫向移動等等。fallDown函式的heightY參數還可以代入負值,做出類似上升泡泡在天花板的彈動效果。



  • esabear 發表於樂多回應(1)引用(0)Flash筆記編輯本文
    樂多分類:網路/3C │昨日人次:1 │累計人次:1809 │標籤:運動,心得,Tweener
    Ads by Roodo! 

    引用URL

    http://cgi.blog.roodo.com/trackback/8083031

    回應文章

    請問如果要加入rotation要怎麼寫呢?
    比如掉下來的時候邊旋轉90度。
    謝謝
    ---------------------------------------------
    版主回覆:
    可以試試這段程式碼:

    import caurina.transitions.Tweener;

    fallDown(circle_mc, 1, 120, 50, 15, 0.5);

    function fallDown(target:Object, time:Number, heightY:Number, speedX:Number = 0, speedRotation:Number=0, energyReduceRatio:Number = 1) {
    Tweener.addTween(target, {x:target.x + speedX * time, rotation:target.rotation + speedRotation * time, time:time, transition:"linear"});
    Tweener.addTween(target, {y:target.y + heightY, time:time, transition:"easeInQuad", onComplete:goUp, onCompleteParams:[target, Math.sqrt(energyReduceRatio)*time, energyReduceRatio*heightY, speedX, speedRotation, energyReduceRatio]});
    }

    function goUp(target:Object, time:Number, heightY:Number, speedX:Number = 0, speedRotation:Number=0, energyReduceRatio:Number = 1) {
    if (Math.abs(heightY) < 0.01) return; // 不加會堆疊溢位
    Tweener.addTween(target, {x:target.x + speedX * time, rotation:target.rotation + speedRotation * time, time:time, transition:"linear"});
    Tweener.addTween(target, {y:target.y - heightY, time:time, transition:"easeOutQuad", onComplete:fallDown, onCompleteParams:[target, time, heightY, speedX, speedRotation, energyReduceRatio]});
    }

    道理相同 只是額外改變rotation值
    注意circle_mc本身的中心點要置中 不然轉起來會很奇怪
    | 檢舉 | Posted by apum at 2010年02月5日 00:22