- 締切済み
ActionScriptのLoaderクラス
以下、FLASHのカテゴリーがあることに気付かずに、プログラミング(その他)に投稿してしまいましたので、再投稿いたします。よろしくお願いいたします。 以下はActionScript3.0を用いたフォトギャラリーで、外部のXMLファイルに記述しているパスをFLASH上に読み込み、それを参照して外部のフォルダからサムネイル画像を読み込むプログラムの一部です。 おそらく、ActionScriptの超初歩的なことが分かっていないのだと思います。 申し訳ございませんが、ご教示ください。 1 var thumbLoader_obj:Loader; 2 for(var i:uint=0;i<8;i=i+1){ 3 var thumbBtn:MovieClip=this["btn0"+(i+1)+"_mc"]; 4 var thumbUrl:URLRequest=new URLRequest(imgThumb_arr[i]); 5 thumLoader_obj=new Loader(); 6 thumbLoader_obj.load(thumbUrl); 7 thumbLoader_obj.x=3; 8 thumbLoader_obj.y=3; 9 thumbBtn.addChild(thumbLoader_obj); 10 } 以上は配列:imgThumb_arrに格納しているサムネイル画像のパスを参照して、loadメソッドを用いて インスタンス:thumLoader_objに読み込んだサムネイル画像を、サムネイル画像の枠を格納しているインスタンス:thumbBtnにループ処理で配置させるプログラムです。 3行目からわかる通り、サムネイル画像の枠のインスタンス名はbtn01_mc~btn08_mcで、 7行目と8行目は単なるサムネイル画像と枠の配置調整のための座標設定です。 さて、質問なのですが、5行目の代わりに1行目を thumLoader_obj=new Loader(); と書いて、5行目をコメントアウト(もしくは削除)してもプログラム的には問題ないように初心者の私には思えてしまうのですが、このようにすると、最後のサムネイル枠(btn08_mc)にしかサムネイル画像が読み込まれません。最初の通りだとすべての枠に該当するサムネイル画像が読み込まれてうまくいきます。明らかなプログラム上の違いがあるのだと思いますが、調べてみても簡単には分かりませんでした。どなたか、お教えいただければ幸いです。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- BlurFiltan
- ベストアンサー率91% (1611/1754)
#2です。 > Stringクラスからループ処理ごとインスタンスを生成しなくとも、 > 上手く値を更新して順に配列の中に文字列を期待通りに格納可能です。 > > これと、私が質問している(もしくは例で説明いただいている) > 内容とのプログラム上の違いが私には今一つ明確に理解できていません。 これに関しては #1の回答でお茶を濁したように(誤魔化して簡略化して)少し書いています。 > 変数には 文字列 や 数値 を直接入れることもありますし > ムービークリップ や Loader などの参照を入れることもあります。 文字列(String) や 数値(Number や int などなど) はその値が変数にに直接入るのです。 参照代入にはなりません。 ムービークリップ や Loader や スプライト などはその参照が変数に入るのです。 参照代入になります。 > 私には、学校0に田中先生が配属されて、 > あとはダメという具合だとまだ分かるのですが、 > どうして最後の学校7にだけ上手く配属されてしまうのかが、 > ご説明ではうまく理解できませんでした > (そういう仕様だということでしょうか?)。 その仕様を突き通すとするなら インスタンスは配置した以上,座標も変えられない(座標の引っ越しもできない)ということになりますよ。 それで良いのならその仕様になると思いますが そんなの Flash ではないでしょう? アニメーションを一切できなくなります。 一度配置したインスタンスは 別座標に引っ越しすることもできますし 別階層(ご質問の場合は別ムービークリップ)に引っ越しすることもできます。 ただこのような仕様になったのは,ActionScript 3.0 からです。 ActionScript 2.0 までは 別座標に引っ越しはできても 別階層には引っ越しできませんでした。 正に質問者さんが主張する仕様です。 ActionScript 2.0 まで 別階層には引っ越しする場合は 一旦その階層からインスタンスを(removeMovieClip で)消して 別階層に別インスタンスを(attachMovieClip で)作り直す必要がありました。 非常に面倒でしたし, なおかつ,上記のように引っ越しの矛盾を含んでいました。 それが不評だったためか ActionScript 3.0 では改善されて 別階層への引っ越しが可能になったのです。
- BlurFiltan
- ベストアンサー率91% (1611/1754)
スクリプト書き直すとは だいたいこのように↓するとういうことですよね? //------------------------------------------ //Loaderインスタンスを参照する変数を用意 var thumbLoader_obj:Loader; //Loaderインスタンスを1つだけ作成 thumLoader_obj=new Loader(); for(var i:uint=0;i<8;i=i+1){ var thumbBtn:MovieClip=this["btn0"+(i+1)+"_mc"]; var thumbUrl:URLRequest=new URLRequest(imgThumb_arr[i]); //1つのLoaderインスタンスに対して //順に imgThumb_arr[0]~imgThumb_arr[7] をロード thumbLoader_obj.load(thumbUrl); thumbLoader_obj.x=3; thumbLoader_obj.y=3; thumbBtn.addChild(thumbLoader_obj); } //------------------------------------------ お碗を1つ用意して まずは ワカメのみそ汁を入れ (それを捨てて)豆腐のみそ汁を入れ (それを捨てて)油揚げのみそ汁を入れ (それを捨てて)あさりのみそ汁を入れ (それを捨てて)納豆のみそ汁を入れ (それを捨てて)玉葱のみそ汁を入れ (それを捨てて)麩のみそ汁を入れ (それを捨てて)ジャガイモのみそ汁を入れました。 さて,この状態でお碗に入っているみそ汁は何のみそ汁でしょう? このみそ汁と同じことですよ。 器を1つしか用意せずに 次から次へと取っかえ引っかえ違うものを入れて行けば 最後に入れたものしか残りません。 上の文章には「(それを捨てて)」と書いていています。 実際にFlashでも同じLoaderに次から次へと違う物をロードすれば 前にロードしていたものはアンロードされます。 しかし「(それを捨ずに)」に変更しても結局同じことです。 1つの器の中で様々なものがごちゃまぜになっていくか, 上に上に重なって一番上のものしか見えなくなるだけです。 どちらにしても1杯のみそ汁しかできません。 上に書いたスクリプトの1行目&2行目ですが ここにポイントがあるので注意してください。 次のように1行にまとめても同じことです。 //Loaderインスタンスを1つだけ作成して //そのインスタンスの参照を変数に代入 var thumbLoader_obj:Loader=new Loader(); 2行にしても1行にしても同じことですが, どちらにしてもとにかく thumbLoader_obj というのは「変数」であって Loaderインスタンス自体ではありません。 Loaderインスタンスを参照する「変数」です。 最初にご質問で書かれているスクリプトと同じような 内容を喩え話的に書き直してみます。 //---------------------------------- //選出する校長を仮称「ボス」と呼ぶことにする var ボス:校長; for(var i:uint=0;i<8;i=i+1){ ボス = 選出した新しい校長(); そのボスを 学校0~7 に順次配属; } //---------------------------------- 最初のスクリプトはこんな感じですよ。 「ボス」は校長を名指しするための仮称です。 例えば 田中先生,高橋先生,佐藤先生,鈴木先生,…のように 次から次へと違う新しい校長を選んでは 次々に違う学校に配属させているのです。 ですから 結局 学校0~7 には違う校長が配属されることになります。 次に私が上に書いたスクリプトも同じような 内容を喩え話的に書き直してみます。 //---------------------------------- //校長を1人選出して仮称「ボス」と呼ぶことにする var ボス:校長 = 選出した新しい校長(); for(var i:uint=0;i<8;i=i+1){ そのボスを 学校0~7 に順次配属; } //---------------------------------- 「ボス」という仮称を与えられた校長は1人しか選出されていません。 田中先生なら田中先生1人のみです。 その「ボス」を 学校0~7 に次から次へと配置替えするのですから 結局「ボス」は 学校7 のみに1人だけ配属されることになってしまいます。 とにかく大切なことは var ○○ の ○○ は変数だということです。 変数には 文字列 や 数値 を直接入れることもありますし ムービークリップ や Loader などの参照を入れることもあります。 何かを参照する変数ですから(何かを名指しで呼ぶための名称ですから), 基本的に Flash に存在するものは何でも入れることができます。 クラスでも関数でも何でも代入できます。 //---関数を変数に代入する例---------------- //関数を作成してその参照を変数function_objに代入 var function_obj:Function = function():void{ trace("関数が実行されました"); } //function_objが参照する関数を実行 function_obj(); //----------------------------------------- 「F-site [AS3] MovieClipインスタンスとインスタンス名」 http://f-site.org/articles/2008/04/19014939.html
- anyhelp
- ベストアンサー率43% (79/181)
その通りです。最後しか変わりません。 あなたは8回繰り返してますが、5行目がなければ最後の1回だけ実行したのと同じです。 難しい事は抜きにして、それぞれを別々に動作させたいと考えるなら5行目のnew Loader()という表記をループで 毎回利用するとまずは覚えておくといいでしょう。
お礼
ご回答有難うございます。 もしよろしければ、何故、ラスト1回だけ機能しているのかをご教示願えませんでしょうか? お手数でしたら、何か参考にするべきサイトや文献、こういったキーワードで調べたら回答に行き着くなど、問題解決に至る術を教えていただけると大変、助かります。 申し訳ございませんが、よろしくお願い申し上げます。
補足
anyhelp様、この件にご回答いただき、ありがとうございます。 私なりに考えたのですが、最後の一度しか機能しないのは?というよりは、希望通りの処理がなされないのは以下のことが理由ではないかと考えています。 FLASH上で画像をActionScriptでコントロールする為にインスタンス化するということは、実際の手順としては、 (1)ライブラリにシンボルが登録(もしくは、シンボルをクラス化する) (2)そのシンボル(クラス)からインスタンスを作成 (3)作成されたインスタンスにインスタンス名を付けて、ActionScriptでコントロール可となる。 ということであると解釈しています。 ここで、画像のインスタンスに設定可能なプロパティは座標や拡大縮小であり、色の変更など、元のシンボルの画像とは本質的に異なる設定はできないことになっています。 そこで、もともとの私が書いているプログラムの6行目の部分で、thumbLoader_objに画像が読み込まれた時点で、これはそのサムネイル画像のインスタンス名になっているわけですから、5行目をコメントアウトして、その代わりに、5行目の内容を1行目と置き換えたのでは、ループ処理して、thumbloader_objに再度、本質的に画像として異なる次の順番のサムネイル画像を読み込もうとしていることになってしまいます。 したがって、既にインスタンス化されている画像のインスタンス名に新たな画像を読み込む行為はプログラムとして正しい文法ではなく、ループ処理ごとに新たなサムネイル画像を読み込んでくることを想定していますので、thumbLoader_objというLoaderクラスのインスタンスを毎回、生成して、読み込んできたサムネイル画像をインスタンス化する必要があるのではないかという考えに至りました。 それでも、1行目を5行目で置き換え、5行目をコメントアウトした場合に、最後1回のサムネイル画像の読み込みだけが機能しているという部分には疑問が残ってしまいます。 個人的な事情ですが、私自身、単にプログラムが上手く動けばよいという立場にはあらず、しっかりと原因を理解しなければなりません。私の考えの是非についてコメントを頂ければ幸いです。 何卒、よろしくお願い申し上げます。
お礼
BlurFiltan様 ご回答ありがとうございます。 例え話を織り交ぜていただき、丁寧な解説をありがとうございます。 また、個人的な事情でお礼を申し上げるのが遅くなり、申し訳ございませんでした。 その後私もこの件について色々と考えてみました。 どうやら、解説いただいている内容からすると、私は変数とインスタンスの理解が少し違っているような気がしました。以前、Adobeが提供しているflash_as3_programing.pdfの第3章のデータ型という節(11ページ)に以下の様な解説がありました。 ----------------------------------------------------------- http://help.adobe.com/ja_JP/ActionScript/3.0_ProgrammingAS3/flash_as3_programming.pdf データ型と同じ意味で多く使用される用語に、クラスとオブジェクトがあります。 クラスは単にデータ型の定義です。データ型のすべてのオブジェクトのテンプレートと考えることができ、「Example データ型のすべての変数には A、B および Cの 3 つの特性があります」と宣言するようなものです。一方、オブジェクトは、クラスの実際のインスタンスです。データ型が MovieClip である変数は、MovieClip オブジェクトとして記述できます。したがって、次のように同じ内容を様々な表現で表すことができます。 • 変数 myVariable のデータ型は Number • 変数 myVariable は Number インスタンス • 変数 myVariable は Number オブジェクト • 変数 myVariable は Number クラスのインスタンス ----------------------------------------------------------- この部分を読んで、変数名を冠して宣言された実際の変数は、クラスから生成された(インスタンス名を持つ)インスタンスと同じだと思っていました。 さて、ご解説いただいた内容の一部を以下に抜粋させていただきます *********************************************************** //---------------------------------- //校長を1人選出して仮称「ボス」と呼ぶことにする var ボス:校長 = 選出した新しい校長(); for(var i:uint=0;i<8;i=i+1){ そのボスを 学校0~7 に順次配属; } //---------------------------------- *********************************************************** この辺りのことについてご質問です。 以下は配列arrに文字列「みなさんこんにちは1回目」~「みなさんこんにちは9回目」を順に格納するプログラムなのです。 var hello:String=new String(); var arr:Array=new Array() for(var i:int=1;i<10;i=i+1){ hello="みなさんこんにちは"+i+"回目"; arr.push(hello); } このプログラムも、ループ処理の前にStringクラスからインスタンス(変数?)helloを生成して、ループ処理の中でそのまま使用しているというサンプルという意味で提示させていただいています。 これだと、Stringクラスから生成するインスタンス(変数?)helloはループ処理の中でStringクラスからループ処理ごとインスタンスを生成しなくとも、上手く値を更新して順に配列の中に文字列を期待通りに格納可能です。 これと、私が質問している(もしくは例で説明いただいている)内容とのプログラム上の違いが私には今一つ明確に理解できていません。 ただ、この件について、私なりに考えた内容を以下に述べさせていただきます。(これは、anyhelp様のご回答に対する補足からの抜粋です) ----------------------------------------------------------- 私なりに考えたのですが、最後の一度しか機能しないのは?というよりは、希望通りの処理がなされないのは以下のことが理由ではないかと考えています。 FLASH上で画像をActionScriptでコントロールする為にインスタンス化するということは、実際の手順としては、 (1)ライブラリにシンボルが登録(もしくは、シンボルをクラス化する) (2)そのシンボル(クラス)からインスタンスを作成 (3)作成されたインスタンスにインスタンス名を付けて、ActionScriptでコントロール可となる。 ということであると解釈しています。 ここで、画像のインスタンスに設定可能なプロパティは座標や拡大縮小であり、色の変更など、元のシンボルの画像とは本質的に異なる設定はできないことになっています。 そこで、もともとの私が書いているプログラムの6行目の部分で、thumbLoader_objに画像が読み込まれた時点で、これはそのサムネイル画像のインスタンス名になっているわけですから、5行目をコメントアウトして、その代わりに、5行目の内容を1行目と置き換えたのでは、ループ処理して、thumbloader_objに再度、本質的に画像として異なる次の順番のサムネイル画像を読み込もうとしていることになってしまいます。 したがって、既にインスタンス化されている画像のインスタンス名に新たな画像を読み込む行為はプログラムとして正しい文法ではなく、ループ処理ごとに新たなサムネイル画像を読み込んでくることを想定していますので、thumbLoader_objというLoaderクラスのインスタンスを毎回、生成して、読み込んできたサムネイル画像をインスタンス化する必要があるのではないかという考えに至りました。 ----------------------------------------------------------- BlurFiltan様が仰っていることと、上記抜粋の私の理解はやはり、異なっているのでしょうか?かなり身勝手な質問で申し訳ございませんが、この件をしっかりと理解したいと考えていますのでご回答をお願いいたします。 また、ご説明から抜粋した上記プログラムの解説箇所である、 *********************************************************** 「ボス」という仮称を与えられた校長は1人しか選出されていません。 田中先生なら田中先生1人のみです。 その「ボス」を 学校0~7 に次から次へと配置替えするのですから 結局「ボス」は 学校7 のみに1人だけ配属されることになってしまいます。 *********************************************************** の部分についてですが、私には、学校0に田中先生が配属されて、あとはダメという具合だとまだ分かるのですが、どうして最後の学校7にだけ上手く配属されてしまうのかが、ご説明ではうまく理解できませんでした(そういう仕様だということでしょうか?)。 申し訳ございませんが、今一度、ご助力を賜りたく存じます。