Progression のパワーを最大限発揮したい方向けの制作スタイルです。
このスタイルガイドは Progression 3.0.7 をベースとして執筆されています。他のバージョンをご使用の場合には、以下の点にご注意ください。
また、ガイドを円滑に進めるために、必要となるグラフィックデータが予め含まれたプロジェクトデータを使用する前提で解説していきます。以下のデータをダウンロードしてご使用ください。
ダウンロードしたプロジェクトデータ内の ClassStyle.flp を開いてください。Adobe Flash CS3 が起動してプロジェクトパネルが開かれた状態になるので、プロジェクトに登録されている index.fla を開いてみましょう。
Index クラスはデフォルト状態で CastDocument クラスを継承しています。CastDocument クラスは、ドキュメントクラスとして必要となる様々な機能が追加された MovieClip クラスのサブクラスです。このクラスを使用する際には、読み込み状態などを事前に確認が必要となる処理を無視してコーディングが開始可能な DocumentEvent.INIT イベントが設定されています。デフォルトでは前述のイベントを _onInit() というオーバーライド・イベントハンドラメソッドで受け取るように設定されています。
まずは 54 行目にある Progression を使用する際にもっとも重要な Progression インスタンスの作成コードを確認します。第一引数にはインスタンスを識別するためのユニークな識別子を、第二引数には関連付けたい stage インスタンスの参照を、第三引数にはルートシーン(詳しくは後述します。)として使用したいクラスの参照をそれぞれ設定することになります。
57 行目にはブラウザ同期を有効化するための sync プロパティの設定がされています。今回はブラウザ同期を使用したサンプルを作成しますので、設定値を true に変更してください。
最後に 60 行目の goto() メソッドでシーンの移動を行っています。シーン移動について詳しくは後述しますが、特に変更の理由がなければこのままの状態にしておいてください。
以上が Progression を使用する際に必要となるもっとも基本的なコードです。Progression クラスには、他にも様々な機能が用意されています。詳しい情報は API リファレンスをご確認ください。
いよいよコンテンツ作りを開始します。まずはコンテンツの骨格から作っていきましょう。
Progression には、Web サイトをカンタンに作成するための「シーン機能」が用意されています。これは HTML におけるページに相当する要素で、HTML サイトでページを順々と巡っていくのと同じように、Progression ではシーンを巡回しながらコンテンツを閲覧させることになります。
クラススタイルでシーンを扱うには、SceneObject クラスを使用します。SceneObject クラスをそのまま new して使用することもできますが、今回は SceneObject クラスのサブクラスを作成して、その中に各種設定を行うことにしましょう。サブクラスを作成するにはプロジェクト内の templates フォルダにある MySceneObject. as というテンプレートファイルを使用するのが便利です。MySceneObject.as を src/classes/myproject フォルダ内にコピーして、FeatureScene.as と ContactScene.as という 2 つのファイルを作成してください。
これでシーン構造を作成するための準備は完了しました。さっそくシーン構造を作成するためのコードを記述していきましょう。
まずはルートシーンから編集します。前項で Progression インスタンスを作成する際に第三引数に IndexScene と設定していましたが、このクラスがルートシーンの元となるクラスになります。
IndexScene.as を開くとコンストラクタといくつかのオーバーライド・イベントハンドラメソッドがデフォルトで設定されています。まずはシーン構造を作成していくので、コンストラクタに以下のようなコードを追記してください。
public function IndexScene() {
// FeatureScene を作成します。
var feature:FeatureScene = new FeatureScene();
feature.name = "feature";
addScene( feature );
// ContactScene を作成します。
var contact:ContactScene = new ContactScene();
contact.name = "contact";
addScene( contact );
}
以上で 3 つのシーンからなる二階層のシーン構造が作成できました。見て分かるとおり、SceneObject クラスはメソッド名などに多少の違いがありますが、ActionScript 3.0 で登場した DisplayObject クラスで構成される表示リストと同じ方法で扱うことが出来るようになっています。そのため今回は二階層のシーン構造ですが、子シーンに子シーンを追加することで孫シーンを作成することも可能です。
前項でシーン構造が作成できました。しかし、シーン構造はあくまで“器”だけ用意した状態なので、実際には何も処理されることはありません。それぞれのシーンで必要となる処理は、シーンの移動状態に応じて発生するイベントに対して設定する必要があります。もっともシンプルな例としては、特定のシーンで表示したいグラフィックがある場合、そのシーンに「到着した際に表示」させ、そのシーンから「出発した際に削除」することになります。
シーン移動時に SceneObject インスタンスで発生する代表的なイベントは以下の通りです。
では、実際にイベントに対して処理を設定していきましょう。今回は「それぞれのシーンで対応する一枚絵を表示する」処理を作成することにします。まずは IndexScene クラスに対して以下のようなコードを追記してください。
public var page:IndexPage;
public function IndexScene() {
// FeatureScene を作成します。
var feature:FeatureScene = new FeatureScene();
feature.name = "feature";
addScene( feature );
// ContactScene を作成します。
var contact:ContactScene = new ContactScene();
contact.name = "contact";
addScene( contact );
// IndexPage を作成します。
// ※あらかじめライブラリにシンボルとして登録済みです。
page = new IndexPage();
}
protected override function _onInit():void {
// 画面に表示します。
progression.container.addChild( page );
}
protected override function _onGoto():void {
// 画面から削除します。
progression.container.removeChild( page );
}
上記のコードでは画面に表示する際に SceneObject インスタンスの progression プロパティを経由して、Progression インスタンスの container プロパティを呼び出しています。これは DisplayObject クラスのサブクラスではない SceneObject クラスから表示リストにアクセスしやすくするために用意された機能です。
同じ要領でそれぞれ FeatureScene クラスと ContactScene クラスにも追記していきましょう※1。
これでイベントの設定は完了しました。ただし、シーン移動処理が設定されていないので、まだプレビューでの確認はできません。ここではコンパイルエラーのチェックだけに留めておき、実際の動作の確認は次項以降で行ってください。
前項までの内容で基本的な枠組みを作成するのに最低限必要な機能は一通り揃いました。しかし、せっかく Flash を使用するのですから、アニメーションや外部ファイルの読み込み処理なども扱いたいのではありませんか?本項では、そのような時間のかかる処理(以下、非同期処理)の作り方をご説明します。
Progression では、シーンの流れに沿って非同期処理を行うのに最適な機能としてコマンドが用意されています。コマンドとは、よく使う機能をひとつのクラスとしてまとめて、インターフェイスを統一させることによって、より扱いやすくするためのデザインパターン※1の一種です。実際に使用する際には、難しいデザインパターンを意識せずに、ある程度決まったフォーマットに沿って使用するものと理解して頂けば、十分に活用できる機能となっています。
今回は非同期処理としては視覚的にもっとも分かりやすいアニメーション処理を作成することにしましょう。アニメーション処理に使用できるコマンドはいくつか存在しますが、その中でもっとも代表的なコマンドが DoTweener クラスです。これは名前からも分かるとおり、ActionScript 3.0 の世界では一般的となっているトゥイーンライブラリである Tweener を使用するためのコマンドです。
まずはコマンドのフォーマットをより理解しやすくするために通常の Tweener のフォーマットを確認してみましょう。
Tweener.addTween( target, { x:100, time:1 } );
次に同じ処理をコマンドのフォーマットで表現してみます。
var com:DoTweener = new DoTweener( target, { x:100, time:1 } );
com.execute();
通常のフォーマットとの最大の違いは
この 2 点になります。
では、基本的なコマンドのフォーマットが分かったところで、実際にシーン移動でコマンド処理を使ってみましょう。
まずは画面の表示処理を設定します。表示処理をするためには「目的のシーンに到着」した際に処理を行えばよいので、SceneEvent.INIT イベントを使用することになります。IndexScene クラスを開き、以下のように追記してください。
protected override function _onInit():void {
// ページを画面に表示します。
progression.container.addChild( page );
// ページを透明にします。
page.alpha = 0;
// 実行したいコマンドを登録します。
addCommand(
// ページを不透明にします。
new DoTweener( page, { alpha:1, time:1 } )
);
}
このようにイベント中に処理させるためには、SceneObject インスタンスの addCommand() メソッドにコマンドを登録していくことになります。コードを見て分かるように addCommand() 経由で登録されたコマンドは、イベントの流れに応じて自動的に実行されるので、execute() メソッドを実行する必要はありません。
次に画面の消去処理を行います。画面を消去するためには「現在のシーンから出発」した際に処理を行えばよいので、SceneEvent.GOTO イベントを使用することになります。同じように IndexScene クラスに以下のように追記してください。
protected override function _onGoto():void {
// 実行したいコマンドを登録します。
addCommand(
// ページを透明にします。
new DoTweener( page, { alpha:0, time:1 } )
);
// ページを画面から削除します。
progression.container.removeChild( page );
}
追記できたら FLA ファイルをプレビューして、動作を確認してみましょう。正しく設定できていれば、ページにアルファ効果が適用されて表示されるようになります。
では、消去アニメーションはどうでしょうか?意図した動作としては
というものかと思いますが、実際にはアニメーション処理される前に画面から消去されてしまいます。これは addCommand() メソッドで登録したコマンドはイベント発生が完了した後にまとめて処理されるために、イベント内で通常の手続き通りに実行されている removeChild() メソッドの方が先に処理されてしまっていることが原因です。この問題を解決するためには removeChild() メソッド自体を、コマンド処理として設定してあげる必要があります。
protected override function _onGoto():void {
// 実行したいコマンドを登録します。
addCommand(
// ページを透明にします。
new DoTweener( page, { alpha:0, time:1 } ),
// ページを画面から削除します。
new RemoveChild( progression.container, page )
);
// ページを画面から削除します。
progression.container.removeChild( page );
}
このようにコマンドを , で区切って続けて登録することで、前のコマンド処理の終了を待った連続実行が可能になります。機能としてはすでに完成しましたが、フォーマットを統一しておくために addChild() メソッドの方もコマンドとして書き換えておきましょう。
protected override function _onInit():void {
// ページを画面に表示します。
progression.container.addChild( page );
// ページを透明にします。
page.alpha = 0;
// 実行したいコマンドを登録します。
addCommand(
// ページを画面に表示します。
new AddChild( progression.container, page ),
// ページを不透明にします。
new DoTweener( page, { alpha:1, time:1 } )
);
}
同じ要領でそれぞれ FeatureScene クラスと ContactScene クラスにも追記していきましょう※2。
アニメーションが作成できるようになったことで、表現の幅がとても広がりました。しかし、幅が広がったからといって大量のアニメーションを設定しようとすると、シーンイベントがコマンドだらけになってしまいます。設定したいアニメーションが表示オブジェクトに紐付いたモノであれば、その表示オブジェクト自体に設定してしまう方が設計としてもよりシンプルです。
今回は表示オブジェクト自体にイベントフローと連動させたコマンド処理が設定できるようになるキャストオブジェクトについてご説明します。
通常、表示オブジェクトを使用する際には Sprite クラスや MovieClip クラスなどを使用することになります。キャストオブジェクト機能を使用するには、それらを継承した専用のクラスを使用することになります。
では、先ほど作成した page インスタンスをキャストオブジェクトに変更して、DoTweener コマンドをキャストオブジェクト側で実行するように修正してみましょう。
今回も同様にテンプレートから作成していきます。templates フォルダ内にある MyCastSprite.as をコピーして、各シーンに対応するように IndexPage.as、FeaturePage.as、ContactPage.as の 3 つのファイルを作成してください。
用意ができたのでコマンドを委嘱していくことになりますが、そのまえにまずコマンドの移植先となるキャストオブジェクト側のイベントについて理解する必要があります。キャストオブジェクトインスタンスで発生する代表的なイベントは以下の通りです。
今回はすでにキャストオブジェクトを AddChild コマンド、RemoveChild コマンドで表示/削除するようにコーディング済みですので、キャストオブジェクト側の設定だけ行っていくことにしましょう。
まずは IndexScene クラスの _onInit() メソッドに設定してある DoTweener コマンドを IndexPage クラスの _onCastAdded() メソッドに移植します。移植の際には対象設定を this(= IndexPage インスタンス)に変更することを忘れないようにしてください。
protected override function _onCastAdded():void {
// ページを透明にします。
alpha = 0;
// 実行したいコマンドを登録します。
addCommand(
// ページを不透明にします。
new DoTweener( this, { alpha:1, time:1 } )
);
}
次に IndexScene クラスの _onGoto() メソッドに設定してある DoTweener コマンドを IndexPage クラスの _onCastRemoved() メソッドに移植します。こちらでも同じく対象設定の変更を忘れないようにしてください。
protected override function _onCastRemoved():void {
// 実行したいコマンドを登録します。
addCommand(
// ページを透明にします。
new DoTweener( this, { alpha:0, time:1 } )
);
}
移植が完了したら、それぞれ対応するシーンクラスのコマンドを削除しておいてください。
protected override function _onInit():void {
// ページを透明にします。
page.alpha = 0;
// 実行したいコマンドを登録します。
addCommand(
// ページを画面に表示します。
new AddChild( progression.container, page )
// ページを不透明にします。
new DoTweener( page, { alpha:1, time:1 } )
);
}
protected override function _onGoto():void {
// 実行したいコマンドを登録します。
addCommand(
// ページを透明にします。
new DoTweener( page, { alpha:0, time:1 } ),
// ページを画面から削除します。
new RemoveChild( progression.container, page )
);
}
以上で移植は完了です。FLA ファイルをプレビューして、以前と同様の動作をするかどうか確認してみましょう。
前項までの内容で、コンテンツ部分の制作は完了しました。今回のようなシンプルなコンテンツの場合にはファイルサイズも気になりませんが、ある程度の規模になってくるとプリローダーの仕組みが必要になってきます。Progression では、そのようなケースを想定して標準でプリローダー機能が備わっています。
プリローダーを作成するには、プロジェクト内の src フォルダ内にある preloader.fla を編集することになります。
preloader.fla を開いてドキュメントクラスを確認すると、myproject.Preloader クラスが設定されていますので、まずはこのクラスを編集していきましょう。
Preloader クラスは CastPreloader クラスを継承しており、Index クラスと同様に _onInit() イベントハンドラメソッドで初期化処理を設定することができます。まずはこのタイミングで読み込み状態を表示するためのテキストフィールドを作成しておきましょう。
public var _loadedPerField:TextField;
protected override function _onInit():void {
// stage の初期設定を行います。
align = StageAlign.TOP_LEFT;
quality = StageQuality.HIGH;
scaleMode = StageScaleMode.NO_SCALE;
// 開発者用の出力を有効化します。
//Verbose.enabled = true;
//Verbose.filteringCommand();
// TextField を作成します。
_loadedPerField = new TextField();
_loadedPerField.x = 280;
_loadedPerField.y = -100;
_loadedPerField.width = 200;
_loadedPerField.autoSize = TextFieldAutoSize.CENTER;
_loadedPerField.text = "Loading ... 0%";
addChild( _loadedPerField );
}
次にポイントとなるのは _onCastLoadStart() イベントハンドラメソッドです。このメソッドはプリローダーがメインのコンテンツファイルの読み込みを開始した瞬間に実行され、このメソッドの実行中はシーンオブジェクトやキャストオブジェクトと同様に addCommand() メソッドによるコマンド処理が実行可能です。このイベントは、主にプログレスバー表示の際のアニメーション処理などを行うものとして設計されています。今回は以下のように設定することにしましょう。
protected override function _onCastLoadStart():void {
// 実行したいコマンドを登録します。
addCommand(
// テキストフィールドを画面内に移動させます。
new DoTweener( _loadedPerField, { y:200, time:1 } )
);
}
_onCastLoadStart() イベントハンドラメソッドで登録したコマンドが全て実行完了すると、実際に読み込み処理が監視されます。読み込みが開始されると _onProgress() イベントハンドラメソッドが呼ばれるようになります。ただし、このイベント中には _onCastLoadStart() イベントハンドラメソッドのように addCommand() メソッドを使用することはできません。これは _onProgress() メソッドが Event.ENTER_FRAME のように逐次呼ばれるイベントであるため、時間のかかる非同期処理を設定しても意味がないための仕様です。
今回は以下のようにテキストフィールドに表示している読み込み状態を更新していくことにしましょう。
protected override function _onProgress():void {
// テキストフィールドの表示内容を、読み込み状態に応じて変化させます。
_loadedPerField.text = "Loading ... " + Math.round( bytesLoaded / bytesTotal * 100 ) + "%";
}
最後に _onCastLoadComplete() イベントハンドラメソッドを使用して、読み込み完了後の処理を設定します。このイベントの際には _onCastLoadStart() メソッドの時と同様に addCommand() メソッドが使用可能になります。
protected override function _onCastLoadComplete():void {
// 実行したいコマンドを登録します。
addCommand(
// テキストフィールドを画面外に移動させます。
new DoTweener( _loadedPerField, { y:500, time:1 } ),
// テキストフィールドを画面から削除します。
new RemoveChild( this, _loadedPerField )
);
}
読み込まれた SWF ファイルは、_onCastLoadComplete() イベントハンドラメソッドが完了し、登録されたコマンドが全て実行終了したタイミングで画面に表示されるようになります。
以上で全ての作業は完了しました。最後に作成したコンテンツを公開する方法をご説明します。
以上がクラススタイルの基本的な制作方法になります。今回ご紹介できなかったクラスにも様々な機能が含まれていますので、それらを活用してよりよいコンテンツ制作にお役立てください。
FLASH OOP for ActionScript 3.0
Progression の仕様を決定するまでの流れを技術的な面から解説しています。Progression 2 時代に執筆されたものですが、基本概念は Progression 3 でも同様です。
Web Designing 2009年 08月号
Progression 特集。
Web Designing 2009年 03月号
Progression の連載、第 3 回クラス編とインタビューが掲載されています。
Web Designing 2009年 02月号
Progression の連載、第 2 回コンポーネント編が掲載されています。