さて標準コンポーネントも一通り使ってみた事なので、次はやはりそれを活用してみたい。
てなわけで、当サイトの2大テーマのひとつであるところのゲームを作ってみる事にする。
締め切りは3月中。
Flashで比較的作りやすいと評判の「脱出ゲーム」を作ってみる事にする。
とここまで書いていたんだけど、皆さんご存知の通り今はもう夏。締め切りも何もあったものではない。
そこで(どこで?)Flashといったらアニメーション。ActionScriptでアニメーションしてみたい。
なんか、Flash8のころからアニメーション用のTweenってクラスってあったみたい。
私はFlash MX(6)から飛んでFlash CS3(9)へという流れでやっているので、ActionScript2.0がすっぽり抜けている。
そんなわけで、まずは他の言語でも使い回せる、アニメーションのド基本をやってみる。ただし、画面書き換えはTimerイベントではなくてFlashらしくenterFrameで。
ところで、ActionScript3.0ってプライベートクラスが作れるんですよね、packageの外に書けばOK。簡単。
ただ、importを別に書かなきゃいけないのは面倒。あと、頭にprivateって書く必要は無い、というか書いちゃダメ。
//!-- UTF8 package { import flash.display.MovieClip; import flash.events.Event; public class BallAnime extends MovieClip { private var b:Ball; function BallAnime() { b = new Ball(); b.x = 100; b.y = 100; addChild( b ); addEventListener( Event.ENTER_FRAME, enterFrameHandler ); } private function enterFrameHandler( e:Event ):void { b.x += 1; } } } import flash.display.Graphics; import flash.display.Sprite; class Ball extends Sprite { public function Ball() { var g:Graphics = graphics; g.beginFill( 0xff0000 ); g.drawCircle( 0, 0, 16 ); } }
横にじんわり動きます!!
Σc ' _' ) < 思った以上にしょぼかったので、勢いでごまかそうとしてるな… $ σ_σ$ < まぁ、いいんじゃない…たまには勢いで凄いって勘違いする人もいるかもよ
今この瞬間、勘違いする人がいなくなったんですが…
で、fl.transitions.Tweenですよ。
TweenのコンストラクタにアニメーションさせるDisplayObjectと、アニメーションのための関数を渡す。
で、その関数は自分でも作れるけど、motion.easingパッケージの中に色々用意してある。試しにBounce.easeOutを使ってみる。加速しつつ移動して終点のところで跳ねる、という動きだ。
//!-- UTF8 package { import flash.display.MovieClip; import fl.transitions.Tween; import fl.motion.easing.Bounce; import fl.motion.Tweenables; public class BallTween extends MovieClip { private var b:Ball; function BallTween() { b = new Ball(); b.y = 100; addChild( b ); new Tween( b, Tweenables.X, Bounce.easeOut ,100, 400,20 ); } } } import flash.display.Graphics; import flash.display.Sprite; class Ball extends Sprite { public function Ball() { var g:Graphics = graphics; g.beginFill( 0xff0000 ); g.drawCircle( 0, 0, 16 ); } }
Tweenに渡す関数(上のコードでBounce.easeOutの部分)は以下のような感じに作ればいいようだ。
private function tweenMethod( t:Number, b:Number, c:Number, d:Number ):Number { /** 渡された以下の値を元にして、返す値を決定する。 t : 現在時間(time) 0-d の間の現在地を示す値。アニメーション中は、この値しか変化しない。 b : 開始点(begin value) c : 変化量(change value) 初期値に加算される値。つまり終点は b + c となる。 d : 全体の時間(duration) */ return b + c * ( t / d ); // これが一番単純なLinearの中味( 予想 ) }
このコードでは使ってないけど、生成したtweenインスタンスのメソッドでアニメーションを止めたり巻き戻したり、イベント(fl.transitions.TweenEvent)を使ってアニメーションが終了したところで次の処理を開始したり、色々できるようだ。
さらに言うと、別に画像オブジェクトじゃなくても、どんなオブジェクトのどんなプロパティであってもトゥイーンできるようだ。
まとめると「Tweenオブジェクトは、2数値間で目標時間内でプロパティを変化させる」ということと理解して良いようだ。
用意する要素は以下の通り。
んで、開始・アップデート・停止・再開・終了などのイベントを発生させるので、それらを使った制御もできる。
さっきのスクリプトはTweenを生成したあと放りっぱなしだったけど、以下のようにちゃんとTweenのインスタンスを拾っておけば、addEventListenerできる。
private var t:Tween; ... t = new Tween( b, Tweenables.X, Bounce.easeOut ,100, 400,20 ); t.addEventListener( TweenEvent.MOTION_CHANGE, motionHandler ); t.addEventListener( TweenEvent.MOTION_FINISH, motionHandler ); t.addEventListener( TweenEvent.MOTION_LOOP, motionHandler ); t.addEventListener( TweenEvent.MOTION_RESUME, motionHandler ); t.addEventListener( TweenEvent.MOTION_START, motionHandler ); t.addEventListener( TweenEvent.MOTION_STOP, motionHandler ); } private function motionHandler( e:TweenEvent ):void { trace( "Event :", e.type ); }
わりとTweenは分かりやすいけど、複雑な事をやりたくなったら力不足な感は否めない。
そういう人は、Tweenerクラスとか使うのが良いらしい。私はまだ使った事がない。そりゃそーですわな、標準のTweenだって使うの初めてなんだから。
ちなみにTweenerは、もう時代遅れだということで開発終了しているようなんだけど、それって「枯れてる」って事だから、わりと良い事のような気がする。あとで使ってみよう。
おつぎは、fl.transitions.TransitionManager。
ダサイ映画が場面転換に多用する傾向にあるトランジションです。「スターウォーズ」は好きですけど、トランジションはダサイと思います。
あらかじめステージに"b"ってインスタンス名のムービークリップを用意して、以下のドキュメントクラスでもって実行。
//!-- UTF8 package { import flash.display.MovieClip; import flash.events.MouseEvent; import fl.transitions.*; import fl.transitions.easing.*; public class BlindsTransition extends MovieClip { public var b:MovieClip; function BlindsTransition() { stage.addEventListener( MouseEvent.CLICK, clickHandler ); } private function clickHandler( e:MouseEvent ):void { var tr:Object = { type:Blinds, direction:Transition.IN, duration:0.5, easing:None.easeNone, numStrips:20, dimension:1 }; TransitionManager.start( b, tr ); } } }
TransitionManager.start()でトランジションが実行されるんだけど、戻り値のfl.transitions.Transitionを見ても、終了を知らせるイベントとかないよーな…。どないせいっちゅん。
と、良く読むと"transitionInDone" イベントまたは "transitionOutDone"イベントで、終了が監視できるとある。
あーうー、定数の定義もなけりゃ、そもそもイベントとしてASDocに公開してないとかどういう了見なんだろう…。次回のバージョンアップでちゃんと定義される事を期待したい。
とりあえず、リテラルで直書きしてイベントを受けてみる。
Transition.INの場合の"transitionInDone"と、Transition.OUTの場合の"transitionOutDone"と、終了イベントが違うんだけど、…分ける意味がよく分からない。それより開始イベントとアップデートイベントはないのか?
private var t:Transition; ... t = TransitionManager.start( b, tr ); t.addEventListener( "transitionInDone", motionHandler ); t.addEventListener( "transitionOutDone", motionHandler ); } private function motionHandler( e:Event ):void { trace( "Event :", e.type ); }
あと、このトランジションってMovieClipじゃないと動かない。Spriteはもちろん単純にMovieClipを継承したクラスでも動かなかった。
なんだか"__TransitionManager"とかゆープロパティが必要らしい…どゆこと?
ともかく、Transitionは作りかけ感あふるるクラスである事は確か。
ところで、イージングの関数を提供するパッケージには、fl.motion.easingと、fl.transitions.easingが存在しているんだけど、実のところほぼ中味は一緒のようだ。
同じ名前のクラスを入れ替えても動く。作ってるクラスがmotionパッケージ使っているか、transitionsパッケージ使っているかだけで使い分けてよさげ。
あと、アニメーションのためのクラスというとfl.motion.Motionがあるんだけど、これはけっこう大掛かりなクラスのようなので、今回はスルー。
次回への課題とする。
それはそうと、アニメーション用のクラスってFlex用はFlex用で別にあるんだよねー。マジめんどくさい。なんでこんなおかしな事になっているのか。
Flash CS3とかのFlash IDE系と、Flash Builder・Flex SDKのFlex系で、もはや別言語の様相。
Flex全然やってないし、Flash(ActionScript3.0)リファレンス概要からは、Flexの項目なくしちゃおうかなぁ。メンテしてないし。
今日はここまで。
2011-07-09