ActionScript3.0でループ処理を使って関数名を作成する方法

このQ&Aのポイント
  • ActionScript3.0において、ループ処理を使って関数名を作成することは可能です。
  • 指定した変数名に連番を追加することで、関数名を作成することができます。
  • 具体的には、`addEventListener`メソッドの第2引数に関数名を指定する際に、文字列連結を使用して変数名に連番を追加することで、関数名を作成することができます。
回答を見る
  • ベストアンサー

【AS3】ループ処理で関数名を作成するには?

ActionScript3.0についてご教授ください。 forなどを使い、ループ処理を使って変数名を作成する要領で 関数名を作ることは可能なのでしょうか? やりたい処理を記述させて頂きますと次の通りです。 ステージにある3つのボタン「btn0」「btn1」「btn2」に対して マウスクリック時の処理を書こうとしている例文です。 もちろん、これではエラーになります。 for( var i:int; i<3; i++ ){   this["btn"+i].addEventListener( MouseEvent.MOUSE_DOWN,"on"+i );   function "on"+i( e:MouseEvent ):void{     trace( e.target.name );   } } こうした処理を実現したい場合、"on"+i 部分をどのように記述すると良いのでしょうか? もしご存知でしたらお知恵をいただけないでしょうか。 よろしくお願い致します。

  • Flash
  • 回答数1
  • ありがとう数5

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

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

関数はメモリのどこかに存在していて、呼び出す時はその所在地が必要になります。 メモリ内での所在地を表す情報を”参照”といい、関数の名前はその関数のメモリ内での所在地を表す参照になっています。 関数を定義する function キーワードでは、名前を定めない関数(匿名関数といいます)を作ることもできます。 匿名関数を作った時は、作られた関数の参照(=メモリ内での所在地)が返されます。 返された参照を変数に保存しておけば、この変数を関数の名前の代わりに使うことができます。 ループを利用して匿名関数と連番の名前の付いた変数を作ると、連番の関数のようにすることができます。 合わせますと、関数 on0 ~ on2 を定義し、これらをボタン btn0 ~ btn2 のイベント処理関数に指定するスクリプトは次のようになります。 (↓ 各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください) //***  //btn0~btn2のイベントリスナーを登録  for( var i:int = 0 ; i < 3 ; i++ )  {   //匿名関数を作り、連番の変数に参照を保存する   this[ "on" + i ] = function( e:MouseEvent ):void   {    trace( e.target.name );   };   //イベントリスナーを登録   this[ "btn" + i ].addEventListener( MouseEvent.MOUSE_DOWN , this[ "on" + i ] );  } //*** ↑ この場合は関数が3つ作られ、on0 ~ on1 という名前で呼び出せます。 ただし、全く同じ内容の関数が3つ存在することになり、メモリを無駄に占有してしまいます。 - - - - - ActionScript 3.0 では、イベントが発生した時に呼び出される関数に、イベントに関する様々な情報を1つにまとめたものが渡されるようになりました。 渡される情報の1つに、イベントを検出した対象を表す情報があります。上記の例では仮引数 e を介して参照している e.target の部分がそれで、対象がどんなインスタンス名であっても対応できるようになっています。 動作は全く同じで対象だけが異なる場合は、この e.target という表現を利用すると、関数は1つだけで済みます。 //***  //イベント処理関数  function onButton( e:MouseEvent ):void  {   //ボタンの名前を出力   trace( e.target.name );  }  //btn0~btn2のイベントリスナーを登録  for( var i:int = 0 ; i < 3 ; i++ )  {   this[ "btn" + i ].addEventListener( MouseEvent.MOUSE_DOWN , onButton );  } //*** ↑ このスクリプトでは、どのボタンが押されても omButton 関数が呼び出されます。 omButton 関数内の e.target は、btn0 でイベントが検出された時には btn0 を、btn1 で検出された時には btn1 を表しますので、同じ関数を登録していてもボタンに応じた名前が出力されます。

henoheno-moheji
質問者

お礼

お礼が遅くなり、申し訳ございませんでした! 非常にご丁寧なご説明ありがとうございます! おかげで助かりました。

関連するQ&A

  • 連番のインスタンス名をつけたMCの処理 (配列アクセス演算子)

    Adobe Flash CS3、AS3.0の環境で作成しております。 インスタンス名に、btn1~btn10までの連番で名前をつけたMCを、ドラッグ&ドロップできるようにしたいのですが、簡潔に設定を行いたいと思い、配列アクセス演算子を使用すればよいのでは、と思い、下記のように記述したのですが、ドラッグしようとした時点で、「TypeError: Error #1010: 条件は未定義であり、プロパティがありません。」のエラーが出ます。 //--------------------------------------------- for (var i=1; i<=10; i++) { this["btn"+i].buttonMode = true; this["btn"+i].addEventListener(MouseEvent.MOUSE_DOWN, down); this["btn"+i].addEventListener(MouseEvent.MOUSE_UP, up); } function down(eventObject:MouseEvent):void { this["btn"+i].startDrag(); } function up(evnetObject:MouseEvent):void { this["btn"+i].stopDrag(); } //--------------------------------------------- 問題切り分けのために、マウス操作があったときの動作を、単なるtrace等にしてみると問題なく動作するので、function~部分の  this["btn"+i] の記述が問題だというのはわかるのですが、ここの正しい記述方法がわからず、行き詰まっております。ご教示いただけませんでしょうか。

    • ベストアンサー
    • Flash
  • AS3 記述方法

    ボタンが複数存在し、それぞれのボタンの処理をまとめたい時に どうするか考えています。 たとえばステージに3つのボタンインスタンス 「btn1」「btn2」「btn3」があるとします。 クリックすると、それぞれに応じた値を得るために ------------------------------------------------------------- btn1.addEventListener(MouseEvent.CLICK,syori1); function syori1(eventObject:MouseEvent):void{ trace("あんぱん"); } btn2.addEventListener(MouseEvent.CLICK,syori2); function syori2(eventObject:MouseEvent):void{ trace("しょくぱん"); } btn3.addEventListener(MouseEvent.CLICK,syori3); function syori3(eventObject:MouseEvent):void{ trace("カレーぱん"); } ------------------------------------------------------------- としているのですが、 たとえばもしこれが100個のボタンがあれば 100回同じような事を記述しないといけないので あまりよろしくないな・・・と思い、 ------------------------------------------------------------- for(var i=1; i<=3 i++){ this["btn"+i].addEventListener(MouseEvent.CLICK,syori); } function syori(eventObject:MouseEvent):void{ trace("ジャム"); } ------------------------------------------------------------- としたのですが、これではどのボタンをクリックしても"ジャム"がトレースされます。(当然ですが・・・) このような時、まとめて記述するにはどうすればよいでしょうか?

  • AS3.0でボタン処理をまとめて書くには?

    はじめまして。当方、最近プログラム的なものを始めたばかりで困っています。 例えばルートにbtn0,btn1,btn2という3つのムービークリップを置いたとして、 ボタンを押したらそれぞれのムービークリップ名をトレースするには、 AS2.0以前ではルートのフレームアクションで for (var i=0;i<3;i++){  _root.["btn" + i].onRelease = function{   trace(this._name);  } } といった感じでforループでまとめられると思うのですが、 3.0ではどうしたらよいのか見当もつかず困っています。 for (var i=0; i<3; i++) {  ["btn"+i]addEventListener(MouseEvent.CLICK,over); } このようにまとめてリスナーに登録したとしても、 リスナー関数が別になってしまうので、this.nameは使えず…はて。といったところです。 なにとぞご教示よろしくお願い申し上げます。

    • ベストアンサー
    • Flash
  • 【as3】クリックでインスタンスを増やしたい

    Actionscript初心者です。 勉強のため、以下のURLにあるActionscript2.0のFlashをActionscript3.0に書き換えたいと思っています。 http://allabout.co.jp/gm/gc/66814/ 左側にリースのパーツ、右に素のままのリースが配置されています。パーツはそれぞれ、リボン付きベル(インスタンス名「bellBig」)、松ぼっくり (インスタンス名「matu」)、小さいベル(インスタンス名「bellSmall」)と指定してあります。この3つのアイテムをドラッグドロップすることでリースを飾り付けていきます。 インスタンスをドラッグ&ドロップする所まではできたのですが、 松ぼっくりと小さいベルをドラッグした際にインスタンスを複製するところでつまずいています。 あまりにも初歩的な質問で恐縮ですが、ご教授お願いいたします。 /*////////////////////大きいベル/////////////////////*/ // ドラッグ開始 bellBig.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown1); function mouseDown1(event:MouseEvent):void{ bellBig.startDrag(); } // ドラッグ終了 bellBig.addEventListener(MouseEvent.MOUSE_UP,mouseUp1); function mouseUp1(event:MouseEvent):void{ bellBig.stopDrag(); } /*////////////////////まつぼっくり/////////////////////*/ // ドラッグ開始 matu.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown); function mouseDown(event:MouseEvent):void{ matu.startDrag(); } //ドラッグ終了 matu.addEventListener(MouseEvent.MOUSE_UP,mouseUp); function mouseUp(event:MouseEvent):void{ matu.stopDrag(); } /*////////////////////小さいベル/////////////////////*/ // ドラッグ開始 bellSmall.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown2); function mouseDown2(event:MouseEvent):void{ bellSmall.startDrag(); } // ドラッグ終了 bellSmall.addEventListener(MouseEvent.MOUSE_UP,mouseUp2); function mouseUp2(event:MouseEvent):void{ bellSmall.stopDrag(); }

  • 関数名に変数を使いたい場合

    下のように多くのaddEventListener関数を作りたいので arr[0].addEventListener(MouseEvent.CLICK, onClick0); arr[1].addEventListener(MouseEvent.CLICK, onClick1); arr[2].addEventListener(MouseEvent.CLICK, onClick2); arr[3].addEventListener(MouseEvent.CLICK, onClick3); arr[4].addEventListener(MouseEvent.CLICK, onClick4); arr[5].addEventListener(MouseEvent.CLICK, onClick5); for文にいれて下のように処理したいのですが、 関数名に変数を使えず、困っています。 for(var i:int=0; i<6; i++){ arr[i].addEventListener(MouseEvent.CLICK, onClick i ); } 「 onClick i 」この部分は、どうやって記述すればよいのでしょうか? ご存知の方いらっしゃいましたら、どうかよろしくお願いします。

    • ベストアンサー
    • Flash
  • actionscript3.0 rotationについて

    actionscript3.0 rotationについて btnを押すごとにmcを時計回りに90度減速させながら回転させたいと思っています。 しかし2回ボタンを押して180度回転させるまではうまくいくのですが 3回目に270度になると、回転がとまりません。 分岐させて、-90度回そうと思うと(当たり前ですが)逆回転してしまいます。 どのように記述すればよいでしょうか? よろしくお願いします。 以下スクリプトです。 var i:int=0; function onEnter(event:Event):void{ mc.rotation += (i-mc.rotation)*0.1; } addEventListener(Event.ENTER_FRAME, onEnter); btn.addEventListener(MouseEvent.MOUSE_DOWN, MouseLDownFunc); function MouseLDownFunc(event:MouseEvent):void{ i+=90; };

    • ベストアンサー
    • Flash
  • as3でボタンにリンクをはる方法!

    質問ばかりで申し訳ないですが、お世話になります。 flashCS4&Actionscript3を使っているものです。 「ボタンにリンクをはる方法を探しています。 (どうしても 1093のシンタックスエラーになってしまい、困っています。)」 現在作成しているものは、以下のような構造です。 ************************************************************* ステージ ↓ムービークリップ【インスタンス名(menu_mc)】 ________________________________________ ・ボタン【インスタンス名(btn1_btn)】 ・ボタン【インスタンス名(btn2_btn)】 ・ボタン【インスタンス名(btn3_btn)】 ________________________________________ *************************************************** menu_mcの中で、以下のように記述しました。 btn1_btn.addEventListener(MouseEvent.CLICK,gotowebpage1); function gotowebpage1(event : MouseEvent) :void { navigateToURL(new URLRequest("​http://www.yahoo.co.jp"));​ } btn2_btn.addEventListener(MouseEvent.CLICK,gotowebpage2); function gotowebpage2(event : MouseEvent) :void { navigateToURL(new URLRequest("​http://www.yahoo.co.jp"));​ } btn3_btn.addEventListener(MouseEvent.CLICK,gotowebpage3); function gotowebpage3(event : MouseEvent) :void { navigateToURL(new URLRequest("http://www.yahoo.co.jp")); } すると、1093のシンタックスエラーになってしまいます。 うまく動作させる為には、他にどんな作業を行ったらいいのでしょうか、 よろしくお願いします!!!

    • ベストアンサー
    • Flash
  • FLEX 外部asの関数を実行する方法。

    nl.platipus.RenaultJointDevelopment.controls.GearBox.asというasの中に下記の関数があります。 private function makeLeverInteractive(param1:String) : void { switch(param1) { case "clickable": { lever.buttonMode = true; lever.useHandCursor = true; if (!lever.hasEventListener(MouseEvent.CLICK)) { lever.addEventListener(MouseEvent.CLICK, handleLeverClick, false, 0, true); } if (lever.hasEventListener(MouseEvent.MOUSE_DOWN)) { lever.removeEventListener(MouseEvent.MOUSE_DOWN, handleLeverMouseDown); } if (lever.hasEventListener(MouseEvent.MOUSE_UP)) { lever.removeEventListener(MouseEvent.MOUSE_UP, handleLeverMouseUp); stage.removeEventListener(MouseEvent.MOUSE_UP, handleLeverMouseUp); } break; } case "draggable": { lever.buttonMode = true; lever.useHandCursor = true; if (lever.hasEventListener(MouseEvent.CLICK)) { lever.removeEventListener(MouseEvent.CLICK, handleLeverClick); } if (!lever.hasEventListener(MouseEvent.MOUSE_DOWN)) { lever.addEventListener(MouseEvent.MOUSE_DOWN, handleLeverMouseDown, false, 0, true); } if (!lever.hasEventListener(MouseEvent.MOUSE_UP)) { lever.addEventListener(MouseEvent.MOUSE_UP, handleLeverMouseUp, false, 0, true); stage.addEventListener(MouseEvent.MOUSE_UP, handleLeverMouseUp, false, 0, true); } break; } default: { lever.buttonMode = false; lever.useHandCursor = false; lever.emphasize = false; if (lever.hasEventListener(MouseEvent.CLICK)) { lever.removeEventListener(MouseEvent.CLICK, handleLeverClick); } if (lever.hasEventListener(MouseEvent.MOUSE_DOWN)) { lever.removeEventListener(MouseEvent.MOUSE_DOWN, handleLeverMouseDown); } if (lever.hasEventListener(MouseEvent.MOUSE_UP)) { lever.removeEventListener(MouseEvent.MOUSE_UP, handleLeverMouseUp); stage.removeEventListener(MouseEvent.MOUSE_UP, handleLeverMouseUp); } break; break; } } return; }// end function このmakeLeverInteractiveという関数をnl.platipus.BasicATM.InhibitorSwitchAnimation.InhibitorSwitchAnimation.asの中で、 クリックすると実行するように書きたいのですが、できますでしょうか? もし、できるのであればその方法も教えていただけると助かります。

  • ActionScript 3.0 D&Dの実装

    ステージ上に、インスタンス20個配置し (addChildは使わずに、普通に最初から置きます。  インスタンス名は mc1 ~ mc20)  それぞれをドラッグアンドドロップで自由に動かしたいです。 以下のようにプログラムを書いたのですが いざドラッグしようとすると 「TypeError: Error #1006: value は関数ではありません at MethodInfo-1()」 っとエラーが出てしまいました。 っと出てしまいました。 一体何が原因でしょうか? また、解決方法がありましたら是非ともよろしくお願いします。 addEventListener(MouseEvent.MOUSE_OVER,getname); function getname(e:MouseEvent) {    var str= e.target.name; trace(str); //マウスカーソルを乗せたムービークリップのインスタンス名が出ます。 addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); function onMouseDown(e:MouseEvent) { str.startDrag(); } addEventListener(MouseEvent.MOUSE_UP, onMouseUp); function onMouseUp(e:MouseEvent) { str.stopDrag(); } }

    • ベストアンサー
    • Flash
  • もっとなめらかな線を描く方法

    マウスダウンしたままマウスを動かすと軌跡が残るようにしてマウスアップでそれが終わるという、一般的な「線を描く」というプログラムをActionScript3で書きました。 しかし、以下のコードでは物足りないのです。もっとなめらかに線を描きたいのです、このコードではカクカクしていると感じます。updateAfterEventもしてみましたが、まだ満足できません。よいアルゴリズムなど、ご存じの方おりましたらアドバイスを下さい。よろしくお願いします。 言語は、ActionScript3で回答願いたいですが、AS2やAS1や他の言語しか知らないけど改善方法は思いつくといった場合、その言語でも構いません。なんとか翻訳してみようと思います //フレームアクションです var nowdown:Boolean=false; var oldX:Number=0; var oldY:Number=0; var g:Graphics=this.graphics; g.lineStyle(5,0x00ffff); stage.addEventListener(MouseEvent.MOUSE_DOWN,PushPen); function PushPen(e:MouseEvent):void{ trace("down"); nowdown=true; oldX=stage.mouseX; oldY=stage.mouseY; } stage.addEventListener(MouseEvent.MOUSE_MOVE,MovePen); function MovePen(e:MouseEvent):void{ trace("move"); if(nowdown){ trace("move","if"); g.moveTo(oldX,oldY); g.lineTo(stage.mouseX,stage.mouseY); oldX=stage.mouseX; oldY=stage.mouseY; e.updateAfterEvent(); } } stage.addEventListener(MouseEvent.MOUSE_UP,UpPen); function UpPen(e:MouseEvent):void{ nowdown=false; }

    • ベストアンサー
    • Flash

専門家に質問してみよう