- 締切済み
createTextFieldを使う際にインスタンス名を動的に変える方法について
お世話になります。 my_mc.createTextField("Menu_TXT",2,200,150,30,12) 通常、上記のようなスクリプトを書くとmy_mcにMenu_TXTというテキストフィールドを配置するのですが、これをMenu_TXT0~Menu_TXT10まで作成したい場合、for文を使って構築したいと思っています。 for文の構成は分かるのですが、インスタンス名を動的に変えたい場合の記述法が分かりません。例えば"Menu_TXT"+iとするとエラーですよね!?これをうまく書く方法はないでしょうか?
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- DPE
- ベストアンサー率85% (666/776)
#1です。 [ ] 演算子では、テキストフィールドやムービークリップなどのインスタンスだけでなく、変数の参照にも変換できます。 仮に、ステージにムービークリップ” Menu_MC ”があり、その中にムービークリップ” Data_MC ”があって、Data_MC にテキストファイル” command.txt ”から変数を読み込むとします。 command.txt の内容は menu0=たたかう&menu1=まほう&menu2=どうぐ&menu3=ぼうぎょ&menu4=にげる だとします。 Menu_MC にスクリプトでテキストフィールドを作り、読み込んだ変数を連結して表示するスクリプトは、次のようになります。 このスクリプトは、メインのタイムラインのフレームに設定してください。 (↓各行頭に全角のスペースが入っています。コピーする際はご注意ください) //Menu_MCに空のテキストフィールドを作る Menu_MC.createTextField( "Menu_TXT" , 0 , 0 , 0 , 150 , 100 ); //Data_MCに外部テキストファイルからShift-JISで変数を読み込む System.useCodepage = true; Menu_MC.Data_MC.loadVariables( "command.txt" ); //データ読み込み終了後、テキストフィールドに出力 Menu_MC.Data_MC.onData = function() { //全ての変数を連結して表示 for( i = 0 ; i <= 4 ; i++ ) { Menu_MC.Menu_TXT.text += this[ "menu" + i ] + "\n"; } }; 実行すると、Menu_MC の中に” Menu_TXT ”というインスタンス名のテキストフィールドが作られて、 たたかう まほう どうぐ ぼうぎょ にげる ↑このように文字列が出力されます。 表示される内容は、テキストファイルから読み込んだ変数 menu0 ~ 4 を、それぞれの末尾に改行コード(” \n ”)を追加しながら連結したものです。 *********************** テキストファイルから読み込む方法・読み込みの完了を待つ方法・改行コードの問題などは、今回は本題ではないので詳しくは触れませんが。 外部から読み込んだものを利用する時は、必ず、読み込みが完了するまで待ってから次の処理に進むようにしましょう。 MovieClip クラス( Flash MX 以前はオブジェクト)の loadVariables メソッドで読み込んだ場合は、data イベントを利用して読み込みの完了を検出できます。 Flash Player 6 以降からは、onData = function という書き方で、data イベント発生時(読み込みが完了した時)に実行する処理を定義できるようになりました。 onData に登録される関数の中での this は、onData イベントハンドラの持ち主を指します。 つまり、上記のスクリプトの Menu_MC.Menu_TXT.text += this[ "menu" + i ] + "\n"; ↑この箇所の this は、Menu_MC 内にある Data_MC を指しています。 Data_MC の loadVariables メソッドで読み込むと、読み込まれた変数 menu0 ~ 4 は Data_MC のものになりますから、この場合は this を使って変数を指定することができます。 なお、読み込みに関しては LoadVars クラスを使う方法もあります。 *********************** 今回のポイントは this[ "menu" + i ] この部分です。 menu0 ~ 4 は変数ですが、テキストフィールドやムービークリップのインスタンスと同様に、[ ] 演算子で文字列を参照に変換することで変数を指定できます。 実は、文字列を参照に変換して関数を呼び出すこともできます。 Test1 と Test2 という関数を定義して for( i = 1 ; i <= 2 ; i++ ) { this[ "Test" + i ](); } とすれば、Test1 に続いて Test2 が呼び出されます。 先のスクリプトでの変数 menu0 ~ 4 も、上記の関数の例でも、変数や関数は既に存在しているものでした。 [ ] 演算子で変換することで、文字列で指定して変数やオブジェクトを動的に作ることもできます。 例えば for( i = 1 ; i <= 2 ; i++ ) { this[ "no" + i ] = i; } ↑このスクリプトでは、no1 と no2 という変数が作成され、それぞれの値が 1 と 2 になります。 古い Flash Player では eval 関数でも似たようなことができますが、Flash Player 6 以降は式の左辺に eval 関数を使うとエラーになります。 これが、eval 関数を使う手法が旧式とされる理由でもあります。 ある階層の中にある対象を指定することもできますが、その際は、1つの階層の指定につき1組の [ ] でくくります。 eval 関数では eval( "Menu_MC.Data_MC.menu" + i ) と、階層を” . ”で区切り、ひとまとめにして指定できましたが、[ ] の中では” . ”が階層の区切りの役目を果たしません。 [ ] 演算子を使う時は this[ "Menu_MC" ][ "Data_MC" ][ "menu" + i ] このように、1階層分の文字列を1組の [ ] でくくります。 他にも、Menu_MC.Data_MC[ "menu" + i ] というように、最初から参照になっているものと組み合わせるなど、様々な使い方があります。 ある書き方だけが正しくて他は間違いというわけではないので、いろいろな使い方を研究してみてください。
- DPE
- ベストアンサー率85% (666/776)
createTextField で空っぽのテキストフィールドを作成する時に指定する名前は、ただの文字列です。 ですから、for ループの中で "Menu_TXT" + i と書いてもエラーにはなりませんし、テキストフィールドも正常に作成されます。 しかし、できたテキストフィールドの書式を決めたり、表示させる内容を変更する時は、作られたテキストフィールドの参照を指定しなければなりません。 ActionScript では、文字列を参照に変換することができます。 この変換には eval 関数か配列演算子 [ ] を利用しますが、eval 関数を使用する方法は旧式です。 特に Flash Player 6 以降は eval 関数の用法に制限がありますので、配列演算子 [ ] を使うようにしましょう。 例えば、ムービークリップ my_mc の中にテキストフィールド” Menu_Text ”がある場合、文字列からこのテキストフィールドを操作する時は my_mc[ "Menu_TXT" ].text = "サンプル"; というように書きます。 [ ] の中には文字列を入れますので、文字列の連結も利用できます。 for ループの中で my_mc[ "Menu_TXT" + i ].text = "サンプル"; ↑このように使うと、テキストフィールドの名前を” Menu_TXT ”+連番で付けておけば、該当する番号のテキストフィールドを次々に操作することができます。 ------------------------------------------------------------ 仮に、空っぽのムービークリップ” my_mc ”があるとします。 このムービークリップ内にテキストフィールド Menu_TXT0 ~ 4 (外枠あり)を作り、その中に決まったテキストを表示するスクリプトは、次のようになります。 このスクリプトは、my_mc があるタイムラインのフレームに設定してください。 (↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください) //テキストフィールドに表示するテキストのリスト item_list = new Array(); item_list = [ "トップ" , "製品情報" , "サポート" ,"会社情報" , "お問い合わせ" ]; //テキストフィールドの書式 format = new TextFormat(); format.font = "_等幅"; format.size = 15; format.align = "center"; for( i = 0 ; i < 5 ; i++ ) { //空のテキストフィールドを作成 my_mc.createTextField( "Menu_TXT" + i , i , 0 , 20 * i , 150 , 20 ); //外枠を付ける my_mc[ "Menu_TXT" + i ].border = true; //配列変数を見て、テキストフィールドにテキストを表示 my_mc[ "Menu_TXT" + i ].text = item_list[ i ]; //書式を適用する my_mc[ "Menu_TXT" + i ].setTextFormat( format ); } ********************** テキストフィールドに表示する内容は、各テキストフィールドが持っている text というプロパティで管理されています。 このプロパティを書き換えることで、テキストフィールドの表示内容を変更できます。 上記の作例では、表示するテキストを予め配列変数に入れておいて、作ったテキストフィールドに順次表示するようにしています。 配列変数は、同じ名前で管理番号(インデックス)だけが違う変数が集まったものです。 配列変数のインデックスは 0 からの連番になっているので、テキストフィールドを作る for のループも 0 から始めると、テキストフィールドの番号と配列変数のインデックスがズレなくなります。 [ ] で文字列を参照に変換する手法は、テキストフィールドだけでなく、ムービークリップやボタン、ActionScript でいうところのオブジェクト(変数のようなもの)にも使えます。 このサイトでもいろいろな使い方が紹介されていますので、機会がありましたら研究してみてください。 ********************** なお、Flash Player 8 (作成ツールは Flash 8 )からは、createTextField メソッドは作成したテキストフィールドの参照を返してくるようになりました。 上記のスクリプトでは、テキストフィールドの表示内容や書式を決める際にいちいち [ ] 演算子で文字列を参照に変換しているのですが、 //空のテキストフィールドを作成 txt_obj = my_mc.createTextField( "Menu_TXT" + i , i , 0 , 20 * i , 150 , 20 ); ↑このように、変数に createTextField の戻り値を保存しておくと便利です。 例えば、先の例は Flash Player 8 以降でパブリッシュする場合は for( i = 0 ; i < 5 ; i++ ) { //空のテキストフィールドを作成 txt_obj = my_mc.createTextField( "Menu_TXT" + i , i , 0 , 20 * i , 150 , 20 ); //配列変数を見て、テキストフィールドにテキストを表示 txt_obj.text = item_list[ i ]; } と、スッキリと書くこともできます。 繰り返しますが、この仕様は Flash Player 8 で追加されたものです。 Flash Player 7 以前の createTextFiled メソッドは戻り値がありません。 Flash 8 以降をお使いでも、古いバージョンでパブリッシュする時はご注意ください。
補足
有難うございます。 補足というか、インスタンスでの取り扱いはよく分かったのですが、テキストフィールド(ダイナミックテキスト)の変数の取り扱いも教えてください。このスレッドでお願いすることではないのでしょうが、少し似た疑問ですのでご了承ください。 ステージに配置されたMenu_MCインスタンスに、createTextFieldにてText_TXTというテキストフィールドを作成します。この時、このテキストフィールドの変数はmenu0とします。そして、これとは別にData_MCという空ムービークリップをMenu_MCと同じ階層に配置します。 <Data_MCのAS(ムービークリップアクション)> onClipEvent (load) { loadVariables("command.txt", this); } <Menu_MCのAS(フレームアクション)> Menu_MC.Menu_TXT.text=Data_MC.menu0 これで、外部テキストからmenu0のデータを動的テキストフィールドに表示することができました。 質問は、Menu_MC.Menu_TXT.text=Data_MC.menu0のmenu0の部分を動的に変化させたいのです。インスタンスではeval("インスタンス名"+ 変化値)等で対応できますが、テキストフィールドの動的なコーディングはできるのでしょうか?menu + i(変化する値)みたいな・・・
お礼
ありがとうございます^^ 文字列を参照に変換して関数を呼び出す方法、とても良いですね! これから役に立てていこうと思います。 本当に助かりました。