こんにちは。きんくまです。
前回は途中で終わっちゃたんで、とりあえず続きから。
今回作るもの
ICommand > Interface
Command > Commandのベース
TweenerCommand > Tweenerするコマンド
WaitCommand > タイマー
FunctionCommand > 関数実行
とりあえず、上のやつがあればだいたいのことはできるかと。
あと、Loader関係とかあると思うんですが、自分はこの辺はコマンドにしないで
地味に書いていくのが好きなんで、必要な人はお好みで作ってみるのもよいかと。
Interfaceの作成
Interfaceです。前回、自分なりのInterfaceの便利なところを書きました。
今回は実際の設計です。
ICommand.as
package kinkuma.command { /** * ... * @author KinkumaDesign */ public interface ICommand { function execute():void; function addEventListener(type:String, listener:Function):void; function removeEventListener(type:String, listener:Function):void; } }
3つのメソッドを定義しました。コマンドを実行するのと、イベントを登録・削除するというものです。
ICommandからイベントの登録・削除機能を消してしまって、
実際に実装するCommand自体がEventDispatcherを継承して作ってもいいかもしれません。
Command.as
package kinkuma.command { import flash.events.Event; import flash.events.EventDispatcher; /** * ... * @author KinkumaDesign */ public class Command implements ICommand { protected var _eDispatcher:EventDispatcher; public function Command() { _eDispatcher = new EventDispatcher(); } public function execute():void { dispatchCompleteEvent(); } public function addEventListener(type:String, listener:Function):void { _eDispatcher.addEventListener(type, listener); } public function removeEventListener(type:String, listener:Function):void { _eDispatcher.removeEventListener(type, listener); } protected function dispatchCompleteEvent():void { _eDispatcher.dispatchEvent(new Event(CommandEvent.COMMAND_COMPLETE)); } } }
・excuteしたら、COMMAND_COMPLETEイベントを発行する
・内部的にEventDispatcherのインスタンスを作って、外側からイベントを登録しにきたやつをそいつに渡してあげる
ということをしています。終了イベント名はfladdictさんのやつをみると、Event.COMPLETEを発行していたんですが、今回はProgressionの真似をして独自イベントを定義しました。
CommandEvent.as
package kinkuma.command { /** * ... * @author KinkumaDesign */ public class CommandEvent { public static const COMMAND_COMPLETE:String = "command_complete"; } }
独自のイベント名です。
ここからが、実際に使用するコマンドたちになります。
すべてのコマンドはCommandを継承して作っています。でも、もし自分でカスタムコマンドを作るときは、Commandを継承しなくても、ICommandを実装してあげれば、これから作るSerialCommand, ParallelCommandでも使えるようになります。
TweenerCommand.as
package kinkuma.command { import caurina.transitions.Tweener; import flash.events.Event; /** * ... * @author KinkumaDesign */ public class TweenerCommand extends Command { private var _target:Object; private var _params:Object; public function TweenerCommand(p_scopes:Object, params:Object) { _target = p_scopes; _params = params; } override public function execute():void { var self:TweenerCommand = this; _params.onComplete = function():void { self.dispatchCompleteEvent(); }; Tweener.addTween(_target, _params); } } }
基本的に、それぞれのコマンドはコンストラクタで引数を受け付けて、executeをoverrideして、それぞれの動きに書き換えてあげるというふうにしました。
あとTweenエンジンとしては開発の終わったTweenerですが、自分的にはまだまだ現役です。
この辺はお好みのTweenエンジンで書きなおすのもすぐに可能だと思います。
WaitCommand.as
package kinkuma.command { import flash.events.TimerEvent; import flash.utils.Timer; /** * ... * @author KinkumaDesign */ public class WaitCommand extends Command { private var _waitTime:Number; private var _timer:Timer; public function WaitCommand(time:Number = 0) { _waitTime = time; } override public function execute():void { _timer = new Timer(_waitTime * 1000, 1); _timer.addEventListener(TimerEvent.TIMER_COMPLETE, timerCompleteHD); _timer.start(); } private function timerCompleteHD(e:TimerEvent):void { _timer.removeEventListener(TimerEvent.TIMER_COMPLETE, timerCompleteHD); _timer.stop(); _timer = null; dispatchCompleteEvent(); } } }
タイマーをまわして、終わったら終了イベントを出すだけです。
FunctionCommand.as
package kinkuma.command { import flash.events.Event; /** * ... * @author KinkumaDesign */ public class FunctionCommand extends Command { private var _targetFunc:Function; public function FunctionCommand(targetFunction:Function) { _targetFunc = targetFunction; } override public function execute():void { _targetFunc(); dispatchCompleteEvent(); } } }
実行したいFunctionを登録して実行したら終了イベントを発行します
テストしてみる
package { import flash.display.Graphics; import flash.display.Sprite; import flash.events.Event; import kinkuma.command.CommandEvent; import kinkuma.command.FunctionCommand; import kinkuma.command.TweenerCommand; import kinkuma.command.WaitCommand; /** * ... * @author KinkumaDesign */ public class Main extends Sprite { 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); var sp:Sprite = new Sprite(); var g:Graphics = sp.graphics; g.beginFill(0xff0000, 1); g.drawCircle(0, 0, 100); g.endFill(); addChild(sp); sp.x = 200; sp.y = 200; sp.alpha = 0; var tc:TweenerCommand = new TweenerCommand(sp, { alpha:1, x:400, y:300, time:1, transition:"easeinoutquad" } ); tc.addEventListener(CommandEvent.COMMAND_COMPLETE, compHD); tc.execute(); var wc:WaitCommand = new WaitCommand(0.5); wc.addEventListener(CommandEvent.COMMAND_COMPLETE, compHD); wc.execute(); var fc:FunctionCommand = new FunctionCommand(this.compHD); fc.addEventListener(CommandEvent.COMMAND_COMPLETE, compHD); fc.execute(); } private function compHD(e:Event = null):void { trace("comp"); } } }
今回はここまでです。これらのコマンド群が力を発揮するのは次回やるSerialとParallelです。
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ