イベントなど | coconuz info processor

イベントなど

4.1 イベントの基本

ActionScript 3.0ではキーボードやマウスによってプログラムを制御する際の、キーボードの押下やマウスのクリック、移動などを「イベント」として扱います イベントの仕組みは奥が深いですが、ここでは基本的なイベントの概念について学びます。

イベントを利用したサンプルプログラムとして以下のプログラムを実行してみて下さい。円をマウスでクリックすることで色とサイズが変わります。

【MouseEventExample.as】

package {
	import flash.display.Sprite;
	import flash.events.MouseEvent;

	public class MouseEventExample extends Sprite
	{
		private var circle:Circle;
		
		public function MouseEventExample()
		{
			circle = new Circle();
			
			circle.x = 100;
			circle.y = 100;
			this.addChild(circle);
			
			circle.addEventListener(MouseEvent.CLICK,onMouseClick); //イベントリスナーの登録
			
		}
		
		/* イベントリスナー */
		private function onMouseClick( event:MouseEvent ):void
		{
			circle.color = Math.random() * 0xffffff;
			circle.radius += 5;
			circle.draw();
		}
	}
}
イベントが発生した時、そのイベントに対応して実行される関数やメソッドのことをイベントリスナーまたはイベントハンドラーと呼びます。イベントリスナーは通常の関数やメソッドと同じように記述しますが、イベントに対応するクラスを引数としてとります。例えば、マウスイベントにはMouseEventクラスを使用します。上記の例ではonMouseClick()メソッドがイベントリスナーに当たります。 

イベントリスナーを記述したら、次はイベントリスナーの「登録」を行います。登録するとは、発生したイベントに対応してイベントリスナーが実行されるようにすることです。イベントリスナーの登録には以下のようにaddEventListener()メソッドを使用します。

			circle.addEventListener(MouseEvent.CLICK,onMouseClick);

addEventListener()メソッドにはイベント定数と、イベントリスナーを引数として渡します。こうしてベントリスナーを登録すると、イベントが発生した際に引数として指定したイベントのクラスが生成され、イベントリスナーが実行されます。

多くのイベントは該当するクラスにて定数として定義されています。
例えば、MouseEventクラスではマウス関連のイベントが定義されており、以下のようなものがあります。

【MouseEventクラスで定義されている主なイベント定数】
定数名 説明
CLICK マウスの主ボタンのクリック
MOUSE_DOWN マウスの主ボタンの押下
MOUSE_MOVE マウスポインタの移動
MOUSE_OUT マウスポインタがオブジェクト外に移動
MOUSE_OVER マウスポインタがオブジェクト内に移動
MOUSE_UP マウスの主ボタンのリリース

実際にはこれらの定数には文字列が格納されています。例えば、CLICK定数には"click"という文字列が入っています。

それでは、続いてもう一つ簡単なマウスイベントのプログラムを作成してみましょう。 MOUSE_OVERとMOUSE_OUTのイベントを利用します。

【MouseEventExample1.as】

package {
	import flash.display.Sprite;
	
	public class MouseEventExample1 extends Sprite
	{
		public function MouseEventExample1()
		{
			for( var i:int = 0; i < 10; i++ ) 
			{
				for( var j:int = 0; j < 10; j++ )
				{
					var block:Block = new Block();
					block.x = j * Block.length;
					block.y = i * Block.length;
					this.addChild(block);	
				}
			}
			
		}
	}
}

【Block.as】

package
{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	
	public class Block extends Sprite
	{
		public static var length:int = 20;
		
		public function Block()
		{
			draw(0xffffff);
			
			this.addEventListener(MouseEvent.MOUSE_OVER,onMouseOver);
			this.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut);
		}
		
		private function onMouseOver( event:MouseEvent ):void
		{
			draw(0xff0000);
		}
		
		private function onMouseOut( event:MouseEvent ):void
		{
			draw(0xffffff);
		}
		
		private function draw( color:int ):void
		{
			this.graphics.clear();
			this.graphics.lineStyle(1,0x000000);
			this.graphics.beginFill(color,1);
			this.graphics.drawRect(0,0,length,length);
			this.graphics.endFill();
		}

	}
}

4.2 マウスイベントの例

マウスポインタの動きをイベントとして取得し、ペイントツールのように線を描画するプログラムを作成してみます。
考え方は非常に簡単で、マウスポインタの動きをイベントとして取得し、その軌跡をlineTo()メソッドで描いていくことで実現できます。

【Paint.as】

package{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	
	public class Paint extends Sprite
	{
		
		public function Paint()
		{
			this.graphics.lineStyle(1,0x000000);
			
			stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
		}
		private function onMouseMove( event:MouseEvent ):void
		{
			this.graphics.lineTo(this.mouseX,this.mouseY);
			
		}


	}
}

このプログラムでは、イベントリスナーの登録をstageプロパティに対して行っています。stageプロパティとはActionScriptで生成されるファイルの画面全体の領域を表しているクラスです。マウスポインタの移動など、画面全体にイベントの範囲が及ぶ場合はstageプロパティにイベントリスナーを追加します。

一応線を描くことはできますが、線を描くタイミングを指定することができず、マウスポインタを移動すると常に線が描かれてしまいます。

ここでは一般的なペイントツールのように、マウスのボタンを押している間だけ線が描画されるという動作を再設計します。
ペイントツールで線を描くには、マウスのボタンを押す、マウスの移動、マウスのボタンを離すの3つがイベントとしてと考えられます。

【PaintModified.as】

package{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	
	public class PaintModified extends Sprite
	{
		
		public function PaintModified()
		{
			this.graphics.lineStyle(1,0x000000);
			this.graphics.endFill();
			stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
			stage.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
		}
		
		private function onMouseMove( event:MouseEvent ):void
		{
			if( event.buttonDown )
			{
				/*マウスの主ボタンが押されている間だけ、線を描画する*/
			}
				
		}
				
		private function onMouseDown( event:MouseEvent ):void
		{
			/*現在の描画位置をマウスカーソルの位置に設定*/
		}
		
	}
}
マウスの主ボタンが押されているかどうかは、MouseEventのbuttonDownプロパティから判定することができます。

次に、もう一つマウスカーソルの座標を利用したサンプルプログラムを作成してみます。

【ArrowPointing.as】

package {
	import flash.display.Sprite;
	import flash.events.MouseEvent;

	public class ArrowPointing extends Sprite
	{
		private var arrows:Array;
		
		public function ArrowPointing()
		{
			arrows = new Array();
			
			for( var i:int = 0; i < 30; i++ )
			{
				var arrow = new Arrow();
				arrow.x = Math.random() * stage.stageWidth;
				arrow.y = Math.random() * stage.stageHeight;
				this.addChild(arrow);
				arrows.push(arrow);
			}
			
			stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
			
		}
		
		private function onMouseMove( event:MouseEvent ):void
		{
			for each( var arrow:Arrow in arrows ) pointMouseCursor(arrow);
		}
		
		/* 矢印との座標とマウスカーソルの座標から矢印の角度を決定する */
		private function pointMouseCursor( arrow:Arrow ):void
		{
			var dx:Number = this.mouseX - arrow.x; //x成分
			var dy:Number = this.mouseY - arrow.y; //y成分
			var distance:Number = Math.sqrt(dx*dx+dy*dy); // 距離
			arrow.rotation = Math.acos(dx/distance) / Math.PI * 180;
			if( dy < 0 ) arrow.rotation = - Math.acos(dx/distance) / Math.PI * 180;
		}
	}
}

	import flash.display.Shape;
	
	class Arrow extends Shape
	{
		private var size:int = 3;
		
		public function Arrow()
		{
			this.graphics.lineStyle(1,0x000000);
			this.graphics.beginFill(0xffffff,1);
			this.graphics.moveTo(0,-size);
			this.graphics.lineTo(size*3,-size);
			this.graphics.lineTo(size*3,-size*2);
			this.graphics.lineTo(size*6,0);
			this.graphics.lineTo(size*3,size*2);
			this.graphics.lineTo(size*3,size);
			this.graphics.lineTo(0,size);
			this.graphics.lineTo(0,-size);
		}
	}