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
.