ちょっと先の未来クイズ第4問

はじめまして。
FlashMX2004でのスクリプトを教えていただく質問いたします。

画像が10枚以下のようにあるとします。

ABCDEFGHIJ・・・・

これをAB、CD、EF、GH、IJの2枚単位でランダムに表示することは可能でしょうか?

使用目的は、単語の暗記など。
日本語→英語、日本語→英語、日本語→英語・・・という感じです。
※わかりづらい説明で申し訳ありません。

どうぞよろしくお願い致します。

A 回答 (3件)

#2です。



> 思ったよりも難しい仕様になるようで、ちょっとビビッていますw

こちらは最初からかなりビビッていますよ(;^_^ )。
【犬】【Dog】~【机】【Desk】は
例えば,中学英語の 中1の Lessson1 みたいなものに当てはまるわけでしょう(勝手な想像)。
これだけで終わるはずがない。
Lesson1 の次は  Lesson2  Lesson3 ……
他の Lesson に行くたびに問題数は変わるのでスクリプトは汎用的に使い回しができるようにしなければいけない。
などと考えますし,
ファイル管理のデータベースを先に作って,そのデータベースから問題を抽出すべきではないか?
などなど。
「問題を出題する」みたいな内容は壮大なシステムをどうしても想像してしまいます。
全体が変わると,細部のスクリプトも当然変わって来ます。
まぁ,そういう大きな話は置いておいて,

>> 1問目に【犬】→【Dog】と1秒間隔くらいで画像が切り替わった後、
>> 2問目に【リンゴ】→【Apple】
>> 3問目に【本】→【Book】という感じでランダムに変わるもの

ですね。
loadMovie を仮に使った場合,ロードする場所は1つで良いということになります。

でも,やはり1問目と○問目は重複して良いのかどうかがわかりません。
5問目までで終了するものでしたら,重複は許されないと思いますし,
ずーっと繰り返すのであれば,どうあがいても絶対に重複しますから,単なるランダム表示で良くなります。

しかし補足要求をしても,たぶん答えにくいと思います。
実際に作ってみて,「やっぱりループにしよう」とか「ここはこう変えた方が良い」とかが考えられます。

なので,これまた簡単な例を書いておきます。
参考にしてみてください。
2画像1セットの単なるランダム表示で,基本的にはループするものです。

最初はスクリプトですべてしようかと思いましたが,
【犬】→【Dog】と1秒間隔くらいで画像が切り替わった後,の "後"
1問目から2問目へ進むときは自動なのか,ボタンをクリックするのかもわかりませんし,
時間を空けて自動で進むにしても何秒かわからないので,タイムラインを利用してみました。
これだとスクリプトなど理解しなくてもカスタマイズ可能です。

ベースは#1の2つ目で,これをタイムラインに分けて実行するものです。
少なくとも下記のように3レイヤーあったほうが良いです。

          1         13        ?
レイヤー3 筆・・|○|○     []|○|      []|○| ←スクリプトレイヤー
レイヤー2 筆・・|●                  []| ←ボタンレイヤー
レイヤー1 筆・・|○|●                 []| ←MCレイヤー

まずMCレイヤーのフレーム2以降に
loadMC というインスタンス名のMC(ムービークリップ)を用意します。
このMCは小さい四角とか,中に何も入っていない空のムービークリップで良いです。
ステージの左上の方に配置して,一度ロードさせてみて,場所をてきとうな所に調節すれば良いと思います。

次に,「スタート」ボタンを用意します。
複雑なスクリプトはすべてタイムラインでしますから,このボタンには
------------------------
on (release) {
this.gotoAndPlay(2);
}
------------------------
と書くだけで良いです。
2フレームに進みます。

スクリプレイヤーのフレーム1のタイムラインには
------------------------
this.stop();
------------------------
と書いて,そのムービーを止めておきます。

スクリプレイヤーのフレーム2をキーフレームにして
そのタイムラインには
------------------------
ransu = Math.floor(Math.random()*5)*2+1;
this.loadMC.loadMovie(ransu+".jpg");
------------------------
で,ransu にランダムな奇数を得て,
その ransu の数字のJPEGを loadMC に読み込ませます。

フレームレートを12fptに設定してある場合は1秒間に12フレーム進みますから,
スクリプレイヤーのフレーム13あたりをキーフレームにして,そこには
------------------------
this.loadMC.loadMovie(ransu+1+".jpg");
------------------------
と書きます。
これで,もし,フレーム2 で 1.jpg が読み込まれたら フレーム13では 2.jpg が読み込まれますよね。

最終フレームには
------------------------
this.gotoAndPlay(2);
------------------------
と書いてください。
これで,フレーム2に自動的に戻り,再び乱数が計算されて,その乱数通りにフレーム2とフレーム13で画像が読み込まれます。
もし,1問1問止める場合は,ここを
------------------------
this.gotoAndStop(1);
------------------------
にするか,何も書かなければ,1フレームに戻ってストップします。
時間調節はフレームを挿入したり削除すればできます。

途中でループを止めたいときは,
ボタンレイヤーに「ストップ」ボタンを作って,
------------------------
on (release) {
this.stop();
}
------------------------
で止めてください。

このスクリプトは,あえて this という相対パスを使っています。
メインアニメーションは別に流れていて,ステージの一部で,ランダムに切り替わるこの部分がある場合はムービークリップ内で以上のようなものを作ってください。
相対パスを使っているので, _root でも,ムービークリップ内でも同じスクリプトで動作すると思います。

とりあえず,こんな感じのを作ってみて,
いろいろ試行錯誤しながら作っていくしかないでしょう。
実際にいろいろ作ってみないと,やりたい具体的なことも見つからないと思います。


///////////////////////////////////////////////////////////////////

---注---

#2の説明も,この説明もほとんど loadMovie で説明していますが loadMovie にこだわる必要はありません。

loadMovie を使っている理由は,
テキストだけでの説明が簡単だというのもありますが

1 Flash自体を書き替えなくても,
  外部画像さえ変えれば違う問題に変えられる(最重要)
2 本体のFlashが軽くなる
3 スクリプトが比較的簡単になる(unloadしなくて良い)

などです。
逆にデメリットもあります。

1 ファイル数が増えるのでファイルの管理が面倒
2 素早い画像切り替えには対応できない
3 画像の種類が限られる(JPEG または SWF)
  ※書き忘れていましたが,
   JPEGでも,プログレッシブJPEGはloadできません。

などです。

画像の表示方法は他にも,
最初からステージ上に時間軸に並べて置いて,ランダムで gotoAndPlay(); する方法も考えられます。

          ↓ランダムに飛ばすスクリプト
レイヤー3 筆・・|○         []|○|  ---  []|○| 
レイヤー1 筆・・|○|●   []|●|   []|●|  ---  []|●|   []|●|   []|
            A    B      C         I      J

A や C や E や G や I が表示される前にランダムで他のフレームに飛ぶ。
ランダムと言っても当然ルールはあります。
でも, Math.floor(Math.random()* X);
を使ってランダムな整数を得て,そこから分岐すれば,
A または C または E または G または I が表示される最初のフレームにランダムに飛ばすことはできますよね。

また,
あらかじめ全ての画像をムービークリップ内に作って,
そのムービークリップごと _visible = true; や _visible = false; で表示非表示を切り換える方法もあります。
「ActionScript 辞書 _visible(可視、不可視)」
http://f-site.org/cont/02refere/pro/_visible.htm

画像をオブジェクトにし,ライブラリでリンケージを設定して,
attachMovie や removeMovieClip で出したり消したりする方法もあります。
「Flash▲Plantation - aqua+Flash - 乱数を扱う」
http://flash.g.hatena.ne.jp/aquatail/20050704


これらを一つ一つ説明すると「"ランダム"で画像を表示する」という本題からはかけはなれてきますので省略しました。
loadMovie以外に他の方法が良い場合もかなりあります。
いろいろやってみてください。
    • good
    • 0
この回答へのお礼

sassakunさん 心から感謝しております。m(_ _)m

まずは増大していくであろう問題数のことは抜きにして
回答を頼りに頑張ります10問くらいずつで練習してみます。

ループさせる作戦でしたので更に助かりました。
参考書よりずっと為になります。

Flashマスターへの道は遠いなぁ・・・

お礼日時:2005/09/27 15:41

#1さんがおっしゃっているように,


Math.floor(Math.random()* X );
でランダムな整数を取得して,その後の処理をするのが普通だと思います。

ランダムな整数に関してはここを参考に↓。
http://www.macromedia.com/jp/support/flash/ts/do …

ランダムは良いのですが,その後どういうように画像を表示させるかがわからないので,
具体的な方法は答えられません。
例は不要なのかもしれませんが具体的な方法例を2つばかり書いておきます。
2つとも,外部に10枚のJPEGを用意して,そのJPEGをランダムに2枚ずつロードするものです。


1 基本的な方法

外部に A.jpg ~ J.jpg を用意し,
loadMC1,loadMC2というインスタンス名のムービークリップに
AB または CD または EF または GH または IJ をランダムに読み込むボタンのスクリプト

--------------------------------
on (release) {

//変数 ransu に 0~4 のランダムな整数を格納
ransu = Math.floor(Math.random()*5);

//ransu が 0 のとき
if (ransu == 0) {
//loadMC1にはA.jpgを読み込む
loadMC1.loadMovie("A.jpg");
//loadMC2にはB.jpgを読み込む
loadMC2.loadMovie("B.jpg");

//以下同様
} else if (ransu == 1) {
loadMC1.loadMovie("C.jpg");
loadMC2.loadMovie("D.jpg");
} else if (ransu == 2) {
loadMC1.loadMovie("E.jpg");
loadMC2.loadMovie("F.jpg");
} else if (ransu == 3) {
loadMC1.loadMovie("G.jpg");
loadMC2.loadMovie("H.jpg");
} else if (ransu == 4) {
loadMC1.loadMovie("I.jpg");
loadMC2.loadMovie("J.jpg");
}
}
--------------------------------


2 少し技巧的な方法

外部に 1.jpg ~ 10.jpg を用意し,
loadMC1,loadMC2というインスタンス名のムービークリップに
1・2 または 3・4 または 5・6 または 7・8 または 9・10 を
ランダムに読み込むボタンのスクリプト
外部のJPEG名を規則正しい数字にしておくとスクリプトは単純になり,
IFによる分岐はなくせます。

--------------------------------
on (release) {

//変数 ransu に 1~9 のランダムな奇数を格納
ransu = Math.floor(Math.random()*5)*2+1;

//各MCに ransu.jpg と ransu+1.jpg を読み込む
loadMC1.loadMovie(ransu+".jpg");
loadMC2.loadMovie(ransu+1+".jpg");
}
--------------------------------

こんな感じでしょうか。
その他も画像の表示の方法はたくさんありますが,
同様に考えればできると思います。


//////////////////////////////////////////////////////////////

とここまで書いて,もう一度ご質問を読み返してみたのですが!!!

>> これをAB、CD、EF、GH、IJの2枚単位で
>> ランダムに表示することは可能でしょうか?

と書かれていますが,これって,単語カード的に1問1問出すのではなくて,

   日 英
問1 E F
問2 A B
問3  I J
問4 G H
問5 C D

↑こんな感じにドリル的というか,問題集的に出すということでしょうか?
つまり1枚もしくは1画面にランダムに全問表示。
これだと考え方が全く変わります。
上で書いた方法は単語カード的に単発で出すものです。
問題集的なものを作ろうとすると,絶対に重複してしまいます。

   日 英
問1 E F
問2 A B
問3 E F
問4 G H
問5 A B

↑こんな感じに。

問題集的なものだとかなり難しくなりますが,一応は考えてみました。
大まかな流れは,
「重複のない順列を作成」→「順列に従いJPEGを読み込む」
というものです。

外部JPEGを 1.jpg~10.jpg 用意し,
ステージ上に
インスタンス名 loadMC1~loadMC10のMCを以下のように配置したとします。

問1 loadMC1 loadMC2
問2 loadMC3 loadMC4
問3 loadMC5 loadMC6
問4 loadMC7 loadMC8
問5 loadMC9 loadMC10

このMCに外部JPEGを読み込ませるボタンのスクリプトは以下のようになります。

※これはインデントを付けないとややこしいので,
 各行のスクリプトの前に全角空白文字をたくさん入れています。
 もしコピペで試される場合は,
 各行の全角空白文字を全て削除してください。

-------------------------------------

on (release) {

   //問数の設定(可変)
   n = 5;
   //ransuという配列を作成
   ransu = new Array();
   //unretsuという配列を作成
   junretsu = new Array();

   //ransuuの1~nの要素(エレメント)に乱数を取得
   for (i=0; i<n; i++) {
      ransu[i] = Math.random();
   }

   //junretsuの要素を初期化
   for (i=0; i<n; i++) {
      junretsu[i] = 0;
   }

   //ransuuの各要素に入った数の
   //大きさの順をjunretsuの要素に並べる(※注↓)
   for (j=0; j<n; j++) {
      for (i=0; i<n; i++) {
         if (ransu[j]>=ransu[i]) {
            junretsu[j] += 1;
         }
      }
   }

   //得られた重複のない順列通りに
   //loadMCにJPEGを読み込む
   for (i=0; i<n; i++) {
      _root["loadMC"+(2*i+1)].loadMovie(junretsu[i]*2-1+".jpg");
      _root["loadMC"+(2*i+2)].loadMovie(junretsu[i]*2+".jpg");
   }
}

-------------------------------------

※注

 配列 ransu には
  (0.0464299493469298,
    0.804838167037815,
      0.113816660828888,
        0.867104816716164,
          0.604140473529696)
 などいう乱数の要素が得られます。

 この各要素を比べて,配列junretsuに
  (1,4,2,5,3)
 という小さいもの順の新たなる要素を得ます。
 すると,この (1,4,2,5,3) は重複しない順列になります。

 なおこの考え方は
 岐阜大学総合情報メディアセンター
 村瀬康一郎さんの100マス計算のExcelの関数
 http://www.crdc.gifu-u.ac.jp/edsoftdb/
 を参考にさせて頂きました(というより発想をパクってます)。
 (Flashは意外とExcelの技法が役に立ちます。
  Excelの方が歴史も古くユーザーも多いので,
  達人の方もFlashよりはるかに多いです。)
 (Flashのスクリプト自体は私が考えたので,
  無理や無駄があると思います。)


もし,作りたい物が単語カードのような単発的なものの場合は,
 ///// より上を参考にしてみてください。
もし,作りたい物が,問題集的に出すもので,
各問いが重複してはならないときは ///// より下を参考にしてみてください。

なお ///// より下のように乱数から重複しない順列を作り出すのではなくて,
(1,2,3,4,5) をランダムにシャッフルして,重複しない順列を得る方法もあります。
その方法は他の方が回答していらっしゃいますので,
良かったらこちらも参考してみてください。↓
上段は教えて!goo 下段はOKWeb で同じものです。

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=881637, …

この回答への補足

sassakunさん どうもありがとうございます!
これほどまでに丁寧な回答がいただけるとは正直思っておらず
感動と驚きで興奮しております。

私の説明不足のせいで、とんだ手間をとらせた上に、
>>こんな感じにドリル的というか,問題集的に出すということでしょうか?
という疑問まで抱かせてしまいました。

締め切ろうと思ったのですが、
念のため補足させて頂きます。


画像10枚というのは
【犬】【Dog】/【猫】【Cat】/【本】【Book】/【リンゴ】【Apple】/【机】【Desk】
こんな感じで、順番に2枚一組の画像があります。

1問目に【犬】→【Dog】と1秒間隔くらいで画像が切り替わった後、
2問目に【リンゴ】→【Apple】
3問目に【本】→【Book】という感じでランダムに変わるものを考えておりました。
思ったよりも難しい仕様になるようで、ちょっとビビッていますw

補足日時:2005/09/27 00:36
    • good
    • 0

こんにちは。



私はMXなので自信がありませんが、
単純に10枚の画像をボタンなどで呼び出すことは可能だと思います。^^
「オブジェクト」「コアオブジェクト」「Math」に
Math.floor();
Math.random();

がMXだとあります。
    • good
    • 1
この回答へのお礼

suzukoさん 回答ありがとうございました!

お礼日時:2005/09/27 00:39

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!