• ベストアンサー

Math.ramdom()を特定回数繰り返す

Math.ramdomについての質問です。 特定回数ランダム処理を行った後に、別のフレームに飛ぶというのは、どのようにやればいいのでしょうか? 分かりづらいと思うので、例を書きます。 ---例---------------------------- 左右のキャラが交互にランダム選択の言葉を掛け合う。それを3回おこなった後に、左右のキャラがフェードアウト。 --------------------------------- こんな感じの動きです。 最初forを使って特定回数処理を行おうかと思ったんですが、forって一気に処理しますよね? ということは、ひとつのランダム処理を行った後に次のランダム処理をする場合には使えないということになりますよね? 分かりづらい説明ですいません。

質問者が選んだベストアンサー

  • ベストアンサー
  • DPE
  • ベストアンサー率85% (666/776)
回答No.2

”ランダムにセリフが変わるアニメ”を3回繰り返した後、キャラクターがフェードアウトする、という作品ではないでしょうか。 このように考えてはいかがでしょう。 例えば、会話のアニメが 20 フレームでできているとします。 アニメの最初のフレームに、セリフを選択するスクリプトを書きます。 変数を1つ用意しておいて、アニメの最後のフレームでカウントをとり、更に、”このカウントが3回未満ならアニメの最初に戻る”というスクリプトを書きます。 あとは会話アニメの先のフレームにキャラがフェードアウトするアニメを作っておけば、会話を3回繰り返し、フェードアウトする作品になります。 会話アニメの最初には会話のパターンを選ぶスクリプトが書かれています。会話アニメの最初に戻った時にはパターンを選ぶスクリプトが実行されるので、会話の内容は毎回ランダムに選択されます。 前回 No.1520309 の質問でも書きました通り、変数で数字や演算を扱う場合は変数の初期化が大切です。 今回は変数でカウントを取りますから、カウント用の変数に最初に0を入れておかないと回数が正しくカウントされず、フレーム間をまたいだループが正常に動かなくなります。 セリフの選択は、配列変数で予めパターンを作っておいて、その番号(インデックス)を選択する方法が簡単です。 変数の初期化や配列変数の準備などは最初の1回だけ実行すれば充分ですから、初期化するスクリプト専用のフレームを作ると便利です。 まとめますと、次のような構成になります。 仮に、会話アニメは 20 フレームで作るとします。  フレーム1  :初期設定  フレーム2~21:会話アニメ  フレーム22~ :キャラのフェードアウト スクリプトはフレーム1・2・ 21 に書きます。 (↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください)  ●フレーム1  //会話の回数を保持  cnt = 0;  //会話のパターンを管理  pattern = 0;  //セリフを設定  word_a = new Array( "○○○" , "□□□" , "△△△" );  word_b = new Array( "●●●" , "■■■" , "▲▲▲" );  ●フレーム2  //会話のパターンを選ぶ  pattern = Math.floor( Math.random() * ( 2 - 0 + 1 ) ) + 0;  //セリフを取り出す  a = word_a[ pattern ];  b = word_b[ pattern ];  ●フレーム21  //会話した回数を更新  cnt++;  //会話の回数が3回未満であれば、セリフの選択・会話アニメに戻る  //それ以外は先に進む  if( cnt < 3 )  {   gotoAndPlay( 2 );  } フレーム1では、必要な変数の初期設定をまとめて行います。 仮にキャラAとBがいるとして、Aのセリフは word_a 、Bのセリフは word_b という配列変数に入れてあります。 会話だと、例えばAが○○○と言った時にBが▲▲▲といったトンチンカンな言葉を返しては変でしょうから、word_a と word_b はそれぞれ対応するようにセリフを入れています。 セリフが長くて配列変数に入れにくい時は、word_a1 = "・・・"; というように固定の名前+通し番号で変数名を付けておくと、配列変数と同じようなことができます。 Aの言葉に対してBが適当なことを言っても構わないのなら、2つの配列に対応させてセリフを用意しなくても構いませんし、セリフの種類も同じ数にする必要もありません。 また、乱数はAとBのセリフをそれぞれ決めるために2種類選ぶことになるかと思います。 このあたりは、作品に合わせて適宜変更してください。 フレーム2では、乱数を使ってセリフを選択します。 任意の範囲内で乱数を作る方法については、#1の方が挙げていらっしゃるページをご参考になさってください。 乱数で何を選ぶかというと、配列のインデックス番号をランダムに選びます。 上記のスクリプトでは、セリフが3パターン、つまり、配列変数の中に変数は3つ作られています。インデックスでいうと0番から2番までの変数があります。 この中の1つを選ぶには0~2の間で乱数を作り、できた乱数で配列変数を参照すればいいことになります。 スクリプトの中では計算式が分かるように書きましたが、  pattern = Math.floor( Math.random() * 3 ); としても同じことです。 できた乱数をもとにセリフを格納した配列変数を参照して、セリフを決めます。 上記のスクリプトではとりあえず、キャラAのセリフを a 、キャラBのセリフを b という変数に入れています。ダイナミックテキストで変数の内容を表示するなどして、利用してください。 フレーム 21 のスクリプトが、会話アニメを繰り返すための肝となる部分です。 for 文は  for( i = 0 ; i < 3 ; i++ ) 単に3回繰り返すだけなら、何もこんなややこしい書き方をしなくてもいいような気がしますが、これにはちゃんと理由があります。 for 文の動作原理は、2番目のパラメータとして与えられた条件が成立している間だけループを継続するというものです。 上記の for は”3回繰り返す”ではなく、正式には、” i が3未満の間( i < 3 が成立している間)ループを継続する”という意味になります。 i の値を0からスタートし、1回の処理が終了するごとに i のカウントを1つ増やして、与えられた条件を判断します。 ループを繰り返すと i の値は1ずつ増えます。やがて i は3以上になり、i < 3 の条件が不成立になります。この時点でループが打ち切られます。 つまり、i < 3 が成り立つのは i が0・1・2の時だけなので、結果的に処理が3回繰り返されるというだけです。 for 文は1つのフレーム内で繰り返し処理を行うものです。20 フレームからできたアニメを3回繰り返すためには利用できません。 そこで、for 文と同じ仕組みを変数とフレームアクションを使って再現し、複数のフレームにわたるループを作ります。 ループカウンタとして cnt という変数を用意し、会話アニメを繰り返した数を記録します。初期値は0です。 会話アニメが終わるたびにカウントを1増やし、これが3未満である間、アニメを繰り返すようにします。 cnt は0から始まり、カウントは1ずつ増えますから、cnt の値が3未満の間とは、cnt に0・1・2が入っている3回限りということになります。 いくつかのフレームをまたいではいますが、考え方は for のループと全く同じです。 カウントを取って繰り返す方法や、配列変数にデータを用意してランダムに選択するといった手法はいろいろな局面に応用できます。 今回はセリフを配列変数に入れてランダムに選択しましたが、アニメを何パターンか作っておき、各アニメの開始フレームを配列変数で管理すると、再生するアニメそのものをランダムに選ぶこともできます。 以前、似たような作例を紹介したことがありますので、よろしければご参照ください。 #2で、紹介しております。  ・Flashで線がうねって波みたいに?!   http://okweb.jp/kotaeru.php3?q=816038 タイムライン上に用意しておいたアニメ(上記の例では3パターン)をランダムに選択し、再生する・・・というのを無制限に繰り返す方法です。 アニメを選択するたびにカウントを取り、3未満であれば次のアニメを選択、それ以外なら先に進むようにスクリプトを書くと、アニメを繰り返す回数を指定できます。 ちなみに、上記の例で tbl_ref に乱数を入れるのではなく、tbl_ref++; として単純に加算していくと、ある決まった順序(配列変数に書かれた順序通り)でアニメを再生できます。

coder
質問者

お礼

DPEさんのご指導のお陰で無事再生させることができました。 それにしてもDPEさんはすごいですね、ほんとに。 尊敬です。

coder
質問者

補足

はい、DPEさんのおっしゃる通りのアニメーションです。 なんかものすごい説明不足で申し訳ないです。 しかも前回に続き、今回もこんなに詳しく説明していただき、ありがとうございました。 何となく分かったので、取りあえずこれから挑戦してみます。

その他の回答 (1)

noname#35109
noname#35109
回答No.1

いったい何についてのご質問なのかがよくわかりませんよ。 題名は,random関数に関しての質問で,本文はforの質問になっています。 乱数で,その後を変えたい場合は, 乱数が整数の方が,処理しやすいと思います。 これには,Math.random() だけでは不十分で, Math.floor(Math.random()*10) などで,整数化しておく必要があります。 http://www.macromedia.com/jp/support/flash/ts/documents/fl0173.html を参照のこと。 次ですが, >> forを使って特定回数処理を行おうかと思ったんですが、 >> forって一気に処理しますよね? forは一気に処理しますが,forを使っても使わなくても一気に処理します。 たとえば,3回繰り返し。 a = 乱数; もし a が1だったら,Aは「こんにちは」と言う  もしくは a が2だったら,Aは「さようですか」と言う   もしくは a が3だったら,Aは「いやはやなさけない…」と言う    それ以外,Aは「バイバイ」と言う b = 乱数; もし b が1だったら,Bは「こんばんは」と言う  もしくは b が2だったら,Bは「それはびっくり」と言う   もしくは b が3だったら,Bは「どうしよう…」と言う    それ以外,Bは「バイバイ」と言う a = 乱数; もし a が1だったら,Aは「こんにちは」と言う  もしくは a が2だったら,Aは「さようですか」と言う   もしくは a が3だったら,Aは「いやはやなさけない…」と言う    それ以外,Aは「バイバイ」と言う b = 乱数; もし b が1だったら,Bは「こんばんは」と言う  もしくは b が2だったら,Bは「それはびっくり」と言う   もしくは b が3だったら,Bは「どうしよう…」と言う    それ以外,Bは「バイバイ」と言う a = 乱数; もし a が1だったら,Aは「こんにちは」と言う  もしくは a が2だったら,Aは「さようですか」と言う   もしくは a が3だったら,Aは「いやはやなさけない…」と言う    それ以外,Aは「バイバイ」と言う b = 乱数; もし b が1だったら,Bは「こんばんは」と言う  もしくは b が2だったら,Bは「それはびっくり」と言う   もしくは b が3だったら,Bは「どうしよう…」と言う    それ以外,Bは「バイバイ」と言う forを使っていませんが,コレくらいのスクリプトだったら, 0.00001秒? くらいで済んでしまいます。 人間が何かしゃべったところを見る間もなく,会話は終わります。 だから, 問題はforを使うとか使わないではないと思います。 いったいどういうタイミングで会話がさせたいのか, 時間制御か,ボタンクリックか。 それともアニメーションと同期か。 その辺のところをちゃんと考えて,アニメーションをさせないと,できないと思います。 それと,予感ですが… 具体的にどういうときにどういうことがしたいのか考えられたとしても ---例---------------------------- 左右のキャラが交互にランダム選択の言葉を掛け合う。 それを3回おこなった後に、左右のキャラがフェードアウト。 --------------------------------- の部分を説明できる自信は全くありません。 それで良ければ,補足してください。 他の方が答えてくださるかもしれませんし, わかることでしたら,時間はかかるかもしれませんが,答えるつもりはあります。 まったく自信はなしですが。

coder
質問者

補足

ものすごい説明不足で申し訳ございません。 そうですよね、イベントが起こるタイミングとかそういうものを全く説明してませんね。 【ムービー説明】 1.イベントは左右にキャラクターがいるフレームが再生されたら、発生します。 2.会話は左の人が何かしゃべって、それに対して右の人が何かをしゃべる。この時に話す会話の内容はいくつかあるパターンの中からrandom選択です。 3.ひとつの会話のパターンのアニメーションが終わったら続いて、別のパターンの会話のアニメーションを始める。これを3回繰り返した後に、会話を終了し先のフレームに進む。 こんな感じのムービーです。 ランダム選択のやり方や、さらに配列を組んで同じものが選択されないやり方は分かるんです。 ただ、ランダム選択した会話のアニメーションを「3回だけ繰り返す」というやり方が分からなかったんです。 そこで、最初にfor分を使って3回繰り返すのを考えたのですが、forは1Frでの繰り返し処理で、特定の長さを持つアニメーションの繰り返し処理は出来ないですよね? そういった疑問の質問をさせていただきました。 ものすごく説明不足なのに、こんなにどういう情報が必要なのかというのを教えてくださってありがとうございます。

関連するQ&A

専門家に質問してみよう