- ベストアンサー
再訪時のランダムな背景について
- FLASH初心者のため、再訪時に背景をランダムに表示する方法について困っています。
- レイヤーの一番下に設定した背景画像がランダムに変わるのですが、上層の文字やボタンが表示されません。
- また、背景画像をゆっくりフェードインさせる方法もわからず困っています。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
ムービーのタイムラインに this.loadMovie( ・・・ ); とスクリプトを書いて読み込んだのでは、ムービー全体に画像が読み込まれ、ムービーそのものが読み込んだ画像に置き換えられてしまいます。 背景画像を受け取るムービークリップを用意しておき、このムービークリップに読み込むようにすると、背景だけをランダムに差し替えることができます。 フェードインはモーショントゥイーンを使う方法が一般的ですが、スクリプトで _alpha プロパティを操作する方法もあります。 今回はこちらをご紹介します。 外部から読み込んだファイルを使って何かをする時は、必ず、読み込みの終了を待ってから次の処理に進むようにしましょう。 ActionScript の loadMovie など外部のファイルを読み込むスクリプトは、”○○を読み込め”の命令を出すだけで終了し、すぐに次の処理に進みます。 しかし、どんなに単純なファイルであっても、読み込みの命令を出した直後に読み込みが完了することはまずあり得ません。 読み込みの終了を待たずに先に進むと、読み込んだものが表示されなかったり、その後の処理が上手く動かないなどの不具合の原因になります。 読み込みを待つ方法はいろいろありますが、loadMovie で読み込むとこのあたりの処理が少々面倒です。 Flash Player 7 (作成ツールは Flash MX 2004 )からは、loadMovie を強化した MovieClipLoader という読み込み専門のクラスが使えるようになりました。 このクラスの持つ機能(メソッドといいます)で読み込むと、読み込みが済んだ時にイベントが発生し、loadMovie よりも読み込みの終了を検出しやすくなっています。 MX 2004 をお使いとのことですので、せっかくですから、loadMovie ではなく MovieClipLoader を使ってみましょう。 ------------------------------------------------- まず、背景画像を読み込むためのムービークリップを用意します。 今回はとりあえずシンボルとして作りますが、スクリプトで作ることもできます。 一番下のレイヤーに、線のない塗りだけの四角形をステージと同じ大きさに描き、ステージの左上に合わせてください。 四角形ツールで適当な大きさに描き、「プロパティ」か「情報」パネルで大きさと座標を入力すると簡単です。 描画した四角形を選んだ状態で右クリック( Mac では control +クリック)でメニューを出し、この中から「シンボルに変換」を選んでください。 どのようなシンボルに変換するかを設定するパネルが開きますので、「タイプ:」のラジオボタンで”ムービークリップ”を、「基準点:」を表す図形で左上の四角形を選択して「 OK 」をクリックします。 描画した四角形がムービークリップに変換され、ステージにはその分身(インスタンス)が残ります。 ちなみに、ムービークリップに画像を読み込むと、画像の左上が基準点の位置に来るように読み込まれます。 左上以外の点を基準点にしていると画像がズレて表示されてしまいますので、ご注意ください。 ステージに残ったインスタンスに名前を付けてください。 この名前は、スクリプトでこのムービークリップに画像を読み込む時に必要になります。 インスタンスを選択した状態で、「プロパティ」パネルを見てください。 左上の方に <インスタンス名> と書かれた項目があります。 ここに、英数字と” _ ”だけで名前を入力してください。 仮に” back_image ”と付けたとします。 それから、同じく「プロパティ」パネルにある「カラー:」のリストから「アルファ」を選び、スライダを調節して0%に設定してください。 これで、ムービークリップが最初から透明になります。 ------------------------------------------------- 背景を読み込むためのムービークリップの準備ができたら、このムービークリップに画像を読み込み、読み込み終了を待ってフェードインさせるスクリプトを書きます。 スクリプトはフレームに書きます。 レイヤーは特に関係ありませんが、スクリプト専用のレイヤーを1つ用意しておくとスクリプトを管理しやすくなります。 (↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください。このまま使うとエラーになります) //MovieClipLoaderオブジェクトを作成 load_obj = new MovieClipLoader(); //ランダムに背景画像を読み込む img = Math.floor( Math.random() * 6 ) + 1; load_obj.loadClip( img + ".jpg" , back_image ); //読み込み終了時の処理を定義 load_obj.onLoadInit = function( clip:MovieClip ) { //フェードインの速さを設定 clip.fade_spd = 5; //フェードインの処理を定義 clip.onEnterFrame = function() { //フェードインの処理 clip._alpha += clip.fade_spd; //完全に不透明になったら終了 if( clip._alpha >= 100 ) { clip._alpha = 100; delete clip.onEnterFrame; } }; }; MovieClipLoader を使った読み込みでは、loadClipというメソッドで画像を読み込みます。 なお、1~6の間で乱数を作るスクリプトは、計算式で書くならば Math.floor( Math.random() * ( 6 - 1 + 1 ) ) + 1; です。 詳しくはこちらをご参考になさってください。 ・Math.random() でランダムな整数を取得する方法 http://www.macromedia.com/jp/support/flash/ts/documents/fl0173.html ****************************************** MovieClipLoader で読み込んだ時は、読み込みの様々な局面でイベントが発生するので、読み込みの状況を詳しく把握することができます。 このイベントが発生した時に実行する処理を予め定義しておくと、その処理が自動的に呼び出されます。 今回は、読み込んだファイルが利用可能になった時に発生する” onLoadInit ”というイベントを利用しています。 onLoadInit で呼び出される処理(関数)の中では、イベントが起きたムービークリップの名前(正確には参照といいます)を変数として利用できます。不要なら省略しても構いません。 上記のスクリプトでは、 load_obj.onLoadInit = function( clip:MovieClip ) ・・・ として、関数内でイベントが発生したムービークリップを操作できるように定義しています。 clip と書かれている部分が、この処理が実際に実行される時には、画像を読み込むムービークリップである” back_image ”に置き換えられると思ってください。 ****************************************** フェードインは、ムービークリップが持っているイベントである” enterFrame ”を利用して行います。 onEnterFrame = function ・・・として定義しておくと、ムービークリップがステージに存在している間、フレームレート分の1秒ごとに定義した処理が実行されます。 スクリプトでアルファを操作するには、_alpha というプロパティを書き換えます。 つまり、onEnterFrame を利用してフレームレート分の1秒ごとに _alpha プロパティを書き換える処理を実行し、連続的にアルファを更新することで徐々に画像がはっきり見えるようにするということです。 フェードインの速さは、fade_spd という変数を使って調節しています。 速さを変える時は //フェードインの速さを設定 clip.fade_spd = 5; の、” 5 ”の部分を変更してください。数字が大きいほどフェードインが速くなります。 フェードインはアルファが 100 %になったら終了です。 onEnterFrame は一種の変数のようなもので、これを削除すると次からは呼び出されなくなります。 上記のスクリプトでは if 文で _alpha の値を常時監視し、100 になった時点で onEnterFrame を削除してフェードインの処理を打ち切っています。 変数等を削除するには delete というスクリプトを使います。 背景のフェードインが済んでからボタンや文字を表示する場合は、メインのタイムラインを一旦 stop(); アクションで止めておき、フェードインが終わった後(上記のスクリプトでは delete clip.onEnterFrame; の前)に _root.play(); を入れてください。 ただ、フレーム1で stop(); を実行すると、稀に、ムービー自体の読み込みの都合でスクリプトが実行されず、勝手に進んでしまう場合があります。 フレーム1を空白にし、フレーム2にスクリプトを書いて背景画像の読み込みとフェードインの終了を待ち、それからフレーム3以降に進むと万全だと思います。 その場合でも、画像を読み込むムービークリップ” back_image ”はフレーム1からステージに配置してください。 長くなってすみませんでした。 不明な点がありましたら、補足してください。
その他の回答 (2)
- rheda
- ベストアンサー率30% (3/10)
loadMovieだと、_rootのムービーそのもの 全部が上書きされてしまうと思います。 loadMovieNumで、背景レイヤーに読み込むか、 背景レイヤーに、ムービークリップを置き、 そこに、loadMovieを使うものだと思います。
- DPE
- ベストアンサー率85% (666/776)
#1です。 MX 2004 をお使いでも、MovieClipLoader が使えるのは Flash Player 7 用にパブリッシュする時だけです。 Flash Player 6 以前のバージョンにパブリッシュするのでしたら loadMovie で読み込むしかありませんが、loadMovie には、読み込みが終了した時にイベントを発生させて知らせてくれる機能はありません。 ムービークリップの総容量と読み込み済み容量を調べるメソッドがありますので、これらで情報を取得して 100 %読み込まれたかどうかで判断するといった方法になります。 ただ、loadMovie で読み込みの命令を出した直後は画像ファイルはまだ開かれておらず、この間にムービークリップの容量を調べるとインスタンス自体の容量が返ってきてしまいます。 インスタンスは既に読み込まれてステージにあるのですから、完了率を計算すると当然ながら 100 %になっており、これでは画像の読み込みが完了したかどうかは判断できません。 そこで、loadMovie 等で外部からの読み込みが実行された時、データがダウンロードされるたびに発生する data というイベントを利用して画像の読み込みの進捗状況を把握します。 data イベントは読み込みが始まった後にしか発生しないので、インスタンス自身の容量が返ってくることはありません。 ただし、ムービークリップのイベントを使った処理の定義は#1でも使ったように on*** = function ・・・という書式でも書けるのですが、loadMovie 使用時の data イベントは例外で、onData = function で書くと正常に動きません。 data イベントを利用するには、ムービークリップへのもう1つの指示の仕方である onClipEvent アクションを使ってインスタンスに直接スクリプトを書く必要があります。 ------------------------------------------------------------- フレーム1で loadMovie や stop(); を使うと、ムービー本体の読み込みの都合によりスクリプトが上手く動かない場合があります。 (おそらく、ムービークリップがステージに読み込まれるタイミングと loadMovie が実行されるタイミングがわずかにズレることが原因だと思います) ムービークリップをフレーム1からステージに登場させ、画像を読み込むスクリプトはフレーム2に設定しておくと、必ずムービークリップの方が先に読み込まれるので安全です。 今回は、フレームとムービークリップの両方にスクリプトを設定します。 ムービークリップは#1と同じく、最初は透明(アルファを0%)でインスタンス名を” back_image ”とします。 (↓各行頭に全角のスペースが入っています。コピーする際はご注意ください) ●フレーム2に設定するスクリプト //ランダムに背景画像を読み込む img = Math.floor( Math.random() * 6 ) + 1; back_image.loadMovie( "image" + img + ".jpg" ); //タイムラインを止めておく stop(); ●ムービークリップ” back_image ”に設定するスクリプト onClipEvent(data) { //読み込みの進捗状況を把握 total = this.getBytesTotal(); loaded = this.getBytesLoaded(); //読み込み完了後、フェードイン開始 if( loaded >= total ) { //フェードインの速さを設定 this.fade_spd = 5; //フェードインの処理を定義 this.onEnterFrame = function() { //フェードインの処理 this._alpha += fade_spd; //完全に不透明になったら終了 if( this._alpha >= 100 ) { this._alpha = 100; delete this.onEnterFrame; //メインのタイムラインを動かす _root.play(); } }; } } ActionScript では、利用したい関数や変数・インスタンスがどの階層(タイムライン)にあるかを正確に指定しなければなりません。この指定のことをターゲットパスと言います。 ターゲットパスには相対と絶対があります。 this は相対的な表現で、ムービークリップのインスタンスに書いた onClipEvent や on の中では自分自身を指します。 つまり上記のムービークリップに書くスクリプトでは、this は back_image 自身を指しています。自分自身の容量を取得し、読み込みが完了したら自分の onEnterFrame イベントを使ってフェードインさせる、という意味になります。 #1のスクリプトでは、onEnterFrame = function ・・・の部分は、MovieClipLoader の仕様上、clip という変数を使って定義していました。 内容は同じなのですが、今回は clip の部分が this という表現に変わっていますのでご注意ください。 Flash ではムービー自体も1つのムービークリップとして扱い、通常は_root という名前で識別します。 メインのタイムラインやステージを表すターゲットパスが _root であり、ステージにあるインスタンスやメインのタイムラインで定義された関数や変数は、特に断りがなければ全て _root の持ち物です。 上記のスクリプトでは、メインのタイムラインは stop(); によりフレーム2で止まっていますから、フェードインの終了後、_root.play(); でタイムラインを動かしています。 back_image から見ますと、メインのタイムラインは他人のものです。 他の階層が持っているものを参照したり他のタイムラインを操作する時は、その対象を表すターゲットパスが必要です。 ターゲットパスは面倒なものに見えますが、このおかげで、同じシンボルから作られた複数のインスタンスが全く同名のインスタンスや関数などを持っていたとしても、別のものとして区別して個別に操作できるのです。 ActionScript では大切な考え方ですから、解説書や入門サイト等で研究してみてください。
お礼
DPE 様 ありがとうございました。できました!!感謝です。 まだ歴1年も満たないのですが,ますますはまってしまいそうです。 参考書は一冊持っているのですが,基礎からしっかり学んでいこうと思っています。 丁寧なご説明もまだ,半分も理解できませんが,手持ちの参考書よりずっとわかりやすい説明です。 また,ご教授ください。ありがとうございました。
お礼
早速の回答ありがとうございます!!! おかげさまで,できました。 ただ,これはご説明にもあったとおりFlash Player 7以上でないと再生できないようです。 ひとつバージョンを落としてFLASH Player6で再生できるようにはできないのでしょうか。