Flashは、アーティスチックなコンテンツやプログラムチックなコンテンツを作るツールとしては抜きん出た存在です。ActionScriptがバー ジョン3.0となり、Flashは今まで以上にパワフルなツールとなりました。ある意味、脅威でもあります。この「デベロッパー/デザイナー向け ActionScript 3.0講座」の第1回目の講座では、モジュール・プレローダーの作成を通してクラスの書き方を紹介し、ActionScript 3.0の世界を体験していただきたいと思います。また、パフォーマンスを最適化するための実例や、アートワークを見直して思い通りのルック&フィールを実 現するための考え方を紹介します。個人の作品であっても、Flashコンテンツのポテンシャルを最大限に生かすには、デザインや開発がうまくかみ合ってい なければなりません。

タイムライン

まずはじめに、デベロッパーのみなさんにお知らせです。タイムラインは、デベロッパーさんの敵ではありません。むしろ、友達と言っていいくらいです。協力者です。ぜひとも、タイムラインを使いましょう。

<タイムラインって本当に役立つの?>

デベロッパーの方々は、「アートワークをステージに配置するときは、ダイナミックに配置した方がタイムラインも整理できるのでよい」と教わっているのではないでしょうか。もっともらしく聞こえますが、実際はというと、みなさんが思っているほど役立つ教えではありません。

この記事ではプレローダーを作りますが、私はプレローダーを直接ステージに配置しています。その理由は、ダイナミックに配置する場合はディスプレイ領域の中心を計算しなければなりませんが、その手間が省けるからです。「x = width * stageWidth/2 + someOffset」といったコードを書く必要はありません。私の代わりにFlashが計算をしてくれるので、その分、私はプレローダーを自分の思い通りの位置に配置することに集中できます

プレローダーをステージの中心に配置し、プレローダーのタイムラインを図1のように作成してフレームラベルを付けました。

タイムラインだけでなく、さらにフレームラベルも付けました。その理由は、フレームラベルを使えば、アニメーションの内容が一目瞭然となるからです。「フレーム2で登場してきて、フレーム37で消え始める」といった内容をいちいちメモしておかなくても、フレームラベルの「IN」と「OUT」という文字を見れば、そのアニメーション内容がわかります。

タイムラインを活用すれば、ステージ上でプレローダーを表示する際の位置が思い通りにならずに試行錯誤することはありません。しかも、デザイナーがプレローダーを修正したい場合でも、簡単に行うことができます。INのラベルを付けた部分のアニメーションに10フレーム分追加したくなったとしても、問題ありません。さらにプレローダーの色をグリーンからパープルにしたい? もちろん大丈夫です。見た目をワイングラスにして、ローディングが進むごとにグラスが満たされるようにしたい? どうぞ、できますよ。つまり、タイムラインを使えば、「コンテンツのプレローディング」というプレローダーの本質的な機能を損なわずに、ルック&フィールを自由に変更することができるのです。

<プレローダーのタイムライン>

この記事で作成するプレローダーは、いろいろな状況に対応でき簡単に使い回しができるようにするため、以下のように設計しました。

  1. ローディングを開始する準備ができたら、プレローダーのタイムラインにIN(登場)アニメーションを再生するように指示する。
  2. プレローダーのINアニメーションが完了したら、「progress_mc」と名付けたムビークリップをステージ上に配置する。
  3. ローディングが進行状況に応じて、ロード済の割合(%)を算出し、progress_mcムービークリップのタイムラインのロード済の割合に該当するフレームを再生する。
  4. progress_mcムービークリップのタイムラインが最後まで再生されたら、つまりロードが完了し100%になったら、プレローダーのタイムラインにOUT(消失)アニメーションを再生するように指示する。
  5. プレローダーのタイムラインのOUTアニメーションが完了したら、サイトあるいはアプリケーションにその旨を通知し、プレローダーを再利用するためにリセットする。

わりと分かりやすい設計です。ただ、いつINやOUTのアニメーションが完了したのかをどうやって調べるのか気になる人もいるでしょう。それについては、次の項目で解説します。

<イベント、リスナー、イベントディスパッチ、イベントフック>

ActionScript 3.0ではイベントディスパッチ(イベント送出)という概念があります。ActionScript 1.0や2.0の経験がある人ならば、十分に理解していなくても、なんとなく分かるのではいないでしょうか。たとえば、以下のようなコードがあります。

var mouseListener = new Object(); mouseListener.onMouseDown = function() { trace("The mouse button is down."); }; Mouse.addListener(mouseListener);

mouseListenerオブジェクトは、Mouseクラスのイベント(onMouseDown)を監視しています。そのイベント、つまりユーザーがマウスボタンを押したときに、MouseクラスはonMouseDownイベントをディスパッチ(送出)します。そして、mouseListenerオブジェクトがonMouseDown関数を実行します。イベントディスパッチの特長は、複数のオブジェクトが同じ1つのイベントを監視しつつ、そのイベントが起きたときにオブジェクトごとに異なる処理を設定できるというところにあります。以下のコードは、その例です。

var mouseListener1 = new Object(); var mouseListener2 = new Object(); mouseListener1.onMouseDown = function() { trace("the mouse button is down."); }; mouseListener2.onMouseDown = function() { trace("1+1=" + (1+1)); }; Mouse.addListener(mouseListener1); Mouse.addListener(mouseListener2);

2 つのリスナーがあります。2つのリスナーとも同じイベントを監視していますが、そのイベントが起きた際は異なる処理を行うようになっています。上記の例では、両方のリスナーとも出力パネルに違うメッセージをトレース出力しています。もちろんまったく異なる処理を実行させることも可能です。

オブジェクト指向プログラミングを習得したい、特にクラス作成に興味があるという人は、このイベントディスパッチ概念は非常に重要なものなので、ぜひ押さえておいてください。クラスの内容に関係なく、複数のクラスが同じイベントを扱うことができるのです。

<オブジェクト指向プログラミングの補足説明>

先ほどオブジェクト指向プログミラングについて触れましたが、少し実際のコードから離れて、現実の世界に置き換えて考えてみましょう。あなたのコードはファーストフードレストラン「ActionScriptカフェ」だとします。そして、ユーザーは、そこに来るお客さんでお腹がすいています。お客さんが何かを注文したい。そのとき、あなたのレストラン(ActionScriptコード)での対応は、以下の2つが考えられます。

  • シナリオ1: お客さんがウェイターに欲しいものを伝える。それから、ウェイターかお客さんのどちらかが、クックにそれを伝えることになっている。そしてウェイターか、お客さんか、クックの誰かが料理を作ることになっている…このように誰が何をすべきなのかが明確でないと混乱が起きてしまい、非常に効率が悪くなってしまいます。
  • シナリオ2: お客さんはタッチスクリーンを使って注文する(残念ながら、ウェイター職をタッチスクリーンに奪い取られたのです)。注文内容がクックとレジ係に伝わり、料理が出され、支払いが行われる。クックは食材の調理方法を知っていますし、レジ係はレジの扱い方を知っています。クックは、お客さんの支払いのことは気にする必要はありません。ちゃんと払ってくれるだろうと思っておけばいいのです。一方で、レジ係は料理のことを気にする必要はありません。料理に問題があれば、それはレジ係の責任ではなく、クックの責任となるからです。

これをプログラミングに置き換えると、シナリオ1は古いスタイルのプログラミング方法です。どの時点で何が起きているのかが把握しづらく、バグがあっても解決するのが困難です。シナリオ2は理想的なプログラミング方法です。料理に問題があればクッククラスを調べればよく、レジに問題があればレジ係クラスを調べればいいのです。もし両方に問題があれば、タッチスクリーンクラスを調べるのです。とにかく、このように役割分担を明確にすることで、コードは整理され管理しやすくなります。

<ActionScript 3.0でのイベントハンドリング>

それでは、プレローダーを例に、ActionScript 3.0でイベントがどのように作用するかを説明しましょう。ActionScript 3.0では、独自のイベントを定義できます(ActionScript 2.0でも同様に行えます)。さらに、ムービークリップはEvent Dispatcherを拡張します。つまり、先ほどのコード例と同じ方法でムービークリップはイベントをディスパッチすることができます。この特徴がいかに役立つことなのかを、プレローダーを例にお見せしましょう。再度図1を見てください。タイムラインのIN_IDLEフレームラベルのところにコードがあります。

import com.bigspaceship.events.AnimationEvent; dispatchEvent(new AnimationEvent(AnimationEvent.ANIMATE_IN)); stop();

importステートメントは、外部クラス(後述します)をこのタイムラインで使用するために読み込むためのコードです。AnimationEventは私が作ったカスタムイベントで、ここではAnimationEvent.ANIMATE_INイベントをディスパッチします。このイベントの内容はシンプルです。 ActionScript 1.0でonMouseDown イベントが起きることによって「マウスが押された」ことが検知できるのと同じように、リスナーは、AnimationEvent.ANIMATE_INを監視し、「タイムラインのINフレームラベルのアニメーションが完了した」こと検知します。タイムラインのOUT_IDLEフレームラベルにも似たようなコードを記述しています。

import com.bigspaceship.events.AnimationEvent; dispatchEvent(new AnimationEvent(AnimationEvent.ANIMATE_OUT)); stop();

同じようにdispatchEventを使って、「タイムラインのOUTフレームラベルのアニメーションが完了した」ことをディスパッチしています。私は、これらのイベントを「イベントフック」と呼んでいます。INやOUTのアニメーションが再生されているとき、コードでは待機して監視しているのです。そしてイベントフックに到達すると、プレローディングを進めるようにロジックを作っています。イベントハンドリングの詳細については、Introduction to event handling in ActionScript 3.0を見てください。

ムービークリップをプレローダークリップに変換する

前のページでは、1つのイベントに対して複数のリスナーが検知し、それぞれ異なる処理を実行できることを説明しました。また、カスタムイベントの作成例や、それを使ってどのようにタイムラインでのアニメーション完了をイベントとしてディスパッチするかを紹介しました。この手法を使えば、特定のタイミングで関数を呼び出すことができます。プレローダーでロード状況(%)を正確に表示するには、まさにこの手法が最適です。また、今回のサンプルでは、外部クラスを使用するためにimportステートメントを使用しています。それでは、ActionScriptのクラスについて詳しく解説して行きましょう。クラスを使ったモジュールコーディングは、役立つコーディング手法なのでぜひ覚えてください。

<クラスの構造>

クラスにはコードの書き方があります。初心者は、シンプルなコードからクラスへと発展させていくといいでしょう。慣れてくれば、今のコードの書き方よりもクラスの書き方のほうが分かりやすく感じるようになると思います。以下は、簡単なクラスコードの例です。

package { public class MyClass { var myVar:String // this is a class variable, otherwise known as a property. function MyClass() { } // this is called the constructor. When you create new MyClass(), this function automatically runs. function doSomething() {} // this is a class function, aka a method. I could call this to tell the class to quite literally do something. } }

クラスではimportステートメントを使って他のクラスを読み込んで利用することができます。先ほどのタイムラインのコードでは、「com.bigspaceship.events.AnimationEvent」を読み込んでいます。Flashのクラスやオブジェクト指向プログラミングに関する本はたくさんありますが、中でも私が役立つと思うのはColin Moockの『Essential ActionScript 3.0』です。彼の本は常に私の机の上に置いています。

<プレローダークリップのエンジンを構築>

プレローダークリップは特殊なムービークリップです。プレローダークリップは、基本的なムービークリップメソッド(startDragstopDragなど)とプロパティ(xyalphaなど)を持っているほか、ローディング用のカスタム機能も持っています。

MovieClipクラスを利用するので、以下のように記述します。

package com.bigspaceship.frameworks.site { import flash.display.MovieClip public class PreloaderClip extends MovieClip { function PreloaderClip() {}; }; };

ここで注目してほしいのは、4行目の「extends MovieClip」です。プレローダークリップはMovieClipクラスを拡張したものです。プレローダークリップの1フレーム目には「stop();」を記述しています。これは、指示があるまでプレローダーのアートワークが表示されないようにするためです。プレローダーを表示させたら、INフレームラベルのセクションを再生させるので、以下のようなメソッドを作ります。

public function animateIn():void { gotoAndPlay("IN"); addEventListener(AnimationEvent.ANIMATE_IN, _onPreloaderIn,false,0,true); };

このメソッドでは、タイムラインにINアニメーションを再生させるように指示しているとともに、私が作成したカスタムイベントAnimationEvent.ANIMATE_INを監視しています。そのイベントが検知した場合は、自動的に_onPreloaderIn関数を呼び出します。_onPreloaderIn関数は以下のようになっています。

private function _onPreloaderIn($evt:Event):void { progress_mc.addEventListener(Event.COMPLETE,_onProgressBarComplete,false,0,true); progress_mc.addEventListener(Event.ENTER_FRAME,_onProgressEnterFrame,false,0,true); progress_mc.stop(); dispatchEvent(new Event(Event.INIT)); };

プレローダークリップ内には、progress_mcという名前のムービークリップが入れ子で入っています。このprogress_mcムービークリップは、準備が整わないうちにロード状況を表示してしまわないように一旦ストップさせておき、さらに「Event.COMPLETE」と 「Event.ENTER_FRAME」の2つの新しいイベントを監視させています。

ENTER_FRAMEは、onEnterFrameイベントを扱うための新しい方法です。ここでは、毎フレームごとに_onProgressEnterFrame関数を呼び出しています(詳細はのちほど)。Event.COMPLETEは、progress_mcムービークリップのタイムラインの最後にあるイベントフックです。progress_mcムービークリップのタイムラインの最後まで再生したら、ローディング完了ということです。dispatchEventの行はとても重要なコードです。プレローダークリップが、リスナーに何かが起きたことを知らせるためのものです。私が作成したイベントフックのように、addEventListener()をどこかに記述して、プレローダーの準備が整ってローディングを開始してもよいタイミングを知ることができます。

では、ENTER_FRAME時に呼び出す_onProgressEnterFrame関数のコードを見てみましょう。

private function _onProgressEnterFrame($evt:Event):void { (_targetFrame > progress_mc.currentFrame) ? progress_mc.play() : progress_mc.stop(); var totalPct:Number = Math.round((progress_mc.currentFrame/progress_mc.totalFrames) * 100); try { pct_mc.tf.text = totalPct.toString(); } catch($error:Error) { Out.debug(this,"% loaded: " + totalPct.toString()); } };

これがプレローダーの秘密部分です。実は、プレローダークリップは何もロードしていません。ただ、進行状況を表示しているだけです。外部から必要なファイルをロードして、そのロード状況に応じて、以下の情報をプレローダークリップに渡しているのです。

  • bytesLoaded:現在ロードしているアイテムのバイト数
  • bytesTotal:ロードした総バイト数
  • itemsLoaded:現在ロードしているアイテム
  • itemsTotal:ロードしたアイテムの総数

つまり、アイテムを順々にロードして行きます。たとえば、XMLファイル、SWFファイル、JPEGファイルをロードするとしたら、最初にXMLファイルをロードします。この場合、itemsLoadedは2のうちの0となります(ご存知の通り、常に0からカウントするからです)。XMLファイルのロードが完了したら、次はSWFファイルをロードします。itemsLoadedは1となります。最後にJPEGファイルをロードします。itemsLoadedは2となります。JPEGファイルのロードが完了すると、progress_mcムービークリップのタイムラインは最後まで再生されます。コンテンツが100%ロードされ、プレローダークリップはEvent.COMPLETEイベントを検知して、自動的に_onProgressBarComplete関数を実行します。

rivate function _onProgressBarComplete($evt:Event = null):void { _isLoadComplete = true; progress_mc.removeEventListener(Event.ENTER_FRAME,_onProgressEnterFrame); _animateOut(); }; private function _animateOut():void { gotoAndPlay("OUT"); addEventListener(AnimationEvent.ANIMATE_OUT, _onPreloaderOut,false,0,true); };

この関数では、プレロードの完了を受けて、タイムラインのOUTアニメーションを開始します。そして、イベントフック「AnimationEvent.ANIMATE_OUT」に到達すると、_onPreloaderOut関数を実行します。

private function _onPreloaderOut($evt:Event):void { // プレローダーの再利用に備えて、リスナーをクリアします // もしクリアを忘れると、_onPreloaderIn()を2度実行することになり、イベントフック「ANIMATE_IN」に到達した時点ですべてが台無しになってしまいます removeEventListener(AnimationEvent.ANIMATE_IN,_onPreloaderIn); removeEventListener(AnimationEvent.ANIMATE_OUT,_onPreloaderOut); if(_isLoadComplete) dispatchEvent(new Event(Event.COMPLETE)); else animateIn(); };

この関数では、リスナーをクリアして、Event.COMPLETEイベントをディスパッチしています。こうしてリスナーに「プレローダークリップが完了して、ステージにロードしたコンテンツを表示できるようになった」ことを伝えます。

<プレローダーのテスト>

このプレローダーを使ってみましょう。本記事のサンプルにはもう1つMainというクラスを用意しています。この Mainクラスは、Document Rootクラスです。Document Rootはメインタイムラインのクラスです。SWFがロードされたとき、Document Rootは制御クラスになります。このMainクラスをセットするには、ステージのどこでもいいのでクリックして、使いたいクラスへのクラスパスを記述します。今回の場合、パッケージ内に入れ込むのではなく、単にMainと名付けて、Main.asファイルとして保存しています。以下は、Main.asの内容です。

public function Main() { Out.enableAllLevels(); Out.status(this,"Ready to go!"); // まずはじめに、プレローダークリップが完了した際にその旨を通知するように設定します。なお、Mainはメインタイムラインでpreloader_mcはプレローダークリップです。 preloader_mc.animateIn(); preloader_mc.addEventListener(Event.INIT,_onPreloaderIn,false,0,true); preloader_mc.addEventListener(Event.COMPLETE,_onPreloaderOut,false,0,true); }; private function _onPreloaderIn($evt:Event):void { _loadCount = 0; // 以下は、ActionScript 3.0でSWFファイルやJPEGファイルを読み込む方法です。 _swfLoader = new Loader(); _swfLoader.contentLoaderInfo.addEventListener(Event.INIT,_onSWFLoaded,false,0,true); _swfLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,_onLoadProgress,false,0,true); _swfLoader.load(new URLRequest("loadedContent.swf")); };

コンストラクタが呼び出される(つまり、SWFがイニシャライズされる)と、すなわちメインタイムラインにプレローダークリップ(preloader_mc)があるということなので、preloader_mcムービクリップにINアニメーションを再生するように指示します。そして、Mainはそのアニメーションが完了する時を監視するようにしています。それから、実際のローディングを行うローダーをセットアップします。このローダーはロード状況に関わるProgressEvent.PROGRESSイベントを監視していて、このイベントが起きるとMainにある_onLoadProgress関数を実行します。

private function _onLoadProgress($evt:Event):void { Out.status(this,"_onLoadProgress"); // ロード状況を表示するために必要なもの preloader_mc.updateProgress($evt.target.bytesLoaded,$evt.target.bytesTotal,_loadCount,_loadTotal); };

SWFのローディング中は、_loadCountの値は0で、_loadTotalは1となります。ここでは2つのファイルをロードしているだけなので、プレローダークリップは半分までロード状況が進んでいることを示します。SWFファイルのローディングが完了すると、Mainは_onSWFLoaded関数とともに待機します。_onSWFLoaded関数は以下のようになっています。

private function _onSWFLoaded($evt:Event):void { Out.status(this,"_onSWFLoaded"); _loadCount = 1; // XMLファイルをロードする準備ができました。ActionScript 3.0では、以下のようにしてXMLファイルをロードします。 // _onLoadProgress関数はSWFファイルでも、XMLファイルでも両方で使用できます。 _xmlLoader = new URLLoader(); _xmlLoader.addEventListener(Event.COMPLETE,_onXMLLoaded,false,0,true); _xmlLoader.addEventListener(ProgressEvent.PROGRESS,_onLoadProgress,false,0,true); _xmlLoader.load(new URLRequest("content.xml")); };

content.xmlというXMLファイルをロードしていますが、XMLローダーではSWFのときと同じようにMainにある_onLoadProgress関数を実行しています。1つの関数内の1行のコードが、すべてのビジュアルアップデートを扱っているのです。違いと言えば、_loadCountの値が0から1に変わったくらいです。XMLファイルのロードが完了したら、_onXMLLoaded関数が実行されます。_onXMLLoaded関数は以下のようになっています。

private function _onXMLLoaded($evt:Event):void { preloader_mc.setComplete(); };

以上です。プレローダーは完了して消えて行きます

private function _onPreloaderOut($evt:Event):void { var loadedSWF:MovieClip = _swfLoader.contentLoaderInfo.content; addChild(loadedSWF); // SWFをステージに配置 loadedSWF.gotoAndPlay("IN"); // fロードされたSWFは、そのINアニメーションを再生します loadedSWF.addEventListener(AnimationEvent.ANIMATE_IN,_onLoadedSWFAnimateIn,false,0,true); };

ロードされたSWFをステージに配置して、そのINアニメーションを再生します。これで完成です。

<Flashでクラスを使用する>

では、作成したこれらのクラスをFlashがどのように見つけるかというと、初期状態ではFlashはFLAファイルがあるディレクトリを探します。個人的には、FLAファイルと同じディレクトリにクラスファイルを置くのは好きではありません。分かりやすいディレクトリを作成してその中でクラスファイルを管理する方がよいでしょう。どのように行うかというと、メニューから「ファイル/パブリッシュ設定」を選び、パブリッシュ設定ダイアログを開きます。Flashタブを選んで、「ActionScriptのバージョン」項目の右側にある「設定」ボタンをクリックします(図2)。ちなみに、「ActionScriptのバージョン」項目は、「ActionScript 3.0」を選んでおいてください。

ActionScript 3.0設定ダイアログが表示されるので、「+」ボタンをクリックして新しいクラスパスを追加します。今回の場合、すべてのクラスファイルはFLAファイルと同じディレクトに作成した「_classes」ディレクトリ内で管理することにしているので、「./classes/」というパスを追加しました(図3)。

図4 は、FLAファイルの保存場所を示したものです。クラスファイルのディレクトリとの関係が分かるかと思います。ここでは、すべてのクラスファイルをクラスパッケージ名と関連したディレクトリで保存しています。たとえば、「foo.bar.MyClass」という名前のクラスなら、そのクラスファイルは「_classes/foo/bar/MyClass.as」ディレクトリにあります。

通常、クラス名を付ける際は一般的なパッケージ名から始めて、徐々に固有のディレクトリ名になるようするのが良いとされています。私の場合、最も一般的なクラス名として「com」を使っています。comディレクトリ内にあるbigspaceshipディレクトリには、私が所属する会社「Big Spaceship」のために作ったクラスやパッケージを置くようにしています。bigspaceshipディレクトリ内にあるframeworksディレクトリには、会社のプロジェクトで使う基本構造設計のため必要なすべてのクラスやパッケージを置くようにしています。frameworksディレクトリ内にあるsiteディレクトリには、Webサイトのプロジェクトで使うクラスを置いています(Adobe AIRアプリケーションやゲームに使うクラスと区別するためです)。この記事のサンプルの場合、すべてのコードは「_classes/com/bigspaceship/frameworks/site/PreloaderClip.as」ディレクトリに置いています。

なお、クラスパケージ名は自由に付けることができます。あなた次第です。ただ、チームで作業する場合は、私たちのように何か基準を設けて名前をつけた方が、ファイルを探しやすくなるでしょう。ファイルが見つからなくて作り直したという失敗を避けることができます。

<リンケージ>

ActionScript 2.0では、リンケージというと、ユニークIDを識別することでした。ActionScript 3.0ではというと、似ていますが違う部分もあります。ActionScript 3.0では、これまでの通り各ムービークリップは固有のリンケージIDを持っています。ただ、それだけでなくもう1つ「基本クラス」というパラメータを持っています。基本クラスとはリンケージのタイプを示すものです。今回の場合、MovieClipクラスを拡張したものなので、「flash.display.MovieClip」とします。拡張クラスについての解説は、この記事の範疇外なので詳しくは「 ActionScript 3.0 Language and Components Reference 」を見てください。このサンプルでは、リンケージの設定をリンク項目は「com.bigspaceship.frameworks.utils.PreloaderClip」とし、基本クラス項目は「flash.display.MovieClip」としています。プレローダーをステージにダイナミックに配置したい場合は、以下のようなコードを記述します。

import com.bigspaceship.frameworks.utils.PreloaderClip; var p:PreloaderClip = new PreloaderClip(); addChild(p);

上記のコードでは、新しいプレローダークリップを作成しており、このクリップは変数Pを使って参照できます。次にaddChild.を使ってそれをdisplay listに追加します。display listとは、Flash Playerがオブジェクトを扱う新しい方法のことです。かなり複雑な内容なので、ここでは解説を省きます。

<ついに完成>

これでFlashはステージ上に配置されたムビークリップを、MovieClipクラスを拡張したカスタムクラス「プレローダークリップ」として扱うようになります。Document Rootクラスには、ロード状況を表示する際に、プレローダークリップを活用するように設定しています。あとは、SWFファイルをコンパイルしてリラックスするだけです。

スーパーモジュール

もう1点、説明しておきたいことがあります。ロード中にプレロードの作業がリセットされる可能性があり、それに対応できるようにプレローダーをアップデートしておかなければなりません。ロードの途中で、
ユーザーが別なコンテンツをロードすることになった場合に備えて、いつでもロードアニメーションをキャンセルできる柔軟性を持たせたいところです。

この機能を実装するには、プレローダークリップにリセットしてから0%からロードし直す関数が必要です。そうしなければ、表示されているロード状況と実際のロード状況とが異なり、ユーザーが混乱し、サイトがおかしいと考えてしまうでしょう。それでは、以下の関数をプレローダークリップに追加します。

public function reset():void { _onProgressBarComplete(); _isLoadComplete = false; }; public function cancel():void { _onProgressBarComplete(); };

これだけです。機能は保持したまま、簡単に見た目を変更できて再利用もできるプレローダーの完成です。このプレローダークリップは、どんな状況にも対応できるはずです。少なくとも、ActionScriptの次のバージョンが登場するまでは大丈夫です。お気づきかと思いますが、このスクリプトではfor ループやonEnterFrameを1つも使っていません。それは、onEnterFrameのチェックや繰り返しループを行わないことで、コードのパフォーマンスが向上するからです。おかげで、このプレローダーはかなり快適に動作します。

まとめ

プログラミング要素だけでなくタイムラインなどいろいろな環境が統合されているのがFlashの強みです。デベロッパーの方々は、タイムラインを使わない方が綺麗でよりテクニカルなコードが書けると教えられてきたでしょうが、今はその考えを改めるときです。常に最もテクニカルな手法がベストなソリューションとは限りません。再設計をできるだけ押さえ、正確な役割を行う戦略というものが必要なときもあるのです。デザイナーを信頼し、仕様を設計する権限を与えることで、ワークフローはより早く流れ、目的を再確認しなければならないという失敗に落ちるリスクとストレスを減らし、そして何よりもあなた自身が健全になることができるはずです。仕事をするときは頭のどこかにこのことを置いておいてください。あなた一人で、デザインと開発を行っている場合でもそれは同じです。

必要条件

この記事に必要な予備知識

この記事はActionScript 3.0の基本を解説しています。必ずしも必要というわけではありませんが、ActionScript 2.0の知識があると理解しやすいでしょう。

ユーザーレベル

中級