Modification de la position

Flash Player 9 et les versions ultérieures, Adobe AIR 1.0 et les versions ultérieures

La manipulation la plus fondamentale de tout objet d’affichage consiste à le positionner à l’écran. Pour définir la position d’un objet d’affichage, changez ses propriétés x et y.

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

Le système de positionnement d’un objet d’affichage assimile la scène à un système de coordonnées cartésiennes (système de grille standard doté d’un axe horizontal x et d’un axe vertical y). L’origine du système de coordonnées (coordonnée 0,0 correspondant à l’intersection des axes x et y) figure dans le coin supérieur gauche de la scène. A partir de l’origine, les valeurs x sont positives vers la droite et négatives vers la gauche, tandis que, contrairement aux systèmes de graphes standard, les valeurs y sont positives vers le bas et négatives vers le haut. Par exemple, les lignes précédentes de code déplacent l’objet myShape vers la coordonnée x 17 (17 pixels sur la droite de l’origine) et la coordonnée y 212 (212 pixels sous l’origine).

Par défaut, lorsqu’un objet d’affichage est créé dans ActionScript, les propriétés x et y sont toutes deux définies sur 0, plaçant ainsi l’objet dans le coin supérieur gauche de son contenu parent.

Modification de la position relativement à la scène

Il est important de se rappeler que les propriétés x et y se réfèrent toujours à la position de l’objet d’affichage par rapport aux coordonnées 0,0 des axes de son objet d’affichage parent. Ainsi, pour une occurrence de Shape (par exemple un cercle) contenue dans une occurrence de Sprite, mettre à zéro les propriétés x et y de l’objet Shape revient à placer le cercle dans le coin supérieur gauche de l’objet Sprite, qui n’est pas forcément le coin supérieur gauche de la scène. Pour positionner un objet par rapport aux coordonnées globales de la scène, utilisez la méthode globalToLocal() de tout objet d’affichage afin de convertir les coordonnées globales (scène) en coordonnées locales (conteneur de l’objet d’affichage), comme suit :

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

Vous pouvez également utiliser la méthode localToGlobal() de la classe DisplayObject pour convertir les coordonnées locales en coordonnées de la scène.

Déplacement des objets d’affichage à l’aide de la souris

Vous pouvez autoriser un utilisateur à déplacer les objets d’affichage à l’aide de la souris par le biais de deux techniques distinctes dans ActionScript. Dans les deux cas, deux événements de souris sont utilisés : lorsque l’utilisateur appuie sur le bouton de gauche (l’objet reçoit alors l’instruction de suivre le curseur de la souris) et lorsqu’il le relâche (l’objet reçoit alors l’instruction de cesser de suivre le curseur de la souris).

Remarque : Flash Player 11.3 et les versions ultérieures et AIR 3.3 et les versions ultérieures : vous pouvez également utiliser l’événement MouseEvent.RELEASE_OUTSIDE dans le cas d’un utilisateur qui relâche le bouton de la souris en dehors des limites du Sprite conteneur.

La première technique, basée sur la méthode startDrag(), est plus simple, mais plus limitée. Lorsque l’utilisateur appuie sur le bouton de la souris, la méthode startDrag() de l’objet d’affichage à faire glisser est appelée. Lorsque l’utilisateur relâche le bouton de la souris, la méthode stopDrag() est appelée. Puisque la classe Sprite définit ces deux fonctions, l’objet déplacé doit être un Sprite ou l’une de ses sous-classes.

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

Cette technique présente un désavantage relativement important : l’utilisation de startDrag() ne permet de faire glisser qu’un seul élément à la fois. Si un objet d’affichage est en cours de glissement et que la méthode startDrag() est appelée sur un autre objet d’affichage, le premier objet cesse immédiatement de suivre la souris. Par exemple, si la fonction startDragging() est modifiée comme indiqué, seul l’objet circle est déplacé par glissement, bien que la méthode square.startDrag() ait été appelée :

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

Puisqu’un seul objet à la fois peut être déplacé par glissement par le biais de startDrag(), la méthode stopDrag() peut être appelée sur n’importe quel objet d’affichage et arrête tout objet en cours de glissement.

Pour déplacer plusieurs objets d’affichage, ou pour éviter tout risque de conflit au cas où plusieurs objets seraient susceptibles d’utiliser startDrag(), il est préférable d’utiliser la technique de suivi de la souris pour créer l’effet de glisser-déposer. Avec cette technique, lorsque l’utilisateur appuie sur le bouton de la souris, une fonction est enregistrée en tant qu’écouteur de l’événement mouseMove de la scène. Cette fonction, qui est alors appelée à chaque déplacement de la souris, entraîne le saut de l’objet déplacé vers la coordonnée x, y de la souris. Une fois le bouton de la souris relâché, la fonction n’est plus enregistrée en tant qu’écouteur. Elle n’est donc plus appelée lorsque la souris est déplacée et l’objet cesse de suivre le curseur. Le code suivant illustre cette technique :

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

Outre le suivi du curseur par un objet d’affichage, il est souvent préférable de positionner l’objet déplacé à l’avant de l’affichage, créant ainsi une impression de flottement au-dessus de tous les autres objets. Supposons, par exemple, que deux objets, un cercle et un carré, puissent tous deux être déplacés à l’aide de la souris. Si le cercle figure sous le carré sur la liste d’affichage et que vous cliquez et faites glisser le cercle pour placer le curseur au-dessus du carré, il semble glisser derrière le carré, brisant ainsi l’illusion du glisser-déposer. Vous pouvez procéder de sorte que lorsque vous cliquez sur le cercle, il passe en première position dans la liste d’affichage et s’affiche ainsi par-dessus tout autre contenu.

Le code suivant (adapté de l’exemple précédent) permet de déplacer deux objets d’affichage, un cercle et un carré, à l’aide de la souris. Lorsque le bouton de la souris est pressé au-dessus de l’un d’eux, cet élément est amené en haut de la liste d’affichage de la scène, afin que l’élément déplacé passe toujours devant les autres. (Tout nouveau code ou code modifié extrait du code précédent est imprimé en gras.)

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

Pour créer un effet plus sophistiqué, par exemple pour un jeu où des jetons ou des cartes passent d’une pile à l’autre, il est possible d’ajouter l’objet déplacé à la liste d’affichage de la scène lorsqu’il est « pris », puis de l’ajouter à une autre liste d’affichage (la « pile » sur laquelle il est déposé) lors du relâchement du bouton de souris.

Enfin, pour optimiser l’effet, vous pourriez appliquer un filtre Ombre portée à l’objet d’affichage lorsque vous cliquez dessus (en début de glissement) et supprimer l’ombre portée lorsque vous relâchez l’objet. Pour plus d’informations sur le filtre Ombre portée et tout autre filtre appliqué aux objets d’affichage en ActionScript, voir Filtrage des objets d’affichage.