Progressionフレームワークを使ってみようとする。
つまづきメモ。
シーンとキャストがある
- シーン …… 状態。URLと対応。遷移でイベント発生。
- キャスト …… 表示するもの。
シーンについては、なかなかイメージを掴むのが難しいと思いますが、
"見た目に直接関係しないコンテンツの構成単位"という説明が近いのかなという気がします。
もっと割り切ってしまうと、どこで URL を発行するか?というだけですね。1 MovieClip = 1 Scene のようにしてしまうのが一番分かりやすいとは思うのですが、
キャンペーン系サイトのような例外的な画面構成が主体となっているサイトでも破綻なく制作できるように、
今回はこのような回りくどい仕様としました。キャストについてはシーンのイベントフローの流れの中で、都合よく処理できる機能を備えた DisplayObject という感じです。
http://flabaka.com/blog/?p=97
ですので、ただ単純に画面に表示したいだけであれば、使用せずとも開発することができると思います。
URLの割り当て
- URLはシーンに割り当てられる。
- 各シーンはシーン名を持っている。(例: index, showcase)
- シーンはツリー構造を成す。→URL (#/index/showcase)
- クラス: SceneObject
ルートのシーン
- Progression#rootがルートシーンオブジェクト。
- Progressionインスタンス作成時にルートシーンのクラスを指定できる。
_prog = new Progression( "(ルートシーン名)", stage );
new Progression( "index", stage ); ならルートシーンのパスは/indexになる。このindexのところを切り替えるにはどうしたらいいんだろう。
↑こういうふうにしたい。/index/showcase だとindexが余分だ。
ProgressionにuseLongPathというプロパティがあった。
ブラウザ同期時に発行されるアドレスに root シーン名を含むかどうかを取得または設定します。
http://progression.libspark.org/htdocs/asdoc/2.0.x/jp/progression/Progression.html#useLongPath
すばらしー。こっちがデフォルトでいいんじゃないのかなあ。パスの一階層目に"/index"以外出てこないんだったら書く意味ない。
見た目
サンプルだと各シーンに対応する*Pageクラス(CastSpriteのサブクラス)が作られていた。同名のムービークリップの「リンケージ...」でクラス名(*Page)を設定する。
ブラウザで実行すると背景が白くなってしまう
背景が白くなってしまう。別に何も後ろに敷いてないんだけど。なんでだ。うーん。。うまくいかないなー……。むーむー。
サンプルだと背景色が設定できてるけど、自分のムービーと違いが無いように見える。
(数時間悩む……)
preloader.flaを開いて、背景色を変えればよかった。フレームワークが準備してくれた環境を把握できてないと、つらい。
ブラウザ実行時に意図したシーンに移動してくれない
/index/subに行こうとすると、一度/index/subに行った後、/indexに戻ってしまう。
たぶんURLをシーンに反映するタイミングが影響してるんだと思う。けどどうやって直せばいいかわからない。
はじめから#/index/subにリンクすればいいんだろうけど、、そんなのは嫌だ。XMLやJSONでパスが決まるような場合は、静的にリンクすることがそもそも不可能だ。
もう一度冷静に考える。
やりたいことは単純なはず。/indexから/index/subへのリダイレクトだ。
到着したシーンが/indexだと確定した時に、/index/subに移動すればいい。
まずIndex.asの_onInit()で
prog.goto(prog.firstSceneId);
としている。これはフラグメントの値を反映して、指定がなければ/indexに移動する。
加えてルートシーンのクラスIndexSceneで以下のようなことをすると、それっぽい動作になる。
protected override function _onInit():void { addCommand( new Goto(new SceneId("/index/sub")) ); }
ただ、これはフラグメント無しでアクセスすると、
/index → /index/sub → /index → /index/sub
というふうに2回同じ移動を繰り返してしまう。なんで???
commandでなければならない理由もよくわかっていない。commandじゃなくすると移動しなくなった。
Index.asの方を変えてみる。
if (prog.firstSceneId.toString() == "/index") { prog.goto("/index/sub"); } else { prog.goto(prog.firstSceneId); }
駄目だった。/index → /index/sub → /indexと移動する。
仕方ないのでソースを見始める。SyncManager.asの_changeにトレース文を入れてみる。
trace("XXX change XXX : " + value + " --- " + _sceneManager.destinedSceneId.toString()); trace(e);
更にブレークポイントを設定してリモートデバッグ。やっぱり後から/indexに戻るのは、SWFAddressで外から呼ばれている感じがする。スタックトレースが
Function/http://adobe.com/AS3/2006/builtin::apply
から始まってた。あとvalueが空文字列だった。これはフラグメントが空なのに対応してるのではと予想。
リダイレクトのタイミングを遅らせるといいのかもしれない。
外から来るイベントをやり過ごしてから、移動する。
SyncManagerは現在地と目的地が一緒なら何もしないようなので、やり過ごしても害は無いはず。
Init.as
prog.goto(prog.firstSceneId);
InitScene.as
// ルートシーンに到着して0.5秒後に移動する。 protected override function _onInit():void { addCommand(new Goto(new SceneId("/index/sub"), 500)); }
これで期待したとおりに動作するようになった。
IndexSceneで確実に時間がかかる処理、何かアニメーションを見せてから
リダイレクトすれば、とりあえずうまくいきそうな感じがする。
ここまで1.5日くらい。
いろいろ慣れてないのもあるけど(Flashのデバッガ初めて使った。デバッグ用のFlashPlayerも初めて入れた。)、結構むずかしいなー。