Search code examples
apache-flexdrag-and-dropflex4collision-detection

Manual drag and drop in Flex 4 while avoiding collision with other draggables


I have a generated application where one part is an exercise where the user has to drag one or more items (text mainly, but images might be possible as well) and drop it into a box as seen below.

http://eastblue.org/dragdropexample.png

The box is a custom subclass of BorderContainer. Each draggable item (a subclass of RichText) gets picked up in a MouseEvent.MOUSE_DOWN using startDrag(). When it gets released on MOUSE_UP it checks if it hit the box using this.hitTestObject(box) and if it didn't hit, gets animated back to the start position. If it did hit, we do

stopDrag();
this.x = e.stageX; // e is the MouseEvent
this.y = e.stageY;

which works fairly well. The problem with this approach is that the draggable items can collide in each other, and that does not look very pretty.

I would like to prevent the draggable items from colliding in each other, and at the same time making sure they are kept inside the box.

I've considered solving this in two ways:

  • Creating some kind of grid inside the box, making sure each grid square is large enough to contain the biggest draggable item, and have the items appear in the closest free grid square.

    The problem with this is that the box and each draggable item can be any size and there can be any number of draggable items, so it's a bit troublesome to make sure the user can drop every item inside the box if he wants to and still keep it looking okay.

  • Checking each dropped item against all the other items already inside the drop, and if they collide, move the newly dropped item a bit in one of the directions until they no longer collide.

    The problem here is keeping everything inside the box and not getting stuck in a loop trying to move in an impossible direction. And what if there is no way it can be moved?

Am I missing some obvious way, or a simpler way of doing this? And if not, how can I implement this as simple as possible?

Some collisions might be okay, since the user won't be spending too much time with one of these exercises, but the way it works now they almost seem to seek each other out and crash horribly.


Solution

  • Use the DragManager as documented in the Flex help. Only put the accept code on your BorderContainer. Then make the items children of the BorderContainer, and give it a layout that does what you want.