Search code examples
javauser-interfacelibgdxdrag-and-dropinventory

Libgdx Drag And Drop, how to sync cursor and sprite/actor?


Gdx version: 1.9.8

Hello, I am creating JRPG and I have a Inventory with drag and drop systems, problem is, when I click on item, position of it on left up corner far from cursor (see on screenshot), how to make sprite to be in center of the cursor (how it's normally should be)???

SCREENSHOT!!!How it looks like

import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Target;
import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Source;
import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Payload;
import com.redsoft.redrune.InventoryItem;

public class InventorySlotTarget extends Target {

    InventorySlot _targetSlot;

    public InventorySlotTarget(InventorySlot actor) {
        super(actor);
        _targetSlot = actor;
    }

    @Override
    public boolean drag(Source source, Payload payload, float x, float y, int pointer) {
        return true;
    }

    @Override
    public void reset(Source source, Payload payload) {
    }

    @Override
    public void drop(Source source, Payload payload, float x, float y, int pointer) {

        InventoryItem sourceActor = (InventoryItem) payload.getDragActor();
        InventoryItem targetActor = _targetSlot.getTopInventoryItem();
        InventorySlot sourceSlot = ((InventorySlotSource) source).getSourceSlot();

        if (sourceActor == null) {
            return;
        }

        //First, does the slot accept the source item type?
        if (!_targetSlot.doesAcceptItemUseType(sourceActor.getItemUseType())) {
            //Put item back where it came from, slot doesn't accept item
            sourceSlot.add(sourceActor);
            return;
        }

        if (!_targetSlot.hasItem()) {
            _targetSlot.add(sourceActor);
        } else {
            //If the same item and stackable, add
            if (sourceActor.isSameItemType(targetActor) && sourceActor.isStackable()) {
                _targetSlot.add(sourceActor);
            } else {
                //If they aren't the same items or the items aren't stackable, then swap
                InventorySlot.swapSlots(sourceSlot, _targetSlot, sourceActor);
            }
        }

    }
}

UPDATE!

import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop;
import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Source;
import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Payload;
import com.badlogic.gdx.scenes.scene2d.utils.DragAndDrop.Target;

public class InventorySlotSource extends Source {

    private DragAndDrop _dragAndDrop;
    private InventorySlot _sourceSlot;

    public InventorySlotSource(InventorySlot sourceSlot, DragAndDrop dragAndDrop) {
        super(sourceSlot.getTopInventoryItem());
        this._sourceSlot = sourceSlot;
        this._dragAndDrop = dragAndDrop;
    }

    @Override
    public Payload dragStart(InputEvent event, float x, float y, int pointer) {
        Payload payload = new Payload();
        Actor actor = getActor();
        if (actor == null) {
            return null;
        }

        InventorySlot source = (InventorySlot) actor.getParent();
        if (source == null) {
            return null;
        } else {
            _sourceSlot = source;
        }

        _sourceSlot.decrementItemCount(true);

        payload.setDragActor(getActor());
        _dragAndDrop.setDragActorPosition(-x, -y + getActor().getHeight());

        return payload;
    }

    @Override
    public void dragStop(InputEvent event, float x, float y, int pointer, Payload payload, Target target) {
        if (target == null) {
            _sourceSlot.add(payload.getDragActor());
        }
    }

    public InventorySlot getSourceSlot() {
        return _sourceSlot;
    }
}

Solution

  • This is set in the DragAndDrop object. The default position assumes you want the bottom right corner of the actor to align with the cursor. You can center it like this:

    dragAndDrop.setDragActorPosition(dragActor.getWidth() / 2, -dragActor.getHeight() / 2);
    

    You only have to call this once after setting the drag actor. I think the method name is misleading (it should say offset instead of position).