Simplified XNA drag and drop

I got a question about how to implement multiple selection with drag and drop, and could see how that might be a challenge to implement to a beginning programmer. So I thought I'd make a codesample to learn from.

image

 

When I had finished coding, it struck me that I could refactor the code so the drag and drop part was tucked away in a helperclass. Then all that was needed to use it in any solution was to have the draggable objects implement an interface to let the helperclass

  • know the boundaries of the object
  • be able to change the position of the object

I expanded the helperclass to notify the object when the mouse was hovering over it, and whether the object was selected, so all that was left for the coder using the helperclass, would be to implement different ways of drawing the object according to what the state of IsMouseOver and IsSelected is.

So without further ado - let me present the DragAndDropController Smiley

What you get

It's as easy as this to use the controllerclass in your project:

//declare the controller somewhere on your Game class
private DragAndDropController<Item> _dragDropController;

//instantiate the controller somewhere
_dragDropController =  new DragAndDropController<Item>(this, _spriteBatch);
//and add it to the Game class' Components
Components.Add(_dragDropController);

//add the items you want drag-and-drop enabled to the controller
_dragDropController.Add(item);

The items that you add to the controller must implement the IDragAndDropItem interface:

image

Or in code, if you prefer that:

/// <summary>
/// Interface describing necessary implementation
/// for working with the DragAndDropController.
/// </summary>
public interface IDragAndDropItem
{
    Vector2 Position { get; set; }
    bool IsSelected {  set; }
    bool IsMouseOver { set; }
    bool Contains(Vector2 pointToCheck);
    Rectangle Border { get; }
}

And that's it! Smiley med åben mund

What an interface does

An interface in code is a contract that allows one piece of code (the DragAndDropController in this case) to treat objects of different types in the same way. This means that no matter whether the class implementing the interface is a "PlayerCharacter", a "MoneyToken" or a "PlayingCard", as long as they implement the abovementioned methods, the controllerclass can interact with them Smiley.

Video demonstration

 

The DragAndDropController<T>

Here you can see the public properties and methods of the DragAndDropController

image

Since it is a generic class you instantiate it to handle the type of your objects, and from then on you can add or remove items of that type to and from the controller.

You can also get the item under the mouse at any time (if any).

Source code

Here is the complete source code

5 Responses to “Simplified XNA drag and drop”

  1. Frendy Says:

    Hai sir, thank you for your drag and drop, it is very useful for me, because i wanted to make the inventory system.

    But, i have a couple of questions to you.

    How do you make the items will be visible only if the I in the keyboard is pressed? and how do you make when the item 1 in the inventory is dragged to the item 2, the item 2 will be moving to the item slot 1 instead of they are overlapping each other.

    I am looking forward for it.. Thank you very much 😀 😀

  2. admin Says:

    Hi Frendy :)

    *** I KEY ***

    I am guessing you want to show an inventory when the "I" key has been pressed? And then remove it again when the "I" key is pressed again?

    For this you will need a boolean variable (e.g. "inventoryVisible"), which you toggle when the "I" key is pressed.
    The easiest way to do this is:

    inventoryVisible = !inventoryVisible;

    which takes the opposite value of what is in the boolean variable and stores it again.

    You will need to store both the current KeyboardState and the previous KeyboardState to make sure you don't just toggle (switch values) for every Update(), but only when "I" key was up in the previous Update() and down in this one.

    *** Swap items ***
    For this to work, you will have to
    - store the original position of the item you grab with the mouse
    - check when you drop an item, whether it is on top of another one

    One way to check for overlap when dropping is to create two bounding rectangles, one for each item, and use the Rectangle.Intersects method (http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.rectangle.intersects.aspx) to check whether one item overlaps the other.
    This way you can just set position of the item that is being dropped on to the original position of the dragged item.
    If you want all items to stay in a grid, have a look at the Drag and Drop with snap to tiles tutorial:
    http://xnafan.net/2012/07/simple-drag-and-drop-with-snap-to-tiles-in-xna/

    Kind regards - Jakob

  3. admin Says:

    Hi again Frendy :)
    I've made a small codesample for you to show you how to swap the positions of two items in a grid:

    http://www.xnafan.net/downloads/_tutorials/dragandswap/dragandswaptotilessolution.zip

    Kind regards - Jakob

  4. Jesse Says:

    Jakob. Thank you very much for that tile swap demo. Helped me a lot!

  5. admin Says:

    Super, glad to hear it! :)
    If you feel like it, send a link to whatever you're working on, if you finish it.
    It would be fun to see :).

    Kind regards - Jakob
    P.S. Sorry for the late answer, for some reason WordPress stopped notifying me of comments ... :-/

Leave a Reply