Flashのフレームワーク「Progression3」を始めてみよう!

第4回Progression3でWebサイトを作る(前編)

お待たせしました! いよいよ今回よりProgression3を利用してWebサイトの作成を行っていきます。

今回は非常に簡単なサンプルサイトの作成となりますが、それでも非常に少ない労力でフルFlashのWebサイトが作成できるということを実感していただければ幸いです。

冗長となってしまうのを避けるため、既に用意してある素材を元に制作します。

以下より、元素材となるプロジェクトファイル一式をダウンロードしてください。

それでは始めてみましょう。

まず、サイト全体をどのような構成にするかを考えます。

この作業は、Progressionのシーン機能をどのような構造にするかを決定するために必要な作業です。

今回は以下のような構造で作成することとします。1項目を1つのシーンとし、前編では子シーンまでを作成します。

図1 今回作成するWEBサイトの構造
今回作成するWEBサイトの構造

キャストクラスの準備

キャストクラスの作成

早速ですが、インデックスシーンを作成していきましょう。そのためにキャストクラスを作成します。今回は簡単に作成するために、各キャストクラスの見た目はFlashのファイルに用意されているムービークリップを使用します。

最初に作成するのは以下のパーツです。

  • 背景
  • ロゴ
  • ボタン

背景とロゴはCastSprite、ボタンはCastButtonを継承したクラスを作成します。

さて、早速キャストクラスを作成していきますが、ここで連載第2回の方法と同様にTemplatesフォルダに入っているテンプレートファイルからコピーをしてキャストクラスを作成します。

TemplatesフォルダのMyCastSprite.asをコピーしてstageフォルダへペーストしてください。

図2 キャストスプライトの作成
図2 キャストスプライトの作成

その後、MyCastSprite.asのファイル名をBackImage.asと名前を変更し、パッケージ名をmyproject.stage、クラス名、コンストラクタをBackImageと変更します。

package myproject.stage 
{
  import jp.progression.casts.*;
  import jp.progression.commands.*;
  import jp.progression.events.*;
  import jp.progression.loader.*;
  import jp.progression.*;
  import jp.progression.scenes.*;

  /*======================================================================*//**
  * BackImage クラス
  */
  public class BackImage extends CastSprite
  {
  
    /*======================================================================*//**
    * コンストラクタ
    */
    public function BackImage( initObject:Object = null ) 
    {
      super( initObject );
    }
以下略

Flashファイルのムービークリップとの関連づけ

これで、クラスファイルの用意はできましたが、このクラスファイルをFlashに用意してあるムービークリップへ関連付ける必要があります。

Flashファイルのライブラリパネル内のstageフォルダにBackImageというムービークリップがありますので、そのムービークリップを右クリックして、メニューの中にあるプロパティを選択するか、ライブラリパネルの下にあるiボタンをクリックしてください。

するとシンボルプロパティというダイアログボックスが開きますので、ActionScriptに書き出し、最初のフレームに書き出しにチェックを入れ、クラスにmyproject.stage.BackImageと記入し、OKを押してください。ここで警告が出てしまう場合はクラスのスペルが間違っていないかをチェックしてください。合っていれば無警告でダイアログが閉じます。

図3 用意されているムービークリップにクラスを関連付ける
図3 用意されているムービークリップにクラスを関連付ける

これで一つのキャストオブジェクトの用意が完了したことになります。

上記と同様に、ロゴを作成してください。ロゴはCastSprite、クラス名はLogo、フラッシュのムービークリップはstageフォルダ内のLogoです。

次にボタンの作成を行います。

ボタンの場合はMyCastButton.asをコピーして作ります。パッケージ名はmyproject.buttonsとしてください。

フラッシュファイルのライブラリの中のbuttonsフォルダに入っているムービークリップに各々上記と同様の設定をします。

シーン移動時に実行されるメソッド

次に、インデックスシーンに動作を与えます。

インデックスシーンは最初に移動するシーンであり、今回はここを出発点とします。表示され続ける背景やロゴの設置はこのシーンで行う事とします。

ここで、シーンで用意されているメソッドについてある程度覚えておかなければいけません。以下簡単ですが、紹介します。

_onLoadメソッド
当該シーンへの到達時、通過時両方でこのメソッドが呼ばれることになります。直接、孫シーンへの到達が行われた際も考慮し、データのロードや削除しないオブジェクト等の設置はこのメソッドで行います。
_onInitメソッド
当該シーンへ到達した場合に実行されます。そのシーン固有の表示設定等を行います。
_onGotoメソッド
当該シーンから移動する際に実行されます。そのシーン固有の表示設定を解除する時に使用します。
_onUnloadメソッド
当該シーンからの移動時、通過時両方でこのメソッドが呼ばれることになります。子シーン、孫シーンで共通の表示項目を親シーンへ戻るときに消す等の処理を行いたい場合に使用します。

上記説明文だけでは良く分からないかと思いますので、以下に図を示します。

図4 シーン移動時に実行されるシーンオブジェクトのメソッド
図4 シーン移動時に実行されるシーンオブジェクトのメソッド

シーン移動時に実行されるメソッドを把握できたでしょうか? 最初は分からなくても徐々に理解できるようになっていきますので、数をこなすことが大事です。

インデックスシーンの作成

背景、ロゴの設置

さて、インデックスシーンにコードを書いていきます。

背景とロゴを追加する処理を記述するのですが、背景とロゴは最初に表示された後、どの場面でも同一のものを表示させておきたいところです。

また、子シーンのアドレスで直接アクセスされた際にも背景、ロゴは表示されていて欲しいので、インデックスシーンの_onLoadメソッドへ記述し、そのまま削除せずに置いておくようにします。

IndexScene.asファイルの_onLoadメソッド内に背景、ロゴのインスタンスを作成し、表示させる処理を記述します。

まず、パッケージをインポートしますので、以下2行をimport文の後ろに追加します。

import myproject.buttons.*;
import myproject.stage.*;

その後、_onLoadメソッドに以下を記述します。

protected override function _onLoad():void {
  //インスタンスの作成
  var backImage:BackImage = new BackImage();
  var logo:Logo = new Logo();
  // 実行したいコマンドを登録します。
  addCommand(
    new Prop(logo, {x:50,y:30 } ),
    new AddChild(progression.container,backImage),
    new AddChild(progression.container, logo)
  );
}

これはPropコマンドでロゴの位置を指定し、AddChildコマンドで表示させるという処理を行っています。表示先コンテナのprogression.containerは現在のProgressionインスタンスに関連付けられているコンテナです。Progressionの表示コンテナと覚えておくと良いでしょう。

ボタンの設置

次に同様にしてボタンの設置を行います。今回はボタンも削除せずそのまま設置させるので、同じく_onLoadメソッドに追記します。

protected override function _onLoad():void {
  //インスタンスの作成
  var backImage:BackImage = new BackImage();
  var logo:Logo = new Logo();
  var btn_Information:Btn_Information = new Btn_Information();
  var btn_Gallery:Btn_Gallery = new Btn_Gallery();
  var btn_About:Btn_About = new Btn_About();
  // 実行したいコマンドを登録します。
  addCommand(
    new Prop(logo, {x:50,y:30 } ),
    new AddChild(progression.container,backImage),
    new AddChild(progression.container, logo),
    new Prop(btn_Information, { x:50, y:450 } ),
    new Prop(btn_Gallery, { x:300, y:450 } ),
    new Prop(btn_About, { x:550, y:450 } ),
    new AddChild(progression.container, btn_Information),
    new AddChild(progression.container, btn_Gallery),
    new AddChild(progression.container, btn_About)
  );
}

この状態でムービープレビューをし、表示を確認してください。以下の図のように表示されます。

図5 インデックスシーンに背景、ロゴ、ボタンを設置
図5 インデックスシーンに背景、ロゴ、ボタンを設置

インデックスシーン固有の表現を追加

この後に、インデックスシーン固有の表現を追加します。

BackImage同様にtextsフォルダ以下にキャストスプライトをTxt_Preという名前で作成してください。パッケージ名はmyproject.textsとします。

作成後のフォルダの構造を以下に示します。

図6 現在のファイル構造
図6 現在のファイル構造

このTxt_Preクラスも他のキャストオブジェクトと同様にFlashファイルのムービークリップと関連付けを行います。ライブラリパネルの中のtextsフォルダに入っているムービークリップTxt_Preに関連付けます。

図7 ムービークリップTxt_Preにクラスを関連付ける
<strong>図7</strong> ムービークリップTxt_Preにクラスを関連付ける

今回のオブジェクトはシーン退出時のメソッドでも参照を行いたいため、クラスのprivate変数に参照を作成し、コンストラクタでインスタンスを作成します。

import myproject.texts.*;とインポート文も忘れず追加してください。

public class IndexScene extends SceneObject {

  private var _txt_Pre:Txt_Pre;
  /*======================================================================*//**
  * コンストラクタ
  */
  public function IndexScene() {
    _txt_Pre = new Txt_Pre();
  }

その後、今度は_onInitメソッドに以下を記述します。

protected override function _onInit():void {
  // 実行したいコマンドを登録します。
  addCommand(
    new Prop(_txt_Pre, { x:400, y:250} ),
    new AddChild(progression.container,_txt_Pre)
  );
}

この状態でムービープレビューを実行して、確認してください。以下の図のように、真ん中に文字が出現します。

図8 インデックスシーンに文字が追加された
図8 インデックスシーンに文字が追加された

キャストオブジェクトに動きをつける

現在の状態ですと動きが全くありません。それぞれのキャストオブジェクトに動きをつけていきましょう。

動きを付けるのは背景、ロゴ、真ん中の文字の出現、退出時と、キャストボタンのロールオーバー、ロールアウトの処理です。

まず、背景出現時にフェードインさせてみましょう。

BackImage.as内の_onCastAddedメソッドに処理を追加します。以下のとおりに記述してください。

protected override function _onCastAdded():void 
{
  addCommand(
    // 任意のコマンドを記述してください。
    new Prop(this, { alpha:0 } ),
    new DoTweener(this, { alpha:1, time:1 } )
  );
}

ムービープレビューを実行すると、背景がフェードインし、その後にロゴやボタンが追加されるのが分かるはずです。

Logo.asとTxt_Pre.asの_onCastAddedメソッドに上記と全く同じ処理を追加してください。

どうでしょう? 各々順番にフェードインされていくはずです。このようにキャストオブジェクトの_onCastAddedメソッドはaddCommand内で当該キャストオブジェクトがAddChildコマンドで追加された場合に実行されるメソッドです。

そして、実行タイミングに注視してください。

親のAddChildコマンド→当該キャストオブジェクトの_onCastAdded内のコマンド→親のAddChildコマンドの次のコマンドという処理の流れになる点が非常に大きなポイントとなります。これをコマンドチェインと呼びます。

次に、キャストボタンのロールオーバー、ロールアウトの処理を書いてみましょう。

Btn_About.asのソースコードを見てください。

前述のCastSpriteとは異なり、_onCastAddedメソッドが無いかわりに_onCastMouseDown、_onCastRollOverといったボタン固有のメソッドを持っています。

今回はロールオーバー、ロールアウトの処理を記述するため、_onCastRollOver、_onCastRollOutの処理を以下のように記述します。

protected override function _onCastRollOver():void 
{
  addCommand(
  // 任意のコマンドを記述してください。
    new DoTweener(this,{alpha:0.5,time:0.5})
  );
}

protected override function _onCastRollOut():void 
{
  addCommand(
    // 任意のコマンドを記述してください。
    new DoTweener(this,{alpha:1,time:0.5})
  );
}

Btn_Gallery.as、Btn_Information.asにも全く同じように記述します。

ムービープレビューを実行して、確認してください。ボタンのロールオーバー、ロールアウトの際、ボタンが半透明になります。

連載第3回でも言及しましたが、キャストボタンは他のキャストオブジェクトとは少し異なり、ボタンの動作に特化したキャストオブジェクトです。まだここでは設定しませんが、キャストボタンならではの機能を沢山持っています。

シーンを作成する

シーンオブジェクトの作成

次に別のシーンの作成を行います。各々ボタンをクリックした時に遷移するシーンです。

TemplatesフォルダのMySceneObject.asをコピーしてscenesフォルダへペーストしてください。

図9 シーンオブジェクトの作成
図9 シーンオブジェクトの作成

そして、キャストオブジェクト同様にAboutScene.asとファイル名を変更し、パッケージ名、クラス名、コンストラクタ関数名を書き換えます。

package myproject.scenes 
{
  import jp.progression.casts.*;
  import jp.progression.commands.*;
  import jp.progression.events.*;
  import jp.progression.loader.*;
  import jp.progression.*;
  import jp.progression.scenes.*;

  /*======================================================================*//**
  * AboutScene クラス
  */
  public class AboutScene extends SceneObject 
  {

    /*======================================================================*//**
    * コンストラクタ
    */
    public function AboutScene( name:String = null, initObject:Object = null ) 
    {
      super( name, initObject );
    }

これでシーンオブジェクトの準備は完了です。

早速ボタンクリックでシーン移動をさせる処理を追加しましょう。

シーンを追加する

まず、シーンを追加します。

追加するシーンはインデックスシーンの子シーンとなりますので、IndexSceneクラスの_onLoadメソッドにシーンを追加する処理を記述します。

そして、aboutボタンのクリックでAboutSceneへ遷移するようにするため、Btn_AboutクラスのSceneIdプロパティに当該シーン識別子を設定します。

シーンパスはシーン名によって決定され、"/親シーン名/子シーン名"といった表記になります。

import myproject.scenes.*;とインポート文も忘れず追加してください。

protected override function _onLoad():void {
  var backImage:BackImage = new BackImage();
  var logo:Logo = new Logo();
  var btn_Information:Btn_Information = new Btn_Information();
  var btn_Gallery:Btn_Gallery = new Btn_Gallery();
  var btn_About:Btn_About = new Btn_About();

  //シーンの追加
  var aboutScene:AboutScene = new AboutScene("about");
  addScene(aboutScene);

  // 実行したいコマンドを登録します。
  addCommand(
    new Prop(logo, {x:50,y:30 } ),
    new AddChild(progression.container,backImage),
    new AddChild(progression.container, logo),
    new Prop(btn_Information, { x:50, y:450 } ),
    new Prop(btn_Gallery, { x:300, y:450 } ),
    new Prop(btn_About, { x:550, y:450 , sceneId:aboutScene.sceneId } ),
    new AddChild(progression.container, btn_Information),
    new AddChild(progression.container, btn_Gallery),
    new AddChild(progression.container, btn_About)
  );
}

CastButtonのsceneIdプロパティにsceneIdを設定する事により、CastButtonクリック時に当該シーンへ遷移させる処理を実装できます。詳細は連載第3回を参照してください。

これでaboutボタンをクリックすると、シーンが遷移されるようになります。当該シーン固有の状態を記述していませんので、見た目は全く変わりませんが、Indexクラスで開発者用の出力を有効にしておくと、遷移していることが分かります。

シーンの状態を作成する

さて、シーンは遷移しましたが、状態は全く変化していません。シーンの状態を作成していきましょう。

シーン固有のオブジェクトの用意

その前にシーン固有のキャストオブジェクトを用意します。

他のキャストオブジェクト同様にCastSpriteを元にAboutPageクラスをpagesフォルダの下に作成し、ファイル名をAboutPage.as、パッケージ名をmyproject.pages、クラス名、コンストラクタ関数をAboutPageとします。

そして、Flashファイルのライブラリパネル内のpagesフォルダ以下にある、ムービークリップAboutPageに関連付けます。

AboutPage クラスの用意ができたらAboutSceneに追加しましょう。

AboutScene.as
package myproject.scenes 
{
  import jp.progression.casts.*;
  import jp.progression.commands.*;
  import jp.progression.events.*;
  import jp.progression.loader.*;
  import jp.progression.*;
  import jp.progression.scenes.*;
  import myproject.pages.AboutPage;

  /*======================================================================*//**
  * AboutScene クラス
  */
  public class AboutScene extends SceneObject 
  {
    private var page:AboutPage;
    /*======================================================================*//**
    * コンストラクタ
    */
    public function AboutScene( name:String = null, initObject:Object = null ) 
    {
      super( name, initObject );
      page = new AboutPage();
    }

シーンの遷移のタイミングよってAboutPageは出したり消したりするため、_onInitメソッド、_onGotoメソッドに出現、退出の処理を追加します。

protected override function _onInit ():void 
{
  addCommand(
    // 任意のコマンドを記述してください。
    new Prop(page, { x:50, y:100 } ), 
    new AddChild(progression.container, page)
  );
}

protected override function _onGoto():void 
{
  addCommand(
  // 任意のコマンドを記述してください。
    new RemoveChild(progression.container, page)
  );
}

インデックスシーンから移動した際の処理

これだけでaboutボタンをクリックするとAboutページが表示されるようになりますが、インデックスシーンで表示している文字が残ってしまっています。

これをシーン移動時に削除します。

IndexSceneクラスの_onGotoメソッドに以下の処理を追加します。

protected override function _onGoto():void {
  // 実行したいコマンドを登録します。
  addCommand(
    new RemoveChild(progression.container,_txt_Pre)
  );
}

AboutPageの表示が唐突な感じですのでAboutPageをフェードイン、フェードアウトさせます。AboutPageクラスの_onCastAdded、_onCastRemovedクラスに以下の処理を追加します。

protected override function _onCastAdded():void 
{
  addCommand(
    // 任意のコマンドを記述してください。
    new Prop(this, { alpha:0 } ),
    new DoTweener(this, { alpha:1, time:1 } )
  );
}

protected override function _onCastRemoved():void 
{
  addCommand(
    // 任意のコマンドを記述してください。
    new DoTweener(this, { alpha:0, time:1 } )
  );
}

ムービープレビューを行ってください。Aboutボタンをクリックすると、aboutシーンへ遷移し、AboutPageが表示されるようになりましたでしょうか?

インデックスシーンへ戻る際の処理

ここで、IndexSceneへ戻る手段が無いことに気づきます。AboutSceneに閉じるボタンを設けて、IndexSceneへ戻る処理を追加します。

まず、閉じるボタンの制作を行います。

他のキャストボタンオブジェクト同様にCastButtonを元にBtn_Closeクラスをbuttonsフォルダの下に作成し、ファイル名をBtn_Close.as、パッケージ名をmyproject. buttons、クラス名、コンストラクタ関数をBtn_Closeとします。

そして、Flashファイルのライブラリパネル内のbuttonsフォルダ以下にある、ムービークリップBtn_Closeに関連付けます。

Btn_Closeクラスの用意ができたらAboutSceneクラスに処理を追加しましょう。

import myproject.buttons.Btn_Close;とインポート文も忘れずに追加してください。

プライベート変数を用意し、コンストラクタでインスタンスを作成します。

public class AboutScene extends SceneObject 
{
  private var _page:AboutPage;
  private var _btn_Close:Btn_Close;
  /*======================================================================*//**
  * コンストラクタ
  */
  public function AboutScene( name:String = null, initObject:Object = null ) 
  {
    super( name, initObject );
    _page = new AboutPage();
    _btn_Close = new Btn_Close();
  }

AboutSceneクラスの_onInit、_onGotoメソッドに処理を追加します。

ここで注目してほしいのは、閉じるボタンをAboutPageに追加している箇所です。

コマンドが上から順に実行されていくため、ボタンをページに追加→ページをフェードイン→ボタンに移動先を設定というような処理のフローを簡単に実装することができます。

protected override function _onInit():void 
{
  addCommand(
    // 任意のコマンドを記述してください。
    new Prop(_btn_Close, { x:700, y:0 , sceneId:progression.root.sceneId } ), 
    new AddChild(_page, _btn_Close),
    new Prop(_page, { x:50, y:100 } ), 
    new AddChild(progression.container, _page)
  );
}

_btn_Close のsceneIdに見慣れないコードを指定していますが、SceneオブジェクトはprogressionというProgressionインスタンスを参照するプロパティを持っていますので、Progressionインスタンスのrootプロパティは当該Progressionインスタンスの一番基底にあるシーンを参照しています。この場合、一番基底にあるIndexSceneへ遷移するために、progressionプロパティを利用し、IndexSceneを参照しています。

このようにProgressionの各オブジェクトは様々な参照方法が用意されています。この便利さもProgressionの魅力の一つです。

protected override function _onGoto():void 
{
  addCommand(
  // 任意のコマンドを記述してください。
    new RemoveChild(_page, _btn_Close),
    new RemoveChild(progression.container, _page)
  );
}

以上の処理を記述し終えたら、一旦ムービープレビューを実行してみましょう。

aboutページに閉じるボタンが追加され、クリックするとインデックスシーンに戻るようになったはずです。

残りのシーンを作成

残りの2つのシーンをAboutSceneと全く同じ方法で作成してください。スペルミスで動作しないことが多々ありますので、スペルミスには十分注意しましょう。

IndexScene.asのシーン追加部分を以下に示します。

protected override function _onLoad():void {	
  var backImage:BackImage = new BackImage();
  var logo:Logo = new Logo();
  var btn_Information:Btn_Information = new Btn_Information();
  var btn_Gallery:Btn_Gallery = new Btn_Gallery();
  var btn_About:Btn_About = new Btn_About();

  //シーンの追加
  var informationScene:InformationScene = new InformationScene("information");
  addScene(informationScene);

  var galleryScene:GalleryScene = new GalleryScene("gallery");
  addScene(galleryScene);

  var aboutScene:AboutScene = new AboutScene("about");
  addScene(aboutScene);

  // 実行したいコマンドを登録します。
  addCommand(
    new Prop(logo, {x:50,y:30 } ),
    new AddChild(progression.container,backImage),
    new AddChild(progression.container, logo),
    new Prop(btn_Information, { x:50, y:450 , sceneId:informationScene.sceneId } ), 
    new Prop(btn_Gallery, { x:300, y:450 , sceneId:galleryScene.sceneId } ), 
    new Prop(btn_About, { x:550, y:450 , sceneId:aboutScene.sceneId } ), 
    new AddChild(progression.container, btn_Information),
    new AddChild(progression.container, btn_Gallery),
    new AddChild(progression.container, btn_About)
  );
}

最終的には以下のような構成となります。

図10 前編での最終的なファイルの構造
図10 前編での最終的なファイルの構造

ムービープレビューを実行してみましょう。右クリックのメニューでシーンを戻ったり進んだりできるようになっていると思います。

もし、Web上で公開する方法をお持ちであれば、index.asの57行目、prog.sync = false;をprog.sync = true;に変えてからパブリッシュし、deployフォルダ以下のファイルを全て同じ構成でアップロードしてみてください。

各シーンに固有のURLが付与されます。

※ 完成版サンプルサイトはこちらになります。

今回はここまでです。次回は孫シーンを作成します。シーンを沢山作らなければならない場合、今回の様に一つ一つ作成していたのでは、非常に労力がかかります。気づいた方もいるとは思いますが、今回の3つのシーンは表示するページのSprite以外、全て同じ構成になっています(この後、個々に様々な機能をつけるため、今回は分けています⁠⁠。同じようなシーンであれば、クラスを使いまわすことによって解決することができます。

次回はそのあたりの説明をいたします。

できる人は今回のキットを使用して進めてしまってかまいません。新たにダウンロード素材をご用意する予定です。

また、今回は完全なチュートリアル記事でしたが、次回は既にできあがった物に対して説明をいきますので、よろしくお願いします。

おすすめ記事

記事・ニュース一覧