Du kan göra det möjligt för en användare att flytta visningsobjekt med musen på två olika sätt i ActionScript. I båda fallen används två mushändelser: när musknappen trycks ner följer objektet med musmarkörens rörelse och när knappen släpps stannar objektet.
Obs!
Flash Player 11.3 och senare, AIR 3.3 och senare: Du kan även använda händelsen MouseEvent.RELEASE_OUTSIDE för att täcka in de fall då en användare släpper upp musknapen utanför gränserna för aktuellt Sprite.
Det första sättet, med metoden
startDrag()
, är enklare men mer begränsat. När musknappen trycks ner anropas metoden
startDrag()
för visningsobjektet som ska dras. När musknappen släpps anropas metoden
stopDrag()
. Sprite-klassen definierar dessa två funktioner, och objektet som ska flyttas måste därför bestå av ett Sprite-objekt eller någon av dess underklasser.
// 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);
Den här tekniken har en viktig begränsning: endast ett objekt i taget kan dras med
startDrag()
. Om ett visningsobjekt dras och metoden
startDrag()
anropas för ett annat visningsobjekt upphör det första visningsobjektet genast att följa musrörelsen. Om till exempel funktionen
startDragging()
ändras kommer endast objektet
circle
att dras, trots metodanropet
square.startDrag()
:
function startDragging(event:MouseEvent):void
{
square.startDrag();
circle.startDrag();
}
Som en konsekvens av faktumet att endast ett objekt i taget kan dras via
startDrag()
kan metoden
stopDrag()
anropas för valfritt visningsobjekt och pågående objekt som dras kommer att stoppas.
Om du behöver dra fler än ett visningsobjekt, eller för att undvika en möjlig konflikt där fler än ett objekt kanske används med
startDrag()
, så är det bättre att använda den musföljande tekniken för att skapa drageffekten. När musknappen trycks ner och den här tekniken används agerar en funktion som avlyssnare för händelsen
mouseMove
på scenen. Med den här funktionen, som sedan anropas varje gång musen flyttas, hoppar objektet som dras till musens x,y-koordinat. När musknappen släpps slutar funktionen att agera som avlyssnare, vilket innebär att den inte längre anropas vid musrörelser och objektet upphör att följa efter musmarkören. Här följer ett kodexempel som visar tekniken:
// 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);
Förutom att få ett visningsobjekt att följa efter musmarkören vill du kanske kunna flytta objektet längst fram på skärmen, så att det verkar flyta över alla andra objekt. Anta till exempel att du har två objekt, en cirkel och en kvadrat, som båda kan flyttas med musen. Om cirkeln råkar vara under fyrkanten på visningslistan och du klickar och drar cirkeln så att markören hamnar över fyrkanten så kommer cirkeln att läggas bakom fyrkanten, vilket bryter dra och släpp-illusionen. I stället kan du göra så att när cirkeln klickas, så flyttas den högst upp i visningslistan och på så vis läggs den framför annat innehåll.
Med följande kod (anpassad från det tidigare exemplet) kan du få två visningobjekt, en cirkel och en kvadrat, att flyttas med hjälp av musen. När musknappen trycks ner över någotdera objekt så flyttas det högst upp i scenens visningslista. Då hamnar det dragna objektet alltid överst. (Kod som är ny eller ändrad sedan föregående listning visas med fet stil.)
// 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);
Effekten kan utökas ytterligare, i till exempel spel där token eller kort flyttas mellan högar, genom att det dragna objektet läggs till scenens visningslista när det ”plockas upp”. Därefter lägger du objektet i en annan visningslista, t.ex. ”högen” där det lämnades, när musknappen släpps.
Slutligen, för att förstärka effekten, kan du använda ett skuggfilter på visningsobjektet när det klickas (och dras) och ta bort skuggan när objektet släpps. Mer information om hur du använder skuggfilter och andra visningsobjektfilter i ActionScript finns i
Filtrera visningsobjekt
.