El usuario puede mover los objetos de visualización con el ratón utilizando dos diferentes técnicas en ActionScript. En cualquier caso, se utilizan dos eventos de ratón: cuando se presiona el botón del ratón el objeto recibe la orden de seguir al cursor del ratón y, cuando se suelta el botón, recibe la orden de dejar de seguirlo.
Nota:
Flash Player 11.3 y versiones posteriores, AIR 3.3 y versiones posteriores: también puede utilizar el evento MouseEvent.RELEASE_OUTSIDE para el caso de usuarios que sueltan el botón fuera de los límites del contenedor Sprite.
La primera técnica consiste en usar el método
startDrag()
y es más sencilla pero también más limitada. Cuando se presiona el botón del ratón, se llama al método
startDrag()
del objeto de visualización que se va a arrastrar. Cuando se suelta el botón del ratón, se llama el método
stopDrag()
. La clase Sprite define estas dos funciones, por lo que el objeto movido debe ser una clase Sprite o una de sus subclases.
// 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);
Esta técnica presenta una limitación realmente importante: con
startDrag()
únicamente se puede arrastrar un elemento cada vez. Si se arrastra un objeto de visualización y se llama al método
startDrag()
en otro objeto de visualización, el primer objeto deja de seguir al ratón inmediatamente. Por ejemplo, si se cambia la función
startDragging()
como se muestra aquí, solo se arrastrará el objeto
circle
, en lugar de la llamada al método
square.startDrag()
:
function startDragging(event:MouseEvent):void
{
square.startDrag();
circle.startDrag();
}
Como consecuencia de poder arrastrar un solo objeto cada vez cuando se usa
startDrag()
, es posible llamar al método
stopDrag()
en cualquier objeto de visualización y detenerlo sea cual sea el objeto que se esté arrastrando.
Si se necesita arrastrar más de un objeto de visualización o evitar la posibilidad de conflictos porque más de un objeto pueda utilizar
startDrag()
, se recomienda usar la técnica de seguimiento del ratón para crear el efecto de arrastre. Con esta técnica, cuando se presiona el botón del ratón, se suscribe una función al evento
mouseMove
del escenario, como detector. Esta función, que se llama cada vez que se mueve el ratón, hace que el objeto arrastrado salte a las coordenadas x, y del ratón. Cuando se suelta el botón del ratón, se quita la suscripción de la función como detector, de modo que ya no se llama cuando se mueve el ratón y el objeto deja de seguir al cursor del ratón. En el código siguiente se muestra esta técnica:
// 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);
Además de hacer que un objeto de visualización siga al cursor del ratón, suele ser conveniente mover el objeto arrastrado al frente de la pantalla, de modo que parezca que flota sobre todos los demás objetos. Por ejemplo, supongamos que se dispone de dos objetos, un círculo y un cuadrado, y que ambos se pueden mover con el ratón. Si el círculo está por debajo del cuadrado en la lista de visualización, y se hace clic en el círculo y se arrastra de modo que el cursor quede sobre el cuadrado, el círculo parecerá deslizarse detrás del cuadrado, rompiendo así la ilusión de arrastrar y colocar. En lugar de eso, se puede hacer que el círculo se mueva a la parte superior de la lista de visualización cuando se hace clic en él, de modo que el círculo siempre aparezca encima de cualquier otro contenido.
El siguiente código (adaptado del ejemplo anterior) permite que dos objetos de visualización, un círculo y un cuadrado, se muevan con el ratón. Cuando se presiona el botón del ratón sobre cualquiera de los dos, el elemento en cuestión se mueve a la parte superior de la lista de visualización del escenario, de modo que el elemento arrastrado aparece siempre encima. (El código nuevo o cambiado con respecto a la lista anterior aparece en negrita.)
// 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);
Para aumentar este efecto, por ejemplo en un juego en el que se mueven fichas o cartas entre distintas pilas, se podría añadir el objeto arrastrado a la lista de visualización del escenario cuando se selecciona y luego añadirlo a otra lista de visualización (por ejemplo, la pila donde se coloca), cuando se suelta el botón del ratón.
Finalmente, para mejorar el efecto, se podría aplicar un filtro de sombra al objeto de visualización al hacer clic en él (al iniciar el arrastre) y quitar la sombra al soltar el objeto. Para obtener información detallada sobre el uso del filtro de sombra y otros filtros de objetos de visualización en ActionScript, consulte
Aplicación de filtros a objetos de visualización
.