- ベストアンサー
Flash重複しないムービー再生とその後の処理について
- Flash MX 2004で重複しないようにランダムにムービーを再生し、その後の処理について相談です。
- 現在の実装ではランダムな数を取得して各フレームに配置し、再生しますが、重複してしまう問題やループする問題があります。
- 重複しないように全ムービーを再生後、次のフレームに進む処理の実装方法について教えてください。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
現状を活かすのでしたら、次のように考えてはいかがでしょう。 重複しないランダムな並びを得るには、配列変数を使うと簡単です。 配列変数に目的の数値や何かの値を入れてシャッフルすれば、重複のないランダムな並びになります。 今回の件で言いますと、配列変数にフレームの番号( 2 ~ 10 )かムービークリップの番号( 1 ~ 9 )を入れてランダムに並べ替えると、重複することなくランダムに再生できる順序が決まります。 あとは、この順序に従ってフレームを再生していきます。 配列変数に書かれている通りに再生するには、配列変数の位置(インデックス)を管理する変数を1つ作り、ムービークリップの再生が終了するたびにこの変数の値を + 1 しながら配列変数から値を取得して、gotoAndStop でフレームを移動します。 この変数の値が配列変数の要素数の最後に達したら、ランダム再生の終了、と判断することができます。 配列変数でランダムな並びを作成する処理(フレームの再生順番を決める処理)は最初の1度だけでいいのですが、次に再生するフレームに移動したり、ランダム再生が全て終了したかどうかの判定などはムービークリップの再生が終了するたびに行わなければなりません。 メインのタイムラインのフレーム1でこれらの処理を全て済ませる場合は、変数が未定義だった時に返ってくる” undefined ”という値を利用して、最初の1度だけ行う処理と繰り返し行う処理に分けることができます。 もっとも、スクリプトを2フレームに分け、フレーム1に最初の1度だけ実行したいスクリプト、フレーム2にランダム再生が終了するまで繰り返すスクリプトを記述し、ムービークリップからはフレーム2に戻るようにする方法もあります。 今回はとりあえず、これまでにできあがっている部分を活かすということで、フレーム1で全てを済ませる作例をご紹介します。 ---------------------------------------------------------- スクリプトの一例です。 メインのタイムラインのフレーム 2 ~ 10 にムービークリップがあり、これらのムービークリップの最後のフレームに _root.gotoAndStop( 1 ); が書かれているとします。 フレーム 2 ~ 10 を重複なくランダムに再生し、最後にフレーム 11 に移動するスクリプトは、大体、次のようになります。 このスクリプトは、メインのタイムラインのフレーム 1 に設定してください。 (↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください。このまま使うとシンタックスエラーになります) /********************************************************/ /************** ランダム再生の最初に1度だけ行う処理 **************/ if( tbl_ref == undefined ) { //フレーム番号のテーブル frame_tbl = new Array(); //テーブルの参照位置を保持 tbl_ref = 0; //ランダム再生するフレームの総数とシャッフルの回数 frames = 9; shuffle = 30; //テーブルにフレームの番号を格納 //スクリプトのフレーム(=このフレーム)の分だけずらして格納しておく for( i = 1 ; i <= frames ; i++ ) { frame_tbl[ i - 1 ] = i + 1; } //テーブル内の値を指定の回数だけシャッフル for( i = 0 ; i < shuffle ; i++ ) { //要素を2つ、ランダムに選ぶ index1 = Math.floor( Math.random() * frame_tbl.length ); index2 = Math.floor( Math.random() * frame_tbl.length ); //2つの値を入れ替える temp = frame_tbl[ index1 ]; frame_tbl[ index1 ] = frame_tbl[ index2 ]; frame_tbl[ index2 ] = temp; } //最初のムービークリップがあるフレームを再生 gotoAndStop( frame_tbl[ 0 ] ); } /************** 2回目以降の処理 **************/ else { //テーブルの参照位置を更新 tbl_ref++; //終了判定:次に再生するムービークリップはあるか? //ある場合はそのフレームに移動 if( tbl_ref < frame_tbl.length ) { gotoAndStop( frame_tbl[ tbl_ref ] ); } //ない場合は先のアニメに進んで終了 else { delete tbl_ref; gotoAndPlay( 11 ); } } /********************************************************/ 再生順番を決める処理や配列変数のインデックス番号を管理する変数の初期化などは、undefined を利用して、ランダム再生の前に1度だけ行います。 どの変数を判断に使ってもいいのですが、上記のスクリプトではとりあえず、配列変数のインデックス番号を管理する変数” tbl_ref ”が未定義だった場合にこれらの初期化を行っています。 1件のムービークリップの再生が終了してフレーム 1 に戻ってきた場合は、変数 tbl_ref が既に定義されているため if 文の条件は不成立で、else 以下の処理(次のフレームの再生と終了判定)が行われるようになります。 なお、全てのムービークリップの再生が終了した時には、delete アクションで変数 tbl_ref を削除しています。 これにより、例えばフレーム 11 から続くアニメの最後からリプレイボタンなどで最初に戻れるような作品でも、変数 tbl_ref が undefined になるので、再度ランダムな再生順序を作成するなどの初期化処理が実行されます。 ある決まった順序や法則をもとにデータを並べて表を見るように使うデータ構造を、”テーブル”といいます。 今回はフレームの番号( 2 ~ 10 )をテーブルにし、予めランダムな順序に並べ替えたものを見ながら順番に再生していくことで、フレーム 2 ~ 10 までを重複することなくランダムに再生します。 配列変数内の値をランダムに並べ替えるにはいろいろな方法がありますが、上記のスクリプトでは簡単なところで、配列変数の要素をランダムに2つ選び出して入れ替える、という処理を数回繰り返す方法を使っています。 入れ替える回数は、変数” shuffle ”の値を書き換えていただくと変更できます。 回数を多くするほどいいというわけでもありませんが、過不足があるようでしたら適宜変更してください。 ---------------------------------------------------------- ちなみに、いくつかのムービークリップをランダムに再生した後で先に進むには、1つのフレームにムービークリップを全て配置しておく方法もあります。 基本的には、今再生するものだけを表示して残りは非表示にし、再生が終了するたびに表示するものを取り換えていきます。 1つのムービークリップの再生が終了したかどうかは、再生されているフレームを管理している _currentframe プロパティと、ムービークリップの総フレーム数を保持する _totalframes プロパティを比較することで検出できます。 配列変数を使ってランダムに再生する順序を作成する点は同じですが、この方法の場合は、テーブルにムービークリップの参照を入れておくと便利です。 機会がありましたら、こちらの作例も研究してみてください。
お礼
ご回答いただき、本当にありがとうございました。 質問には1フレーム目からとさせていただきましたが、実際にはその前にもフレームが存在していましたので、ご回答のScriptを当てはめて“shuffle”や、ここぞと思える箇所の値を調整しながら何度かトライしていました。しかし再生が4つで止まったり8つで止まったり(おしい!)などして、なかなかパーフェクトが出ません。 苦肉の策でランダム再生より前のムービーと今回のランダム再生部分をシーン分けして、“シーン2”のみで1フレーム目から作成してみました。(まるごとコピーさせていただきました。。。) すると、すんなりパーフェクト再生です。次のフレームまでばっちりでした。 おかげさまで、今回はここから先へすすむ事ができます。しかしちょっと悔しいので(笑)落ち着いたらテーブルの概念もふまえてもう一度取り組んでみます。 ありがとうございました。助かりました。