トップページ > マウス, キーボード > ドラッグ機能を自前で用意する



概要

表示オブジェクトをドラッグする機能を書いてみましょう。

Spriteオブジェクトをドラッグする
を先に参照してください。

startDrag(), stopDrag()を使用せず、自前でドラッグする機能を書いていきます。


考え方

  • オブジェクトをクリックした時点でドラッグ開始
  • マウスボタンを離さない間、オブジェクトの位置をmouseX, mouseYに合わせる
  • マウスボタンを離したらドラッグ終了
となります。


プログラム

private var bitmap:Bitmap;
 
public function Main()
{
	// 適当な設定で
	var bd:BitmapData = new BitmapData(100, 100, false, 0xED1A3D);
	bitmap = new Bitmap(bd);
	addChild(bitmap);
 
	// マウスボタンが押されたら、onMouseDown()を呼び出す - ドラッグ開始
	stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
 
	// マウスボタンが離されたら、onMouseUp()を呼び出す - ドラッグ終了
	stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
 
適当にオブジェクトを用意して、stageにマウスイベントを登録します。
ここで問題なのは、どこでクリックしてもドラッグが開始してしまうことです。


private function onMouseDown(event:MouseEvent):void
{
	// クリックした地点にbitmapが無かったら処理終了
	if (!bitmap.hitTestPoint(mouseX, mouseY)) return;
 
	stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
 
private function onMouseUp(event:MouseEvent):void
{
	stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
 
なので、クリックした地点に用意したオブジェクトが存在しなかったら処理を終了させます。
存在したらMOUSE_MOVEイベントを登録します。

マウスボタンが離されたら、ドラッグ終了ということでMOUSE_MOVEイベントを削除します。


private function onMouseMove(event:MouseEvent):void
{
	bitmap.x = mouseX;
	bitmap.y = mouseY;
}
 
マウスが動かされるたびに、対象オブジェクトの位置をマウスに合わせます。
これでドラッグの出来上がりです。


オブジェクトのどこをクリックしても、左上部分がマウスに重なりますね。
これはstartDrag()の第一引数にtrueを入れた状態と同じになります。


では、falseを入れた状態、つまりクリックした位置にマウスポインタが重なるようにコードを変更してみましょう。

private var point:Point = new Point();
 
まずインスタンス変数にPointオブジェクトを用意します。


private function onMouseDown(event:MouseEvent):void
{
	// クリックした地点にbitmapが無かったら処理終了
	if (!bitmap.hitTestPoint(mouseX, mouseY)) return;
 
	// ローカル座標を取得
	point = bitmap.globalToLocal(new Point(mouseX, mouseY));
 
	stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
 
対象オブジェクトがマウスで押されたとき、対象オブジェクトから見てのローカル座標を取得します。
globalToLocal()については、グローバル座標とローカル座標の変換を参照してください。


private function onMouseMove(event:MouseEvent):void
{
	bitmap.x = mouseX - point.x;
	bitmap.y = mouseY - point.y;
}
 
あとはmouseXYからローカル座標を引くだけです。




検証用コード

package
{
	import flash.display.Sprite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.MouseEvent;
	import flash.geom.Point;
 
	public class Main extends Sprite
	{
		private var bitmap:Bitmap;
		private var point:Point = new Point();
 
		public function Main()
		{
			// 適当な設定で
			var bd:BitmapData = new BitmapData(100, 100, false, 0xED1A3D);
			bitmap = new Bitmap(bd);
			addChild(bitmap);
 
			// マウスボタンが押されたら、onMouseDown()を呼び出す - ドラッグ開始
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
 
			// マウスボタンが離されたら、onMouseUp()を呼び出す - ドラッグ終了
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		}
 
		private function onMouseDown(event:MouseEvent):void
		{
			// クリックした地点にbitmapが無かったら処理終了
			if (!bitmap.hitTestPoint(mouseX, mouseY)) return;
 
			// ローカル座標を取得
			point = bitmap.globalToLocal(new Point(mouseX, mouseY));
 
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
		}
 
		private function onMouseUp(event:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
		}
 
		private function onMouseMove(event:MouseEvent):void
		{
			bitmap.x = mouseX - point.x;
			bitmap.y = mouseY - point.y;
		}
	}
}
 

|新しいページ|検索|ページ一覧|RSS|@ウィキご利用ガイド | 管理者にお問合せ
|ログイン|