[AS3]イージングと時間設定をつける < 俺俺TweenエンジンOreOreTweenを作ってみよう2

2010/07/2

とうきょうとしんは、ぱられるぱられるぱられるぱられるワ~ルド♪
きんくまです。相対性理論、最近まで全然知らなかったんですけど、結構ゆるい感じがいいですね。

さて、俺俺Tweenです。
今回つくったもの。なんかTweenエンジンっぽくなってきました。
時間設定(duration)とイージング設定(easing)をつけてみました。

イージングってなによ

前回つくったものは、始点と終点を等分割して、各地点を計算しました。
今回は点をかたよらせることによって、最初ゆっくり、あとで速くみたいに動きに変化をつけてみましょう。

tween2_fig1

さて、始点と終点から、どうやってかたよった点を取得するかですが、
ロバート パナーさんのイージングの式を利用させていただきます。

>> Robert Penner’s Easing Equations

この式はTweenerをはじめとした各種Tweenライブラリでも使用されています。
例えばeaseInQuadという式であれば、

		/**
		 * Easing equation function for a quadratic (t^2) easing in: accelerating from zero velocity.
		 *
		 * @param t		Current time (in frames or seconds).  値を取得したい時間(イージングを開始してからの時間)
		 * @param b		Starting value. 開始時点の値
		 * @param c		Change needed in value. 変化値(開始が10で終了が100なら90)
		 * @param d		Expected easing duration (in frames or seconds). イージング時間
		 * @return		The correct value.
		 */
		public static function easeInQuad (t:Number, b:Number, c:Number, d:Number, p_params:Object = null):Number {
			return c*(t/=d)*t + b;
		}

こんな感じの式であらわすことができます。
このとき、引数b,c,dは1回のTweenでは固定なので、時間tを変化させて、そのときの値を取得していきます。
そうすると、偏った各地点のイージング値を取得することができます。
あとは、それを決まったタイミングで(EnterframeかTimerで)表示オブジェクトに適用してあげればいいです。

時間指定

Tween時間を変更できるようにしましょう。
今回のTweenエンジンはTimerベースではなく、Enterframeベースのものとします。
全部の分割数はフレームレート30のとき、

var segmentNum:int = Math.floor(frameRate * duration);

であらわすことができます。
これとさきほどのイージングの式を使えば、今回のデモが完成します。

今回のソースです。

■Main

package 
{
	import com.bit101.components.HSlider;
	import com.bit101.components.Label;
	import com.bit101.components.List;
	import com.bit101.components.PushButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	[SWF(width="450",height="450",backgroundColor="0x000000",frameRate="30")]
	public class Main extends Sprite 
	{
		public var ball:Circle;
		public var startBtn:PushButton;
		public var easingList:List;
		public var durationSlider:HSlider;
		
		public const START_POS:Point = new Point(50, 150);//開始地点
		public const END_POS:Point = new Point(400, 150);//終了地点
		
		public var tweenValues:Array;
		public var tweenCount:int;
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			ball = new Circle(20, 0x1ECAE8);
			addChild(ball);
			ball.setPosition(START_POS.x, START_POS.y);
			
			startBtn = new PushButton(this, 250, 380, "start", startBtnClickHD);
			
			var label:Label = new Label(this, 100, 280, "EASING");
			label.textField.textColor = 0xffffff;
			var easingListItem:Array = ["easeNone", "easeInQuad", "easeOutQuad", "easeInOutQuad"];
			easingList = new List(this, 100, 300, easingListItem);
			easingList.selectedIndex = 1;
			
			label = new Label(this, 250, 280, "DULATION");
			label.textField.textColor = 0xffffff;
			
			durationSlider = new HSlider(this, 250, 300, null);
			durationSlider.maximum = 2.0;
			durationSlider.minimum = 0.1;
			durationSlider.tick = 0.1;
			durationSlider.value = 1.1;
		}
		
		private function startBtnClickHD(e:MouseEvent):void
		{
			var duration:Number = durationSlider.value;
			var easing:String = String(easingList.selectedItem);
			
			tweenValues = OreOreTween.getTweenValues(END_POS.x, START_POS.x, duration, easing);
			trace(tweenValues); //各地点
			
			//tweenスタート
			startBtn.visible = false;
			tweenCount = 0;
			addEventListener(Event.ENTER_FRAME, updateTween);
		}
		
		private function updateTween(e:Event):void 
		{
			
			//tween終了
			if (tweenCount == tweenValues.length) 
			{
				removeEventListener(Event.ENTER_FRAME, updateTween);
				startBtn.visible = true;
			//tween値を適用
			}else {
				var value:Number = tweenValues[tweenCount];
				ball.x = value;
				tweenCount++;
			}
		}
		
	}
	
}

■OreOreTween

package  
{
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class OreOreTween
	{
		public static const EASE_NONE:String = "easeNone";
		public static const EASE_IN_QUAD:String = "easeInQuad";
		public static const EASE_OUT_QUAD:String = "easeOutQuad";
		public static const EASE_IN_OUT_QUAD:String = "easeInOutQuad";
		
		public static function getTweenValues(to:Number, from:Number, duration:Number = 1.0, easing:String = EASE_NONE):Array
		{
			var frameRate:int = 30;//フレームレート
			
			var values:Array = [];
			var segmentNum:int = Math.floor(frameRate * duration); //分割数
			
			var i:int;
			var t:Number;
			var dt:Number = 1 / segmentNum;
			var time:Number;
			var value:Number;
			for (i = 0; i <= segmentNum; i++) {
				t = dt * i; //tは0以上1以下の範囲で動く
				time = t * duration; //開始からの時刻(秒)
				
				//easingによる分岐
				switch(easing) {
					case EASE_NONE:
						value = OreOreTweenEquations.easeNone(time, from, to - from, duration);
					break;
					case EASE_IN_QUAD:
						value = OreOreTweenEquations.easeInQuad(time, from, to - from, duration);
					break;
					case EASE_OUT_QUAD:
						value = OreOreTweenEquations.easeOutQuad(time, from, to - from, duration);
					break;
					case EASE_IN_OUT_QUAD:
						value = OreOreTweenEquations.easeInOutQuad(time, from, to - from, duration);
					break;
				}
				values.push(value); 
			}
			return values;
		}
		

	}
}

■OreOreTweenEquations
今回はTweenerからソースをもってきているので、Tweenerのライセンスもつけています。

/*
Licensed under the MIT License

Copyright (c) 2006-2008 Zeh Fernando, Nate Chatellier, Arthur Debert and Francis
Turmel

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

http://code.google.com/p/tweener/
http://code.google.com/p/tweener/wiki/License

-------------------------------------------------------------------------------------

Disclaimer for Robert Penner's Easing Equations license:

TERMS OF USE - EASING EQUATIONS

Open source under the BSD License.

Copyright © 2001 Robert Penner
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package  
{
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class OreOreTweenEquations
	{

	// ==================================================================================================================================
	// TWEENING EQUATIONS functions -----------------------------------------------------------------------------------------------------
	// (the original equations are Robert Penner's work as mentioned on the disclaimer)
	// (the original code is from Tweener)

		/**
		 * Easing equation function for a simple linear tweening, with no easing.
		 *
		 * @param t		Current time (in frames or seconds).
		 * @param b		Starting value.
		 * @param c		Change needed in value.
		 * @param d		Expected easing duration (in frames or seconds).
		 * @return		The correct value.
		 */
		public static function easeNone (t:Number, b:Number, c:Number, d:Number, p_params:Object = null):Number {
			return c*t/d + b;
		}
		
		/**
		 * Easing equation function for a quadratic (t^2) easing in: accelerating from zero velocity.
		 *
		 * @param t		Current time (in frames or seconds).
		 * @param b		Starting value.
		 * @param c		Change needed in value.
		 * @param d		Expected easing duration (in frames or seconds).
		 * @return		The correct value.
		 */
		public static function easeInQuad (t:Number, b:Number, c:Number, d:Number, p_params:Object = null):Number {
			return c*(t/=d)*t + b;
		}
		
		/**
		 * Easing equation function for a quadratic (t^2) easing out: decelerating to zero velocity.
		 *
		 * @param t		Current time (in frames or seconds).
		 * @param b		Starting value.
		 * @param c		Change needed in value.
		 * @param d		Expected easing duration (in frames or seconds).
		 * @return		The correct value.
		 */
		public static function easeOutQuad (t:Number, b:Number, c:Number, d:Number, p_params:Object = null):Number {
			return -c *(t/=d)*(t-2) + b;
		}
		
		/**
		 * Easing equation function for a quadratic (t^2) easing in/out: acceleration until halfway, then deceleration.
		 *
		 * @param t		Current time (in frames or seconds).
		 * @param b		Starting value.
		 * @param c		Change needed in value.
		 * @param d		Expected easing duration (in frames or seconds).
		 * @return		The correct value.
		 */
		public static function easeInOutQuad (t:Number, b:Number, c:Number, d:Number, p_params:Object = null):Number {
			if ((t/=d/2) < 1) return c/2*t*t + b;
			return -c/2 * ((--t)*(t-2) - 1) + b;
		}
	}

}

■Circle

package  
{
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.geom.Point;
	/**
	 * ...
	 * @author KinkumaDesign
	 */
	public class Circle extends Sprite
	{
		
		public function Circle(radius:Number = 5, color:int = 0, alpha:Number = 1) 
		{
			var g:Graphics = this.graphics;
			g.beginFill(color, alpha);
			g.drawCircle(0, 0, radius);
			g.endFill();
		}
		
		public function setPosition(posX:Number, posY:Number):void
		{
			x = posX;
			y = posY;
		}
	}

}
LINEで送る
Pocket

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

ページトップへ戻る