- ベストアンサー
外部テキストで画像名を指定してFlashでLoaderを使用する方法
- Flash初心者の方向けに、FlashでLoaderを使用して外部テキストで画像名を指定し、scaleContent=trueで画像を読み込む方法を解説します。
- 具体的な手順として、FlashのmovieclipにLoaderを設置し、外部テキストに画像名を指定します。次に、指定した画像名をもとに画像を読み込み、scaleContent=trueで表示する処理を行います。
- しかし、実際に試してみたところ、画像が表示されずに行き詰まってしまいました。.loadMovie()のカッコ内の値を変数にする方法や、scaleContent=trueで表示する方法についてアドバイスをいただきたいです。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
私の環境では、Windows プロジェクタ( exe 形式)で書き出しても、swf ファイルを直接立ち上げても、正常に表示できていますが、、、? ちなみに当方の環境は、Windows XP( SP2 は未導入)、Flash MX 2004 は Ver 7.2 にアップデート済みです。 HTML ページに配置してブラウザで再生する場合も、プロジェクタ形式で書き出す場合も、基本的には同じスクリプトで動きます。 ブラウザでは動かないものやプロジェクタでは意味を持たないスクリプトもありますけれど、loadVariables と Loader コンポーネントを制御する Loader クラスはプロジェクタでも動くはずです。 HTML で動くのにプロジェクタでは表示できないとなると、スクリプトの間違いなどではなさそうですね。 あとは、画像やテキストファイルがあるフォルダ” item_a ”が exe ファイルと同じフォルダの中にないとか、そのくらいの原因しか、思いつかないのですが... ------------------------------------- 考えにくいことですけれど、もし Loader コンポーネントのバグなどだとするなら、他の方法を試してみてはいかがでしょう。 #1にもちょっと書きましたけれど、ムービークリップに読み込んで、後で大きさを変更することもできます。 よろしければ、新しいファイルを作ってこちらも試してみてください。 ステージには何も配置せず、スクリプトだけでムービーを作ります。 フレームの構成は次のようになります。 フレーム1:画像ファイル名の読み込みと、画像を読み込むための準備。 フレーム2:テキストファイルの読み込み完了を待つ。スクリプトはなし。 フレーム3:ファイル名の読み込み終了後、ムービークリップを作って画像を読み込む。 スクリプトは次のようになります。 全角のスペースにご注意ください。 ・フレーム1 //テキストファイルの読み込み System.useCodepage = true; this.loadVariables( "item_a/STYLE-A.txt" ); //画像を読み込むための準備 load_obj = new MovieClipLoader(); //読み込み終了時に実行する処理 load_obj.onLoadInit = function( target_clip:MovieClip ) { //位置と大きさを決めて表示 target_clip._x = 100; target_clip._y = 100; target_clip._width = 200; target_clip._height = 150; }; ・フレーム3 //テキストの読み込み完了を待つ if( photo_a_name == undefined ) { gotoAndPlay( _currentframe - 1 ); } else { //空のムービークリップを作る this.createEmptyMovieClip( "clip" , 0 ); //画像の読み込み load_obj.loadClip( "item_a/" + photo_a_name , clip ); //タイムラインはここで止める stop(); } 画像を読み込むには、 ・loadMovie アクションを使う ・MovieClip クラスの loadMovie メソッドを使う ・MovieClipLoader クラスを使う( MX 2004 のみ) ・Loader コンポーネントを使う( MX 2004 のみ) このような方法があります。 今回は MovieClipLoader という方法を利用しています。 画像を読み込む時は、その受け皿となるムービークリップが必要になります。 Loader コンポーネントは内部に専用のムービークリップを持っているので、インスタンスを配置するだけでいいのですが、他の方法を使う場合はムービークリップが必要です。 予めステージに配置しておく方法もありますが、スクリプトでムービークリップを作ることもできます。 上記の例ですと、フレーム3の //空のムービークリップを作る this.createEmptyMovieClip( "clip" , 0 ); このスクリプトでムービークリップを作っています。インスタンス名は” clip ”です。 このムービークリップは名義だけはありますけれど、絵も大きさもない、空っぽのムービークリップです。位置は、さしあたってステージのX= 0 、Y= 0 の地点に配置されます。 テキストファイルから読み込んだ画像のファイル名を元に、このムービークリップに画像を読み込みます。 その部分が、 load_obj.loadClip( "item_a/" + photo_a_name , clip ); です。 位置や画像の大きさなどは、どこで決めているのかといいますと。 実は、フレーム1にある load_obj.onLoadInit = function・・・ この中で設定されています。 MovieClipLoader では、読み込みの作業中に様々なイベントが発生します。 イベントが発生した時に実行したい処理を予め指示しておくと、必要な時にその処理を自動で呼び出してくれます。 onLoadInit というイベントは、読み込みが完了した時に発生するイベントです。 今回はこのイベントを利用して、画像が読み込み終わった時点で、画像の位置( _x と _y )と大きさ( _width と _height )を決めるようにしています。 位置や大きさを変更する時は target_clip._x = 100; target_clip._y = 100; target_clip._width = 200; target_clip._height = 150; これらの数値を書き換えてください。 これでも表示できないとなると、Flash とは別のところに原因があるのではないかと思います。 あまりお役に立てず、申し訳ありませんが。。。
その他の回答 (3)
- DPE
- ベストアンサー率85% (666/776)
> しかしダイナミックテキストを配置して変数をphoto_aにしたら、・・・ テキストファイルに書いた変数の名前が、photo_a になっているということでしょうか? 例えば、テキストファイルの中身が photo_a_name=gazou.jpg だとします。 このファイルを読み込むと、photo_a_name という変数が定義され、その中身が gazou.jpg になります。 #1のスクリプトでは、テキストファイルから読み込む変数の名前が photo_a_name であるものとしています。 テキストファイルの中身が photo_a=gazou.jpg なのでしたら、変数 photo_a は定義されますが、変数 photo_a_name はいつまでも定義されないことになります。 #1のスクリプトをそのまま使うと、 if( photo_a_name == undefined ) この条件が常に成立するため、else 以下のスクリプト(画像のファイルパスを指定し、画像を読み込む処理)がいつまでも実行されず、画像は表示されません。単に、フレーム2と3の間を無限にループし続けるだけのムービーになります。 また、phpto_a という名前は Loader コンポーネントのインスタンスの名前でもあるはずです。 読み込んだ変数の名前も photo_a だとすると、名前の衝突が発生して photo_a.contentPath = "item_a/" + photo_a; このスクリプトを実行しても失敗に終わります。contentPath が未定義のままになりますから、画像の読み込みも失敗してしまいます。 しかし、photo_a という変数は、実際には変数としても存在してはいるので、ダイナミックテキストで photo_a の内容を表示すると gazou.jpg と表示されます。 長くなりましたけれど、まとめますと。 #1のスクリプトをそのまま利用する場合は、テキストファイルの内容が photo_a_name=gazou.jpg になっているか、確認してみてください。 テキストファイルの中身を photo_a=gazou.jpg とするのなら、Loader コンポーネントには photo_a 以外の名前を付けてください。 この変更に伴い、スクリプト中の Loader コンポーネントのインスタンス名( photo_a.contentPath と photo_a.load の、photo_a の部分)の変更も必要になります。 また、読み込まれる変数が photo_a になるのですから、if 文の条件や contentPath を設定する時に使っている変数の名前など、かなりの箇所の手直しが必要になります。 簡単なのは、テキストファイルの変数名を合わせる方ですね。 こちらを確認してみてください。 なお、ファイル名の読み込みや contentPath が正しく設定されているかどうかを確認するには、trace アクションを利用すると便利です。 例えば、 trace( "読み込んだ変数:" + photo_a_name ); //読み込んだファイル名を利用して、 //Loaderコンポーネントに画像を読み込む photo_a.contentPath = "item_a/" + photo_a_name; trace( "ファイルパス:" + photo_a.contentPath ); このように contentPath を操作する前後に trace アクションを入れて、読み込んだ変数や contentPath の値を表示してみてください。 「ムービープレビュー」で見ると、「出力」ウィンドウが開いて、photo_a_name に入っている値と、インスタンス photo_a が持っている contentPath の内容が表示されます。 もし、「出力」ウィンドウも開かないようなら、この else 以下のスクリプト自体が実行されていないことになります。 この場合は、if の条件文に書かれている変数名などに誤りがないかを確認してみてください。
補足
DPE様 毎回丁寧に教えていただいて、本当にありがとうございます。 「変数をphoto_aにしたら」は「変数をphoto_a_nameにしたら」の記述ミスです。失礼しました。 trace アクション:こんな便利な機能があったんですね!(だからまず、基本をちゃんとしようよ自分……) 出力ウインドウが出て、「読み込んだ変数:gazou.jpg ファイルパス:item_a/gazou.jpg」とちゃんと出力されました。 実は、今まではswfとWindowsプロジェクタで確認して表示されていなかったのですが(使用目的としてはWindowsプロジェクタ単体で使用したいので)、この時点で確認してわかったのですがHTMLではきちんと表示されていました。 htmlとexeでの表示が違うとは思わなかったので、最初にそう書かなかった私が悪かったのです。申し訳ありません。 引き続き、exeで画像のパスをを外部テキストから読み込む方法をご存知でしたらアドバイスしていただけないでしょうか……
- DPE
- ベストアンサー率85% (666/776)
#1です。 スクリプトのどこかに、全角のスペースが残っていませんでしょうか? ブラウザでは、行頭に半角のスペースがいくつもあると自動的に削除されて見辛くなってしまいますので、#1でご紹介したスクリプトでは、インデントを全角のスペースで付けています。 しかし、実際のスクリプトでは、文字列の一部として使う場合を除き、全角のスペースが入っているとシンタックスエラー(文法違反)となります。 #1のスクリプトで、2文字分字が下がっているといいますか、インデントが付いているところは、全角のスペースが2つ入っています。 コピーする時は、これらを全て半角のスペースかタブに置き換えてください。 スクリプトを編集する「アクション」パネルには、文字や文字列を指定の文字・文字列に置き換える機能がありますので、利用してみてください。 パネルの右上にあるアイコン(「閉じる」ボタンのすぐ下)をクリックしてメニューを出し、その中の「置換...」を選ぶか、パネルの上部に7つほど並んだアイコンの中の、左から3番目のアイコンをクリックしてください。「置換」のパネルが開きます。 「検索文字列」の項目に全角のスペース、「置換」の項目に半角のスペースを入力し、「すべて置換」をクリックすると、一発で置き換えられます。 Tab キーは入力項目の移動用として割り当てられているため、タブにはうまく置き換えられません。 タブでインデントを付けたい場合は、まず、「検索文字列」に全角のスペース、「置換」に何も入力せずに置き換えてください。全角のスペースが全て削除されます。 その後で、手動でタブを挿入してインデントを付けてください。 自動でインデントを付ける、「自動フォーマット」機能(7つのアイコンの、左から2番目をクリック)を利用しても構いません。{ } の配置等が変わりますが、スクリプトの意味は全く同じです。 簡単にではありますが、スクリプトは動作を確認した上でコピーしましたので、全く動かないことはないと思います。 シンタックスエラーということで、全角のスペースが犯人ではないでしょうか。 スクリプトの中に1つでも残っていないかどうか、確認してみてください。
補足
せっかく教えていただいたのに間があいてしまってすみません。 おっしゃる通りエラーの原因は全角スペースでした。こんな基本的なことも知らなくて、いきなりチャレンジするのは無謀だったのかな…… エラーは解決したのですが、画像がまだ表示されないのです。 ためしに photo_a.contentPath = "item_a/" + photo_a_name; を photo_a.contentPath = "item_a/" + "gazou.jpg"; にしてみたら上手く表示されたので、photo_aが上手く取得できてないのかと思いました。 しかしダイナミックテキストを配置して変数をphoto_aにしたら、ちゃんとgazou.jpgというテキストが表示されます。 これってphoto_aの取得は上手くいっているということですよね? なぜ画像が表示できないのか、理由がわからなくて困っています。 お心当たりがあったら教えていただけると嬉しいです。
- DPE
- ベストアンサー率85% (666/776)
まず、ファイル名の読み込みについてですが。 プログラムには、前の仕事が終わらないと次の命令が実行されないものと、仕事が終わらなくても次の命令を出すことができ、前の仕事は裏で並行して進められるものがあります。 ActionScript で言いますと、例えば for や while などのループは、ループが終了するまでは次のスクリプトは実行されません。 loadVariables や loadMovie のように時間のかかる処理は後者のタイプで、「○○ファイルを読み込め」の命令を出した後は、すぐに次のスクリプトに進みます。次のスクリプトを実行しながら、読み込み作業が同時に行われます。 ローカル環境で、通信回線を介さずに再生する場合であっても、ファイルを開き、内容を読み、変数なら変数として内部に変数名と内容を設定し、ファイルを閉じる・・・といった処理が、loadVariables スクリプトを実行した直後に一瞬で終了することは、まずありえません。 外部から読み込んだ変数を使って何かをする時や画像をボタンにする場合などは特に、読み込みの終了を待ってから先に進むための工夫が必要になります。 読み込みが終わる前に先に進むと、必要な情報が未定義のまま処理が行われ、画像が表示されなかったり意図した動作にならないなど、様々なトラブルの原因になります。 読み込みを待つ方法は様々ですが、変数の場合は、ヌルストリング( "" )や変数が未定義であるという意味の undefined を利用して判別する方法があります。 また、Flash MX から使えるようになった LoadVars というクラスを使うと、読み込みが終了した時にイベントが発生するので、終了を検出することができます。 なお、null と undefined はほぼ同じ意味ですが、変数が定義されているかどうかを判断する時は、一般的には undefined が使われます。 フレームに設定したスクリプトは、再生ヘッドがフレームに来た、その時1度しか実行されません。 また、Flash の仕様上、gotoAndPlay アクションで全く同じフレーム移動したとしても、全く同じフレームに連続して再生ヘッドをセットすることはできないようになっています。 変数の値を監視したい場合のように、同じフレームアクションを繰り返し実行させるには、一旦別のフレームに移動してから、スクリプトを設定したフレームに戻すようにします。 変数の読み込みを待って処理する流れは、 フレーム1:読み込み開始。 フレーム2:読み込み終了を待つためのフレーム。スクリプトは何もなし。 フレーム3:読み込み終了判定と、その後の処理。 このようになります。 フレーム2と3の間をループすることで、フレーム3の変数の値を監視するスクリプトを何度も実行させ、変数の読み込みが終わるまで待機します。 変数の読み込みが終了したら、続けて Loader コンポーネントのインスタンス”photo_a”に画像を読み込みます。 スクリプトにしてみますと、大体、次のようになります。 (↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください。このまま使うとシンタックスエラーになります) ・フレーム1 //ファイル名をShift-JISで読み込む System.useCodepage = true; this.loadVariables( "item_a/STYLE-A.txt" ); ※テキストファイルが UTF-8 形式で保存されているときは、System.・・・の1行を削除してください。文字化けの原因になります。 ・フレーム3 //読み込み完了を待つ if( photo_a_name == undefined ) { gotoAndPlay( _currentframe - 1 ); } else { //読み込んだファイル名を利用して、 //Loaderコンポーネントに画像を読み込む photo_a.contentPath = "item_a/" + photo_a_name; photo_a.load(); //タイムラインはここで止める stop(); } --------------------------------------- コンポーネントとは、編集可能なパラメータを持つ”ムービークリップ”です。 ムービークリップである以上、ムービークリップで使えるスクリプトやイベントは基本的には利用可能です。 (ただし、コンポーネントによっては動かないものや、コンポーネントの動作に支障をきたすものもあります) loadMovie はムービークリップで使えるスクリプト(メソッドと呼ばれます)です。 Loader はコンポーネントであると同時にムービークリップでもあるのですから、loadMovie は動作しますし、画像も一応は読み込まれます。 しかし loadMovie では、Loader コンポーネントが持っている機能を充分に引き出すことができません。 Loader コンポーネントには、コンポーネントが持っている機能を効果的に利用できるようにと、様々なメソッドが用意されています。 読み込みに関しては、Loader.load という専用のメソッドがあります。 Loader.load では、loadMovie や loadVariables と同じ要領で読み込むファイル名を直接指定するほかに、Loader コンポーネントが持っているパラメータの1つである contentPath を利用して指定することもできます。 上記のスクリプトでは、contentPath を使って読み込んでいます。 --------------------------------------- 画像の読み込みはムービークリップでもできますし、ムービークリップでも、読み込んだ画像を指定の大きさを変更することはできます。 Loader コンポーネントでは、手軽に使えるようにと面倒な処理をコンポーネントの中で全て引き受けてくれているだけで、内部では同様にムービークリップを使って読み込んでいます。 Loader コンポーネントはステージにはただの四角形として表示されますけれど、内部にはいくつものムービークリップと複雑なスクリプトが組み込まれており、処理も容量も重くなっています。 もう少し Flash や ActionScript に慣れてきたら、ムービークリップに読み込み、大きさを調整する方法も研究してみてください。 長くなってすみませんでした。 不明な点がありましたら、補足してください。
補足
DPE様、丁寧な開設ありがとうございます。 ご指摘の通り、3フレーム目に if( photo_a_name == undefined ) { gotoAndPlay( _currentframe - 1 ); } else { photo_a.contentPath = "item_a/" + photo_a_name; photo_a.load(); stop(); } と記述したのですが、パブリッシュ時に 「**エラー** シーン = シーン 1, レイヤー = スクリプト, フレーム = 3 :行 3:シンタックスエラー gotoAndPlay( _currentframe - 1 ); **エラー** シーン = シーン 1, レイヤー = スクリプト, フレーム = 3 :行 4:予期しない '}' があります。 } ActionScript エラー数 :2 報告済みエラー :2」 と出てしまいます。 できたファイルを開いてみると、画像が表示されていません。 ためしに3フレーム目にダイナミックテキストを配置し、変数を「photo_a_name」にして開いてみたところ、画像名が激しく点滅している状態です。 これは//読み込み完了を待つ//の部分が上手く動いていないということなのでしょうか? 何度もお尋ねしてすみませんが、教えていただけると助かります。
お礼
DPE様。いつも丁寧な回答ありがとうございます。 そうですよね、swfとhtmlで表示結果が違うなんて、理解できません。 とりあえず時間がないため、外部テキストからパスを参照しない(画像名を書き換えてフォルダに入れ替える)方式で先に完成させ、その後教えてくださった内容を試してみたいと思います。 そのときまたわからないことがあればここで質問させていただきたいと思っていますのでよろしくお願いいたします。 本当にありがとうございました。