ActionScript에서는 두 가지 다른 기법을 사용하여 사용자가 마우스로 표시 객체를 이동할 수 있도록 설정할 수 있습니다. 두 방법 모두 두 마우스 이벤트가 사용됩니다. 즉, 마우스 버튼을 누르면 마우스 커서를 따라 이동하도록 객체에게 지시하고, 마우스 버튼을 놓으면 마우스 커서를 따라 이동하는 것을 중지하도록 객체에게 지시합니다.
참고:
Flash Player 11.3 이상 및 AIR 3.3 이상: MouseEvent.RELEASE_OUTSIDE 이벤트를 사용하여 사용자가 포함 Sprite 경계 외부에서 마우스 버튼을 놓는 경우에 대응할 수도 있습니다.
startDrag()
메서드를 사용하는 첫 번째 기법은 더 간단하지만 보다 제한적입니다. 마우스 버튼을 누르면 드래그할 표시 객체의
startDrag()
메서드가 호출됩니다. 마우스 버튼을 놓으면
stopDrag()
메서드가 호출됩니다. Sprite 클래스는 이러한 두 함수를 정의하므로 이동된 객체는 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()
를 사용하여 한 번에 하나의 항목만 드래그할 수 있다는 한 가지 중요한 제한이 있습니다. 표시 객체를 드래그하는 중에
startDrag()
메서드가 다른 표시 객체에서 호출되면, 마우스를 따라 이동하던 첫 번째 표시 객체의 이동이 즉시 중지됩니다. 예를 들어,
startDragging()
함수가 아래에 표시된 것처럼 변경되면
square.startDrag()
메서드를 호출하더라도
circle
객체만 드래그됩니다.
function startDragging(event:MouseEvent):void
{
square.startDrag();
circle.startDrag();
}
startDrag()
를 사용하여 객체를 한 번에 하나씩만 드래그할 수 있기 때문에, 임의의 표시 객체에 대해
stopDrag()
메서드를 호출하여 현재 드래그 중인 객체의 이동을 중지시킬 수 있습니다.
여러 표시 객체를 드래그해야 하거나 여러 객체가
startDrag()
를 사용하여 발생할 수 있는 충돌을 방지하려면 mouse-following 기술을 사용하여 드래그 효과를 만드는 것이 좋습니다. 이 기술을 사용할 경우 마우스 버튼을 누르면 함수가 스테이지의
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);
표시 객체를 마우스 커서를 따라 이동하게 하는 것 외에도, 드래그된 객체를 표시의 전면으로 이동시켜 모든 다른 객체 위에 떠 있는 것처럼 보이게 해야 할 수 있습니다. 예를 들어 원과 정사각형의 두 객체가 있고 두 객체 모두 마우스로 이동할 수 있다고 가정해보십시오. 원이 표시 목록에서 사각형의 아래에 있을 때 원을 클릭한 상태에서 드래그하여 커서를 사각형 위에 놓으면, 원이 사각형 뒤로 서서히 이동하는 것처럼 표시되어 드래그 앤 드롭 효과가 제거됩니다. 대신 원을 클릭하면 원이 표시 목록의 맨 위로 이동하여 항상 다른 내용의 위에 표시되게 할 수 있습니다.
앞의 예제에서 가져온 다음 코드에서는 원과 정사각형인 두 표시 객체를 마우스로 이동할 수 있도록 합니다. 어느 한 객체를 마우스 버튼으로 누르면 해당 항목이 스테이지 표시 목록의 위로 이동하여 드래그된 항목이 항상 위에 표시됩니다. 새 코드나 이전 샘플에서 변경된 코드는 굵은 글꼴로 표시됩니다.
// 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에서 그림자 필터 및 기타 표시 객체 필터를 사용하는 방법에 대한 자세한 내용은
표시 객체 필터링
을 참조하십시오.