ページ 11

【ActionScript】イベント登録時に記述した変数の扱われ方について

Posted: 2012年6月02日(土) 17:24
by MoNoQLoREATOR
突然ですが、下記のコードを実行すると、1が出力されます。

コード:

package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	/**
	 * ...
	 * @author DefaultUser (Tools -> Custom Arguments...)
	 */
	public class Main extends Sprite 
	{
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			
			
			
			//ここ
			var num:uint = 0;
			stage.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void { trace(num); } );
			++num;
			
			
			
			
			
			
		}
		
	}
	
}
画面をクリックすると0が出力されることを期待したのですが、1が出力されました。
おそらく関数(イベントの登録に使用した無名関数)が呼ばれた時に初めて変数の中身が参照されるからなのでしょう。

期待通りの結果を得るためにはどうすれば良いのでしょうか?
ご教授よろしくお願い致します。

Re: 【ActionScript】イベント登録時に記述した変数の扱われ方について

Posted: 2012年6月02日(土) 23:01
by bitter_fox
MoNoQLoREATOR さんが書きました: 期待通りの結果を得るためにはどうすれば良いのでしょうか?
ご教授よろしくお願い致します。
++num;を取り除くなりすればいいと思います。

Re: 【ActionScript】イベント登録時に記述した変数の扱われ方について

Posted: 2012年6月02日(土) 23:07
by みけCAT
何も知りませんが、

コード:

stage.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void { trace(num); } );
++num;

コード:

stage.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void { trace(num); ++num; } );
にするのではダメですか?

Re: 【ActionScript】イベント登録時に記述した変数の扱われ方について

Posted: 2012年6月03日(日) 00:04
by MoNoQLoREATOR
それでは駄目なのです。
もう少し具体的に言うと、下記のようなことがやりたいのです。

[codeAS3]package
{
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;

/**
* ...
* @author DefaultUser (Tools -> Custom Arguments...)
*/
public class Main extends Sprite
{

public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point




var i:uint;
for (i = 0; i < 10;++i )
{
//円情報を作成
var shape:Shape = new Shape();
var g:Graphics = shape.graphics;
g.lineStyle(1, 0x000000, 1.0);
g.beginFill(0xFF0000, 1.0);
//円を描画
g.drawCircle(70 * i+40, 200, 30);
//クリックを感知するためスプライトで包む
var s:Sprite = new Sprite();
s.addChild(shape);
//画面に反映
stage.addChild(s);

s.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void { trace(i); } );
}






}

}

}[/code]

この場合どの円をクリックしても出力は10となります。

Re: 【ActionScript】イベント登録時に記述した変数の扱われ方について

Posted: 2012年6月03日(日) 01:07
by ISLe

コード:

/*(略)*/
                s.addEventListener(MouseEvent.CLICK, hoge(i) );
            }
        }
		private function hoge(i:int):Function
		{
			return function(e:MouseEvent):void { trace(i); }
		}
/*(略)*/
こうする必要があるみたいです。

Re: 【ActionScript】イベント登録時に記述した変数の扱われ方について

Posted: 2012年6月03日(日) 01:37
by MoNoQLoREATOR
>>ISLeさん
ありがとうございます。
解決しました。
まさかそんな方法があったとは・・・!
いえ、逆にそんな方法を使わないと実現できないなんて!(笑)
いやはや、ActionScriptには驚かされてばかりです。

一応解決後のコードを載せておきます。
[codeAS3]package
{
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;

/**
* ...
* @author DefaultUser (Tools -> Custom Arguments...)
*/
public class Main extends Sprite
{

public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point







function create(i:uint):Function
{
return function(e:MouseEvent):void { trace(i); };
}


var i:uint;
for (i = 0; i < 10;++i )
{
//円情報を作成
var shape:Shape = new Shape();
var g:Graphics = shape.graphics;
g.lineStyle(1, 0x000000, 1.0);
g.beginFill(0xFF0000, 1.0);
//円を描画
g.drawCircle(70 * i+40, 200, 30);
//クリックを感知するためスプライトで包む
var s:Sprite = new Sprite();
s.addChild(shape);
//画面に反映
stage.addChild(s);

s.addEventListener(MouseEvent.CLICK, create(i) );
}






}

}

}[/code]