Изменение положения

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

Наиболее основная операция, применяющаяся к любому экранному объекту, заключается в размещении его на экране. Чтобы задать положение экранного объекта, измените свойства x и y объекта.

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

Система размещения экранных объектов воспринимает рабочую область как декартову систему координат (обычная сетка с горизонтальной осью x и вертикальной осью y). Начальная точка системы координат (точка с координатами 0,0, где перекрещиваются оси x и y) находится в верхнем левом углу рабочей области. Отсюда по оси x вправо идут положительные значения, а влево — отрицательные, в то время как положительные значения по оси y направлены вниз, а отрицательные — вверх (в отличие от типичных графических систем). Например, предыдущие строки кода приводят к перемещению объекта myShape в точку с координатой 17 по оси x (17 пикселов вправо от начальной точки) и с координатой 212 по оси y (212 пикселов вниз от начальной точки).

Когда экранный объект создается с помощью ActionScript, свойства x и y по умолчанию принимают значение 0, а объект помещается в левом верхнем углу родительского содержимого.

Изменение положения относительно рабочей области

Важно помнить, что свойства x и y всегда относятся к позиции экранного объекта относительно точки с координатами 0,0 относительно осей родительского экранного объекта. Для экземпляра Shape (например, круга), содержащегося в экземпляре Sprite, присваивание свойствам x и y значения 0 приводит к размещению круга в верхнем левом углу спрайта, который не обязательно совпадает с левым верхним углом рабочей области. Чтобы разместить объект относительно глобальных координат рабочей области, можно воспользоваться методом globalToLocal() любого экранного объекта, чтобы преобразовать координаты из глобальных (рабочая область) в локальные (контейнер экранного объекта). Например, следующим образом:

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

Кроме того, можно воспользоваться методом localToGlobal() класса DisplayObject, чтобы преобразовать локальные координаты в координаты рабочей области.

Перемещение экранных объектов с помощью мыши

Пользователю можно предоставить возможность перемещать экранные объекты с помощью мыши, используя два разных приема в 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() изменяется так, как здесь показано, будет перетаскиваться только объект circle, несмотря на вызов метода square.startDrag():

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

Из-за того, что одновременно с помощью метода startDrag() можно перетащить только один объект, метод stopDrag() можно вызвать по отношению к любому экранному объекту. При этом перетаскивание любого другого объекта останавливается.

Если вам необходимо перетащить более одного экранного объекта или избежать возможных конфликтов, которые возникают, когда метод startDrag() используется более чем одним объектом, используйте технику следования за мышью, чтобы добиться эффекта перетаскивания. В случае данной техники когда нажимается кнопка, функция регистрируется в качестве прослушивателя события 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 см. в разделе «Фильтрация экранных объектов».