Potete permettere a un utente di spostare oggetti di visualizzazione con il mouse utilizzando due diverse tecniche in ActionScript. In entrambi i casi vengono utilizzati due eventi del mouse: quando il pulsante del mouse viene premuto, l'oggetto deve seguire il cursore del mouse, mentre quando il pulsante viene rilasciato, l'oggetto deve bloccarsi nella posizione in cui si trova.
Nota:
Flash Player 11.3 e versioni successive, AIR 3.3 e versioni successive: è anche possibile usare l'evento MouseEvent.RELEASE_OUTSIDE per il caso in cui l'utente rilascia il pulsante del mouse all'esterno dei limiti dello Sprite contenitore.
La prima tecnica, che prevede l'uso del metodo
startDrag()
, è la più semplice, ma presenta dei limiti. Quando il pulsante del mouse viene premuto, viene chiamato il metodo
startDrag()
dell'oggetto di visualizzazione da trascinare. Quando il pulsante del mouse viene rilasciato, viene chiamato il metodo
stopDrag()
. La classe Sprite definisce queste due funzioni, pertanto l'oggetto spostato deve essere di tipo Sprite o una delle sue sottoclassi.
// 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);
Questa tecnica presenta tuttavia un limite significativo: il metodo
startDrag()
consente di trascinare un solo elemento per volta. Se un oggetto di visualizzazione viene trascinato e il metodo
startDrag()
viene chiamato su un altro oggetto di visualizzazione, il primo oggetto cessa immediatamente di seguire il mouse. Se, ad esempio, la funzione
startDragging()
viene modificata come illustrato di seguito, viene trascinato solo l'oggetto
circle
, nonostante la chiamata del metodo
square.startDrag()
:
function startDragging(event:MouseEvent):void
{
square.startDrag();
circle.startDrag();
}
Come conseguenza del fatto che un solo oggetto per volta può essere trascinato con il metodo
startDrag()
, il metodo
stopDrag()
può essere chiamato per bloccare qualsiasi oggetto di visualizzazione in fase di trascinamento.
Se dovete trascinare più di un oggetto di visualizzazione o volete evitare conflitti quando più di un oggetto può potenzialmente usare il metodo
startDrag()
, è opportuno utilizzare la tecnica di inseguimento del mouse per ottenere l'effetto di trascinamento. Con questa tecnica, quando il pulsante del mouse viene premuto, una funzione viene registrata come listener dell'evento
mouseMove
sullo stage. Tale funzione, che in seguito verrà chiamata ogni volta che il mouse si muove, provoca lo spostamento dell'oggetto trascinato in corrispondenza delle coordinate x, y del mouse. Quando il pulsante del mouse viene rilasciato, la registrazione della funzione come listener viene annullata, in modo che la funzione non venga più chiamata a ogni movimento del mouse e l'oggetto cessi di seguire il cursore. Il codice seguente illustra tale tecnica:
// 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);
Oltre a fare in modo che un oggetto di visualizzazione segua il cursore del mouse, è spesso consigliabile spostare l'oggetto trascinato sul livello superiore dello schermo, in modo che sembri fluttuare sopra gli altri oggetti. Ad esempio, supponete di avere due oggetti, un cerchio e un quadrato, che possono essere entrambi spostati con il mouse. Se il cerchio si trova al di sotto del quadrato nell'elenco di visualizzazione e fate clic sul cerchio per trascinarlo facendolo passare sopra il quadrato, il cerchio verrà fatto scorrere sotto il quadrato, interrompendo l'illusione di trascinamento. Per evitare il problema, si può fare in modo che facendo clic sul cerchio, esso venga automaticamente spostato in cima all'elenco di visualizzazione, in modo che, quando viene trascinato, appaia sempre al di sopra di qualsiasi altro oggetto presente sullo stage.
Il codice seguente (adattato dall'esempio precedente) consente di spostare con il mouse due oggetti di visualizzazione: un cerchio e un quadrato. Ogni volta che il pulsante del mouse viene premuto su uno dei due elementi, esso viene spostato al primo posto nell'elenco di visualizzazione dello stage, in modo che risulti sempre in primo piano quando viene trascinato. (Il codice nuovo o modificato rispetto all'esempio precedente è visualizzato in grassetto.)
// 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);
Per estendere ulteriormente l'effetto, come nel caso di un gioco in cui gettoni o carte vengono spostati da una pila a un'altra, potete inserire l'oggetto trascinato nell'elenco di visualizzazione dello stage quando viene “raccolto”, quindi inserirlo in un altro elenco di visualizzazione (ad esempio quello della “pila” dove viene depositato) al momento del rilascio del pulsante del mouse.
Infine, per migliorare l'effetto, potete applicare un filtro ombra esterna all'oggetto di visualizzazione quando viene selezionato mediante clic del mouse (all'inizio del trascinamento) per poi rimuoverlo quando l'oggetto viene rilasciato. Per ulteriori informazioni sull'uso del filtro ombra esterna e di altri filtri per gli oggetti di visualizzazione in ActionScript, vedete
Filtraggio degli oggetti di visualizzazione
.