Modifica della posizione

Flash Player 9 e versioni successive, Adobe AIR 1.0 e versioni successive

Il tipo di manipolazione più banale per un oggetto di visualizzazione è il suo posizionamento sullo schermo. Per impostare la posizione di un oggetto di visualizzazione, modificate le proprietà x e y dell'oggetto.

myShape.x = 17; 
myShape.y = 212;

Il sistema di posizionamento degli oggetti di visualizzazione tratta lo stage come un sistema di coordinate cartesiane (il comune sistema a griglia con un asse x orizzontale e un asse y verticale). L'origine del sistema di coordinate (la coordinata 0, 0, dove gli assi x e y si intersecano) si trova nell'angolo superiore sinistro dello stage. A partire da questo punto, i valori x sono positivi spostandosi verso destra e negativi verso sinistra, mentre (al contrario di ciò che avviene nei grafici tradizionali) i valori y sono positivi spostandosi verso il basso e negativi verso l'alto. Le righe di codice precedente, ad esempio, consentono di spostare l'oggetto myShape alla coordinata x 17 (17 pixel a destra dell'origine) e alla coordinata y 212 (212 pixel al di sotto dell'origine).

Per impostazione predefinita, quando un oggetto di visualizzazione viene creato in ActionScript, le proprietà x e y sono impostate su 0, in modo da collocare l'oggetto nell'angolo superiore sinistro del suo contenitore principale.

Modifica della posizione in relazione allo stage

È importante ricordare che le proprietà x e y si riferiscono sempre alla posizione dell'oggetto di visualizzazione in relazione alla coordinate 0, 0 degli assi del suo oggetto di visualizzazione principale. Di conseguenza, nel caso di un'istanza Shape (quale un cerchio) contenuta in un'istanza Sprite, l'impostazione delle proprietà x e y dell'oggetto Shape su 0 consente di posizionare il cerchio nell'angolo superiore sinistro di Sprite, che non è necessariamente l'angolo superiore sinistro dello stage. Per posizionare un oggetto in relazione alle coordinate globali dello stage, potete utilizzare il metodo globalToLocal() di un qualsiasi oggetto di visualizzazione e convertire le coordinate da globali (stage) a locali (contenitore dell'oggetto di visualizzazione), come indicato di seguito:

// Position the shape at the top-left corner of the Stage,  
// regardless of where its parent is located. 
 
// Create a Sprite, positioned at x:200 and y:200. 
var mySprite:Sprite = new Sprite(); 
mySprite.x = 200; 
mySprite.y = 200; 
this.addChild(mySprite); 
 
// Draw a dot at the Sprite's 0,0 coordinate, for reference. 
mySprite.graphics.lineStyle(1, 0x000000); 
mySprite.graphics.beginFill(0x000000); 
mySprite.graphics.moveTo(0, 0); 
mySprite.graphics.lineTo(1, 0); 
mySprite.graphics.lineTo(1, 1); 
mySprite.graphics.lineTo(0, 1); 
mySprite.graphics.endFill(); 
 
// Create the circle Shape instance. 
var circle:Shape = new Shape(); 
mySprite.addChild(circle); 
 
// Draw a circle with radius 50 and center point at x:50, y:50 in the Shape. 
circle.graphics.lineStyle(1, 0x000000); 
circle.graphics.beginFill(0xff0000); 
circle.graphics.drawCircle(50, 50, 50); 
circle.graphics.endFill(); 
 
// Move the Shape so its top-left corner is at the Stage's 0, 0 coordinate. 
var stagePoint:Point = new Point(0, 0); 
var targetPoint:Point = mySprite.globalToLocal(stagePoint); 
circle.x = targetPoint.x; 
circle.y = targetPoint.y;

Allo stesso modo, potete utilizzare il metodo localToGlobal() della classe DisplayObject per convertire le coordinate locali nelle coordinate dello stage.

Spostamento di oggetti di visualizzazione con il mouse

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 .