ActionScript では、マウスを使用して表示オブジェクトを移動する方法は 2 つあります。いずれの方法でも、2 つのマウスイベントを使用します。つまり、マウスボタンを押したときはマウスカーソルに従って移動し、マウスボタンを離したときはマウスカーソルに従って停止するようにオブジェクトに指示を出します。
注意:
Flash Player 11.3 以降および AIR 3.3 以降:MouseEvent.RELEASE_OUTSIDE イベントを使用して、Sprite を含む境界の外でユーザーがマウスボタンを離した場合に対応することもできます。
最初の方法では
startDrag()
メソッドを使用します。これは簡単な方法ですが、制約が多くなります。マウスボタンを押すと、ドラッグされる表示オブジェクトの
startDrag()
メソッドが呼び出されます。マウスボタンを離すと、
stopDrag()
メソッドが呼び出されます。Sprite クラスがこれらの 2 つの機能を定義するので、移動対象のオブジェクトは Sprite クラスまたはそのサブクラスである必要があります。
// This code creates a mouse drag interaction using the startDrag()
// technique.
// square is a MovieClip or Sprite instance).
import flash.events.MouseEvent;
// This function is called when the mouse button is pressed.
function startDragging(event:MouseEvent):void
{
square.startDrag();
}
// This function is called when the mouse button is released.
function stopDragging(event:MouseEvent):void
{
square.stopDrag();
}
square.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
square.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
この方法の場合、
startDrag()
を使用してドラッグできるのは一度に 1 つのアイテムだけという重大な制約があります。ある表示オブジェクトがドラッグされているときに
startDrag()
メソッドが別の表示オブジェクトに対して呼び出された場合、最初の表示オブジェクトはマウスに従って直ちに停止します。例えば、
startDragging()
関数を次のように変更した場合、
square.startDrag()
メソッド呼び出しにもかかわらず、
circle
オブジェクトだけがドラッグされます。
function startDragging(event:MouseEvent):void
{
square.startDrag();
circle.startDrag();
}
startDrag()
を使用してドラッグできるのは、一度に 1 つのオブジェクトのみです。そのため、表示オブジェクトに対して
stopDrag()
メソッドが呼び出されると、現在ドラッグ中のオブジェクトがどんなオブジェクトであってもそのオブジェクトは停止します。
複数の表示オブジェクトをドラッグする必要がある場合、または複数のオブジェクトが
startDrag()
を使用することで生じる可能性のある競合を回避する必要がある場合は、マウス追従方式を使用してドラッグ効果を作成するのが最適です。この方式を使用すると、マウスボタンが押されたときに、ステージの
mouseMove
イベントに対するリスナーとして関数がサブスクライブされます。マウスを移動するたびに呼び出されるこの関数により、ドラッグされるオブジェクトは、マウスの x, y 座標にジャンプします。 マウスボタンを離すと、関数はリスナーとしてのサブスクライブを解除されます。この場合、マウスを移動しても関数が呼び出されなくなるため、オブジェクトはマウスカーソルに従って停止します。 この方式を説明するコードを次に示します。
// This code moves display objects using the mouse-following
// technique.
// circle is a DisplayObject (e.g. a MovieClip or Sprite instance).
import flash.events.MouseEvent;
var offsetX:Number;
var offsetY:Number;
// This function is called when the mouse button is pressed.
function startDragging(event:MouseEvent):void
{
// Record the difference (offset) between where
// the cursor was when the mouse button was pressed and the x, y
// coordinate of the circle when the mouse button was pressed.
offsetX = event.stageX - circle.x;
offsetY = event.stageY - circle.y;
// tell Flash Player to start listening for the mouseMove event
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragCircle);
}
// This function is called when the mouse button is released.
function stopDragging(event:MouseEvent):void
{
// Tell Flash Player to stop listening for the mouseMove event.
stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragCircle);
}
// This function is called every time the mouse moves,
// as long as the mouse button is pressed down.
function dragCircle(event:MouseEvent):void
{
// Move the circle to the location of the cursor, maintaining
// the offset between the cursor's location and the
// location of the dragged object.
circle.x = event.stageX - offsetX;
circle.y = event.stageY - offsetY;
// Instruct Flash Player to refresh the screen after this event.
event.updateAfterEvent();
}
circle.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
circle.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
表示オブジェクトをマウスカーソルに追従させるだけではなく、ドラッグするオブジェクトを画面の手前に移動することにより、他のすべてのオブジェクトよりも上に浮かせて表示させることもよくあります。例えば、円と四角形の 2 つのオブジェクトがあり、その両方をマウスで移動するとします。表示リスト上で円が四角形の下にある場合、カーソルが四角形の上に来るように円をクリック & ドラッグすると、円は四角形の後ろにスライドして表示され、ドラッグ & ドロップ効果がなくなります。 これとは別に、円をクリックすると、円が表示リストの一番上に移動し、常に他のすべてのコンテンツの一番上に表示される方法があります。
次のコード(前の例を応用)では、円と四角形の 2 つの表示オブジェクトをマウスで移動します。いずれかのアイテム上でマウスボタンを押すたびに、そのアイテムはステージの表示リストの最上部に移動します。その結果、ドラッグされるアイテムは常に一番上に表示されます。(新しいコードと前の例から変更されたコードは、ボールド体で記述されています)。
// This code creates a drag-and-drop interaction using the mouse-following
// technique.
// circle and square are DisplayObjects (e.g. MovieClip or Sprite
// instances).
import flash.display.DisplayObject;
import flash.events.MouseEvent;
var offsetX:Number;
var offsetY:Number;
var draggedObject:DisplayObject;
// This function is called when the mouse button is pressed.
function startDragging(event:MouseEvent):void
{
// remember which object is being dragged
draggedObject = DisplayObject(event.target);
// Record the difference (offset) between where the cursor was when
// the mouse button was pressed and the x, y coordinate of the
// dragged object when the mouse button was pressed.
offsetX = event.stageX - draggedObject.x;
offsetY = event.stageY - draggedObject.y;
// move the selected object to the top of the display list
stage.addChild(draggedObject);
// Tell Flash Player to start listening for the mouseMove event.
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragObject);
}
// This function is called when the mouse button is released.
function stopDragging(event:MouseEvent):void
{
// Tell Flash Player to stop listening for the mouseMove event.
stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragObject);
}
// This function is called every time the mouse moves,
// as long as the mouse button is pressed down.
function dragObject(event:MouseEvent):void
{
// Move the dragged object to the location of the cursor, maintaining
// the offset between the cursor's location and the location
// of the dragged object.
draggedObject.x = event.stageX - offsetX;
draggedObject.y = event.stageY - offsetY;
// Instruct Flash Player to refresh the screen after this event.
event.updateAfterEvent();
}
circle.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
circle.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
square.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
square.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
トークンやカードをパイル間で移動するゲームなどでこの効果をさらに拡張するには、ドラッグされるオブジェクトを「拾う」ときにステージの表示リストに追加し、次にマウスボタンを離すときに別の表示リスト(オブジェクトがドロップされる「パイル」など)に追加します。
最後に、効果を強調するために、表示オブジェクトをクリックしたとき(ドラッグを開始したとき)にドロップシャドウフィルターを適用し、オブジェクトを解放したときにドロップシャドウを削除します。 ActionScript でのドロップシャドウフィルターや、その他の表示オブジェクトフィルターを使用する場合について詳しくは、
表示オブジェクトのフィルター処理
を参照してください。