Search code examples
actionscript-3flashflash-cs5flash-cs4flash-cs6

Dragging movie clips in Action Script 3


Hi so recently I have been attempting to Drag a movie clip in AS3 but I'm having some trouble picking up with the hit tests anyone got any ideas? Just to clarify, the issue is that when the movieclips hit the drag test object, they're not executing the gotoframe() function. initDrag() adds action listeners: MOUSE_DOWN on the object MOUSE_UP on the stage so it doesn’t matter if you are off the object

endDrag() removes the action listeners; call this (for each object) before you go to another frame

startADrag()create a rectangle within which the object can be dragged (in this case the stage) call startDrag() on the object

stopADrag() call stopDrag() on the object from currentObject (but only if currentObject is not null).

var currentObject:MovieClip = null;
initDrag(block1);
initDrag(block2);
initDrag(block3);
initDrag(block4);

function initDrag(obj:MovieClip )
{
    obj.addEventListener(MouseEvent.MOUSE_DOWN,startADrag);
    stage.addEventListener(MouseEvent.MOUSE_UP,stopADrag);
}
function endDrag(obj:MovieClip )
{
    obj.removeEventListener(MouseEvent.MOUSE_DOWN,startADrag);
    stage.removeEventListener(MouseEvent.MOUSE_UP,stopADrag);
}
function startADrag(e:MouseEvent):void
{
    currentObject = (MovieClip)(e.target);
    var rect:Rectangle = new Rectangle(0,0,stage.stageWidth - currentObject.width,stage.stageHeight - currentObject.height + 100);
    currentObject.startDrag(false,rect);
}
function stopADrag(e:MouseEvent):void
{
    if (currentObject != null)
    {
        currentObject.stopDrag();
    }
}
if(block1.hitTestObject(dragtest)){
gotoAndStop("lose");
}
if(block2.hitTestObject(dragtest)){
    gotoAndStop(27);
}
if(block3.hitTestObject( dragtest)){
    gotoAndStop("lose");

}
if(block4.hitTestObject( dragtest)){
gotoAndStop("lose");
}

thanks for any advice or answers.


Solution

  • The following code should work as expected. The problem is, as i already stated in my comment, that your calls to hitTestObject(obj) only get executed once, at the very beginning of your application. What you need to do though is to check it constantly.

    Think about it, if your calls to hitTestObject-calls only get executed once at the beginning, when you didn't even have a chance to drag one of your objects, it will always return false, right? Because your objects are still in their initial position (outside of the dragtest objecti must assume).

    With an event listener for Event.ENTER_FRAME you check it once per frame instead. So even if all the results for hitTestObject are false, it will check them all again on the next frame (if you are currently dragging, controlled through a simple boolean called dragging).

    var currentObject:MovieClip = null;
    var dragging:Boolean = false;
    initDrag(block1);
    initDrag(block2);
    initDrag(block3);
    initDrag(block4);
    
    addEventListener(Event.ENTER_FRAME, checkForHit);
    
    function checkForHit(e:Event):void{
        if(dragging){
            if(block1.hitTestObject(dragtest)){
                 gotoAndStop("lose");
            }
            if(block2.hitTestObject(dragtest)){
                 gotoAndStop(27);
            }
            if(block3.hitTestObject( dragtest)){
                gotoAndStop("lose");
            }
            if(block4.hitTestObject( dragtest)){
                gotoAndStop("lose");
            }
        }
    }
    
    function initDrag(obj:MovieClip )
    {
        obj.addEventListener(MouseEvent.MOUSE_DOWN,startADrag);
        stage.addEventListener(MouseEvent.MOUSE_UP,stopADrag);
    }
    function endDrag(obj:MovieClip )
    {
        obj.removeEventListener(MouseEvent.MOUSE_DOWN,startADrag);
        stage.removeEventListener(MouseEvent.MOUSE_UP,stopADrag);
    }
    function startADrag(e:MouseEvent):void
    {
        currentObject = (MovieClip)(e.target);
        var rect:Rectangle = new Rectangle(0,0,stage.stageWidth - currentObject.width,stage.stageHeight - currentObject.height + 100);
        currentObject.startDrag(false,rect);
        dragging = true;
    }
    function stopADrag(e:MouseEvent):void
    {
        if (currentObject != null)
        {
            currentObject.stopDrag();
            dragging = false;
        }
    }