Flash AS3 - перетащите несколько объектов на несколько целей - PullRequest
0 голосов
/ 11 ноября 2018

У меня есть несколько объектов для перетаскивания на несколько целей. У меня есть код без ошибок. Я использую несколько функций. Но мне интересно, передам ли я объекты и конкретную цель с помощью одной функции, например 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 голосов
/ 11 ноября 2018

Несмотря на то, что ответ Веспера уже принят, я думаю, что он слишком краткий и недостаточный, кроме того, на самом деле он не отвечает на вопрос о том, как спроектировать систему, в которой любое количество объектов может быть отброшено до любого числа. цели, без существенных изменений в коде.

// 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. Я не проверял это, но, думаю, я написал достаточно комментариев, чтобы объяснить всю идею.

0 голосов
/ 11 ноября 2018

Вы должны каким-то образом сделать так, чтобы перетаскиваемые объекты знали свои цели, поэтому, когда ваш SWF регистрирует событие конечного перетаскивания, перетаскиваемый объект проверяет свою цель и, если не сталкивается, то плавает / прыгает назад. Поскольку ваши объекты являются производными от MovieClip s, к ним можно добавлять пользовательские свойства без каких-либо объявлений, но обязательно проверьте, есть ли что-то в пользовательском свойстве, прежде чем использовать его. Допустим, вы назначили каждому перетаскиваемому объекту 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...