Zmiana położenia

Flash Player 9 i nowsze wersje, Adobe AIR 1.0 i nowsze wersje

Do najprostszych manipulacji, jakim można poddać obiekt wyświetlany, należy określić jego położenia na ekranie. Aby określić położenie obiektu wyświetlanego, należy zmienić właściwości x i y obiektu.

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

System określania położenia obiektu wyświetlanego traktuje stół montażowy jako kartezjański układ współrzędnych (układ siatkowy z poziomą osią x i pionową osią y). Początek układu współrzędnych (punkt 0,0, w którym spotykają się osie x i y) znajduje się w lewym górnym rogu stołu montażowego. Z tego miejsca współrzędne x przyjmują wartości dodatnie w prawo i ujemne w lewo, a współrzędne y (w odróżnieniu od typowych systemów graficznych) przyjmują wartości dodatnie w dół, a ujemne w górę. Na przykład: poprzednie linie kodu powodują przesunięcie obiektu myShape do współrzędnej x 17 (17 pikseli w prawo od początku układu) oraz do współrzędnej y 212 (212 pikseli pod początkiem układu).

Domyślnie: gdy obiekt wyświetlany zostanie utworzony za pomocą języka ActionScript, wówczas właściwości x i y otrzymują wartości 0, co powoduje, że obiekt zostaje umieszczony w lewym górnym rogu jego treści nadrzędnej.

Zmiana położenia względem stołu montażowego

Należy pamiętać o tym, że współrzędne x i y zawsze odnoszą się do położenia konkretnego obiektu wyświetlanego względem położenia 0,0 na osiach nadrzędnego obiektu wyświetlanego. Ustawienie dla instancji Shape (np. okręgu), która znajduje się w instancji Sprite, współrzędnych x i y na wartość 0 spowoduje umieszczenie okręgu w lewym górnym rogu instancji Sprite, a to położenie niekoniecznie musi być lewym górnym rogiem stołu montażowego. Aby umiejscowić obiekt względem współrzędnych globalnego stołu montażowego, można użyć metody globalToLocal() dowolnego obiektu wyświetlanego w celu konwersji współrzędnych globalnych (stół montażowy) na współrzędne lokalne (kontener obiektu wyświetlanego) w następujący sposób:

// 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;

W podobny sposób można wykorzystać metodę localToGlobal() klasy DisplayObject w celu konwersji lokalnych współrzędnych na współrzędne stołu montażowego.

Przesuwanie obiektów wyświetlanych za pomocą myszy

W języku ActionScript dostępne są dwie techniki, dzięki którym użytkownik może przenosić obiekty wyświetlane za pomocą myszy. W każdej z tych technik wykorzystywane są dwa zdarzenia myszy: po naciśnięciu przycisku myszy obiekt otrzymuje polecenie przesuwania zgodnie z kursorem myszy, a po zwolnieniu przycisku obiekt otrzymuje polecenie przerwania ruchu zgodnie z kursorem.

Uwaga: Program Flash Player 11.3 i nowszy, środowisko AIR 3.3 i nowsze: Przypadek zwolnienia przycisku myszy przez użytkownika poza obwiednią obiektu Sprite można także obsłużyć za pomocą zdarzenia MouseEvent.RELEASE_OUTSIDE.

Pierwsza technika, w której wykorzystana jest metoda startDrag() , jest prosta, ale wiąże się z większymi ograniczeniami. Po naciśnięciu przycisku myszy następuje wywołanie metody startDrag() obiektu wyświetlanego, który ma zostać przeciągnięty. Gdy przycisk myszy zostanie zwolniony, następuje wywołanie metody stopDrag() . Te dwie funkcje definiuje klasa Sprite, dlatego obiekt przenoszony musi być instancją klasy Sprite lub jednej z jej podklas.

// 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);

W przypadku tej techniki obowiązuje jedno ograniczenie o średniej istotności: za pomocą metody startDrag() można przeciągać tylko jeden element jednocześnie. Jeśli przeciągany jest jeden obiekt wyświetlany i nastąpi wywołanie metody startDrag() dla innego obiektu wyświetlanego, wówczas pierwszy obiekt wyświetlany przestaje przesuwać się zgodnie z kursorem myszy. Na przykład: jeśli funkcja startDragging() zostanie zmieniona w sposób przedstawiony poniżej, tylko obiekt circle będzie przeciągany pomimo wywołania metody square.startDrag() :

function startDragging(event:MouseEvent):void 
{ 
    square.startDrag(); 
    circle.startDrag(); 
}

W konsekwencji faktu, że jednocześnie przeciągany może być tylko jeden obiekt startDrag() , metoda stopDrag() może zostać wywołana dla dowolnego obiektu wyświetlanego i zatrzymuje aktualnie przeciągany obiekt.

Jeśli wymagane jest przeciąganie więcej niż jednego obiektu wyświetlanego lub konieczne jest uniknięcia konfliktów w sytuacji, gdy więcej niż jeden obiekt może korzystać z metody startDrag() , wówczas najlepiej jest wykorzystać technikę śledzenia myszy w celu uzyskania efektu przeciągania. W przypadku tej techniki naciśnięcie przycisku myszy powoduje zasubskrybowanie funkcji jako detektora zdarzenia mouseMove na stole montażowym. Ta funkcja, wywoływana następnie przy każdym ruchu myszy, sprawia, że przeciągany obiekt przeskakuje do współrzędnych x, y kursora myszy. Po zwolnieniu przycisku myszy następuje anulowanie subskrypcji funkcji jako detektora, co oznacza, że funkcja nie jest wywoływana przy ruchu myszy i obiekt przestaje śledzić kursor. Poniżej przedstawiono kod, który demonstruje tę technikę:

// 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);

Często — oprócz tego, że obiekt wyświetlany śledzi kursor myszy — wymagane jest, aby przenoszony obiekt znajdował się na pierwszym planie, dlatego wydaje się, że unosi się on nad innymi obiektami. Na przykład: załóżmy, że istnieją dwa obiekty: okrąg i kwadrat, które można przenosić za pomocą myszy. Jeśli okrąg znajduje się poniżej kwadratu na liście wyświetlania i okrąg zostanie kliknięty, a następnie kursor zostanie przeciągnięty nad kwadrat, wówczas okrąg zsunie się za kwadrat, co spowoduje przerwanie wrażenia „przeciągania i upuszczania”. Możliwe jest również wybranie takiej konfiguracji, w której kliknięcie okręgu powoduje jego przesunięcie na górę listy wyświetlania, a wówczas okrąg będzie zawsze widoczny na wierzchu innych obiektów.

Poniższy kod (zmodyfikowana wersja poprzedniego kodu) umożliwia przeniesienie za pomocą myszy dwóch obiektów wyświetlanych: okręgu i kwadratu. Naciśnięcie przycisku myszy nad dowolnym z tych elementów powoduje przesunięcie tego elementu na górę listy wyświetlania stołu montażowego, dlatego przeciągany element jest widoczny na wierzchu. (Kod nowy lub zmieniony w porównaniu z poprzednim fragmentem został wyróżniony czcionką pogrubioną.)

// 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);

W celu dodatkowego wykorzystania tego efektu, np. dla gry, w której token lub karty są przesuwane w stosach, można dodać przeciągany obiekt do listy wyświetlania stołu montażowego po jego „wybraniu”, a następnie dodać go do drugiej listy wyświetlania — np. do listy stosu, w którym zostanie upuszczony — po zwolnieniu przycisku myszy.

Ostatecznie w celu udoskonalenia efektu można zastosować filtr cienia dla obiektu wyświetlanego po jego kliknięciu (po rozpoczęciu przeciągania), a następnie usunąć cień po zwolnieniu przycisku myszy. Szczegółowe informacje na temat korzystania z filtrów cienia i innych filtrów obiektów wyświetlanych w języku ActionScript zawiera sekcja Filtrowanie obiektów wyświetlanych .