Progressionをやる その3 – カスタムコマンド

Filed under AS3, Progression



絶賛Progressionいじくりまわし中です。

今回は、カスタムコマンドってのをやってみました。

ProgressionにはDoTweenerやWaitなど便利なコマンドクラスが沢山存在します。

で、そんな便利なコマンドクラスを自分で作るのがカスタムコマンドです。

Commandクラスを継承すれば、割と簡単に作れるようです。

とりあえずですが、「実行すると対象をフェードアウトさせるコマンド」ってのを作ってみました。

こんな感じです。

緑の円をクリックすると、円がフェードアウトします。

使い方としては、

// コマンドの作成
var cmd:MyCommand = new MyCommand(circle);

// コマンドの実行
cmd.execute();

みたいにやればフェードアウト開始。

とりあえず練習ってことで。

カスタムコマンドは割と簡単に作れるみたいですね。

うまく作ればBetweenAS3Tweensyを使うコマンドも作れそう。

以下、ソースです。

カスタムコマンド。

package
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import jp.progression.commands.Command;
	import jp.progression.commands.CommandInterruptType;
	import jp.progression.events.ExecuteEvent;
	import jp.progression.executors.ExecutorObjectState;

	public class MyCommand extends Command
	{
		private var _target:Object;
		private var _alpha:Number;
		private var _blur:Number;
		private var _evt:Shape;

		// コンストラクタ
		public function MyCommand( target:Object, initObject:Object = null):void
		{
			super(_execute, _interrupt, initObject);

			_target = target;
			_alpha = target.alpha;
			_blur = 0;
			_evt = new Shape;
		}

		// 処理を開始する関数
		private function _execute():void
		{
			_evt.addEventListener(Event.ENTER_FRAME, onFrame);
		}

		// 処理を行う関数
		private function onFrame(e:Event):void
		{
			// 更新
			_alpha -= 0.01;
			_blur +=1;
			_target.alpha = _alpha;
			_target.filters = [new BlurFilter(_blur, _blur, 1)];

			// 実行中を示すイベント(ExecuteEvent.EXECUTE_UPDATE)を送出する
			dispatchEvent( new ExecuteEvent( ExecuteEvent.EXECUTE_UPDATE, false, false, this  ) );

			// オブジェクトが消えたら処理を終了
			if (_alpha <= 0)
			{
				_evt.removeEventListener(Event.ENTER_FRAME, onFrame);
				_target.parent.removeChild(_target);

				// コマンドの終了を通知
				executeComplete();
			}
		}

		// コマンドの中断処理を行う関数 (今回は処理を止めるだけ)
		private function _interrupt():void
		{
			// 実行中 or 遅延中の場合は処理を中断
			if (state == ExecutorObjectState.DELAYING || state == ExecutorObjectState.EXECUTING)
			{
				// 処理の停止
				_evt.removeEventListener(Event.ENTER_FRAME, onFrame);

				// 中断時の処理方法の分岐。interruptTypeの値によって処理が異なる。
				// 今回は何もしてません。
				switch(interruptType)
				{
					case CommandInterruptType.ABORT:
						break;
					case CommandInterruptType.RESTORE:
						break;
					case CommandInterruptType.SKIP:
						break;
				}
			}
		}

		// 保持してるデータを開放する関数
		override public function dispose():void
		{
			super.dispose();

			_evt.removeEventListener(Event.ENTER_FRAME, onFrame);
			_evt = null;
			_target = null;
		}

		// コピーを返す関数
		override public function clone():Command
		{
			return new MyCommand(_target, this);
		}
	}
}

実行側。

package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.events.MouseEvent;
	import jp.progression.events.ExecuteEvent;

	public class Main extends Sprite
	{
		public function Main():void
		{
			// stageの設定
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			stage.quality = StageQuality.HIGH;
			stage.frameRate = 40;

			// 円を描いたSpriteを作成
			var circle:Sprite = addChild(new Sprite()) as Sprite;
			circle.graphics.beginFill(0x00ff00, 1);
			circle.graphics.drawCircle(0, 0, 50);
			circle.graphics.endFill();
			circle.x = circle.y = 300;
			circle.addEventListener(MouseEvent.CLICK, onClick);
		}

		private function onClick(e:MouseEvent):void
		{
			(e.target as Sprite).removeEventListener(MouseEvent.CLICK, onClick);

			// 自作コマンド (ブラーをかけながら消えていく)
			var cmd:MyCommand = new MyCommand(e.target);

			cmd.addEventListener(ExecuteEvent.EXECUTE_UPDATE, function():void{
				trace("update");
			});

			cmd.addEventListener(ExecuteEvent.EXECUTE_COMPLETE, function():void{
				trace("complete");
			});

			cmd.execute();
		}
	}
}

Post a Comment

Your email is never published nor shared.