Flash AS3-将多个对象拖放到多个目标

时间:2018-11-11 05:05:38

标签: actionscript-3 flash

我有多个对象可以拖到多个目标。 我有没有错误的代码。 我正在使用多种功能。但是我不知道是否通过一个函数(如dropIt)传递对象和特定目标,因为我有更多的对象和重复的函数。

这张照片是我想要实现的。  enter image description here 代码如下。

谢谢。


 var obj1:Array = [obj_1, obj_10];
 var obj2:Array = [obj_2, obj_20]; 

 for each(var redsMC:MovieClip in reds)
 {
obj1MC.buttonMode = true;
obj1MC.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
obj1MC.addEventListener(MouseEvent.MOUSE_UP, dropIt);
obj1MC.startX = obj1MC.x;
obj1MC.startY = obj1MC.y;
   }

for each(var orangesMC:MovieClip in oranges)
{
obj2MC.buttonMode = true;
obj2MC.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
obj2MC.addEventListener(MouseEvent.MOUSE_UP, dropIt1);
obj2MC.startX = obj2MC.x;
obj2MC.startY = obj2MC.y;
 }


function pickUp(event:MouseEvent):void
{
event.target.startDrag(true);
event.target.parent.addChild(event.target);

 }


   function dropIt(event:MouseEvent):void
  {
    event.target.stopDrag();

    if(event.target.hitTestObject(target1)){
     event.target.buttonMode = false;
     event.target.x = target1.x;
     event.target.y = target1.y;

     }else if(event.target.hitTestObject(target10)){
    event.target.buttonMode = false;
    event.target.x = target10.x;
    event.target.y = target10.y; 
     }

   else
   {
     event.target.x = event.target.startX;
     event.target.y = event.target.startY;
      event.target.buttonMode = true;
  }
 }

function dropIt1(event:MouseEvent):void
{
event.target.stopDrag();

if(event.target.hitTestObject(target2)){
    event.target.buttonMode = false;
    event.target.x = target2.x;
    event.target.y = target2.y;

}else if(event.target.hitTestObject(target20)){
    event.target.buttonMode = false;
    event.target.x = target20.x;
    event.target.y = target20.y; 
}

else
{
     event.target.x = event.target.startX;
    event.target.y = event.target.startY;
     event.target.buttonMode = true;
 }
}

2 个答案:

答案 0 :(得分:3)

您应该以某种方式使您的可拖动对象知道其目标,因此,当您的SWF注册结束拖动事件时,被拖动的对象将对照其目标进行检查,如果不发生碰撞,则将其浮动/跳回。由于您的对象是从MovieClip派生的,因此可以在不进行任何声明的情况下向其添加自定义属性,但是请务必在使用前检查自定义属性中是否包含某些内容。假设您已为每个可拖动对象分配了desiredTarget作为需要拖动它们的目标。然后,您可以这样做:

function dropIt(e:MouseEvent):void {
    var desiredTarget:MovieClip=e.target.desiredTarget as MovieClip; // get where this should be placed
    e.target.stopDrag(); // we still need to release the dragged object
    if (!desiredTarget) return; // no target - nothing to do (also helps with debug)
    if (e.target.hitTestObject(desiredTarget)) {
        e.target.buttonMode=false;
        e.target.x=desiredTarget.x;
        e.target.y=desiredTarget.y;
    } else {
        // move dragged object back to starting position
        e.target.x=e.target.startX;
        e.target.y=e.target.startY;
    }
}

答案 1 :(得分:1)

尽管Vesper的答案已经被接受,但我认为它太简短和不足,最重要的是,它实际上并未回答如何设计可将任意数量的对象放入任意数量的对象的系统。目标,无需对代码进行实质性更改。

// Unlike the Object class, that allows String keys only
// the Dictionary class allows you to store and
// access data by the object instance.
var theValids:Dictionary = new Dictionary;

// We'll store the original (x,y) coordinates here.
var theOrigin:Point = new Point;

// The Sprite class is the superclass of MovieClip, furthermore,
// the startDrag method defined for Sprite class, so unless you
// create your own dragging code, you are bound to use Sprites,
// while you cannot drag SimpleButtons and TextFields this way.
// We'll store the current dragged object here.
var theObject:Sprite;

// This first argument is the object you want to be draggable.
// The "...targets:Array" means you can call this method with
// any number of arguments, the first one is mandatory, the
// rest will be passed in a form of Array (empty Array if you
// call this method with a single argument).
function setupDraggable(source:Sprite, ...targets:Array):void
{
    // Make the object draggable.
    source.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
    source.mouseChildren = false;
    source.mouseEnabled = true;
    source.buttonMode = true;

    // Keep the list of the object's targets so it can be
    // retrieved later by the key of the object itself.
    theValids[source] = targets;
}

// Ok, let's setup the objects and link them to their designated
// targets. The whole point of the rest of the code is to make
// this one part as simple as it possible: you just edit
// these lines to tell which one objects go where.

// This object can be dropped to a single target.
setupDraggable(obj_1 , target1);

// These objects can go to two targets each.
setupDraggable(obj_10, target1, target10);
setupDraggable(obj_2 , target2, target20);

// This one object can be dropped to any of targets.
setupDraggable(obj_20, target1, target10, target2, target20);

// The MOUSE_DOWN event handler.
function onDown(e:MouseEvent):void
{
    // Get the reference to the object under the mouse.
    theObject = e.currentTarget as Sprite;

    // Keep the object's initial position.
    theOrigin.x = theObject.x;
    theOrigin.y = theObject.y;

    // Put the dragged object on top of anything else.
    // We are operating in the parent context of all these
    // objects here so there's no need to address anObj.parent.
    setChildIndex(theObject, numChildren - 1);

    // Start dragging.
    theObject.startDrag(true);

    // Listen to the MOUSE_UP event, which could happen offstage
    // and out of the dragged object, so the only reliable
    // way is to listen it from the Stage. That's why we
    // are keeping theObject reference as an additional
    // variable, without relying on event's data.
    stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}

// The MOUSE_UP event handler.
function onUp(e:MouseEvent):void
{
    // Unsubscribe the MOUSE_UP event handler.
    stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);

    // Stop the dragging process.
    theObject.stopDrag();

    // Let's assume there could be more than a single collision.
    // We need to figure the one target that is closest.
    var theTarget:DisplayObject;
    var theDistance:int = 100000;

    // Store the dragged object position so we can
    // measure distances to the valid collisions, if any.
    var thePlace:Point = theObject.localToGlobal(new Point);

    // Now, the magic. Lets browse through the
    // valid targets and see if there's a collision.
    for each (var aTarget:DisplayObject in theValids[theObject])
    {
        if (theObject.hitTestObject(aTarget))
        {
            // Let's see if the current collision is closer
            // to the dragged object, than the previous one
            // (if any, that's what initial 100000 for).
            var aPlace:Point = aTarget.localToGlobal(new Point);
            var aDistance:int = Point.distance(aPlace, thePlace);

            if (aDistance < theDistance)
            {
                theTarget = aTarget;
                theDistance = aDistance;
            }
        }
    }

    // If there's at least one collision,
    // this variable will not be empty.
    if (theTarget)
    {
        // Make the object non-interactive.
        theObject.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
        theObject.mouseEnabled = false;
        theObject.buttonMode = false;

        // Glue the dragged object to the center of the target.
        theObject.x = theTarget.x;
        theObject.y = theTarget.y;
    }
    else
    {
        // If we're here, that means there was no valid collisions,
        // lets return the object to its designated place.
        theObject.x = theOrigin.x;
        theObject.y = theOrigin.y;
    }

    // Clean-up. Remove the reference, the object is no longer
    // being dragged, so you won't need to keep it.
    theObject = null;
}

P.S。。我没有测试它,但我想我已经发表了足够的评论来解释整个想法。