Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scene2d - Rotated actor not translated as expected

Tags:

java

libgdx

I asked this at the libgdx forums but didn't get a response so I was hoping y'all could help me out:

I have Actors that represent game pieces. What I'm trying to do is make it so the player can click-and-drag the tile to move it around the screen and rotate it multiple times before submitting the placeTile command. From what I understand of DragAndDrop it doesn't seem to be designed with my use case in mind so I figured I'd instead attach a dragListener listener to each game piece (code below). It works well for dragging, except I can't figure out how to set the 'minimum distance before drag starts' to 0... but that's not my main question (though any insights would be appreciated )

Anyway, the big problem comes in when I rotate the actor, and then try to drag it: At 30 degrees rotation, drag acts almost like normal: at 60 degrees, very small movements of the mouse send the actor moving in a tight circle very quickly. Another 30 degrees, the tile actor exits the screen in 1-2 frames, moving in a wide arc. If the actor is rotated clockwise, it's movements are clockwise; same pattern for counter-clockwise.

It looks like the translation of the actor is taking rotation into account; I guess my question is, is it possible to rotate an Actor/Group without the rotation affecting future translations? Alternatively, is there a better way to drag an Actor around the screen based on touch/mouse input? I included some code below: I imagine I'm screwing up something basic, but I can't figure out what:

// during initial stage creation
tileActor.setOrigin(tileActor.getWidth() / 2, tileActor.getHeight() / 2);
tileActor.addListener(new DragListener() {
        public void dragStart(InputEvent event, float x, float y,
              int pointer) {
           chosenTileActor = event.getTarget();

        }

        public void drag(InputEvent event, float x, float y, int pointer) {            
           Actor target = event.getTarget();               
           target.translate(x, y);
        }

     });

And for the listener that deals with rotation via scrolling mouse wheel:

multiplexer.addProcessor(new InputAdapter() {
     @Override
     public boolean scrolled(int amt) {
        if (chosenTileActor == null)
           return false;
        else
           chosenTileActor.rotate(amt * 30);
        return true;

     }
  });

Any pointers? Am I even going the right direction by using DragListener?

Thanks for reading!

like image 357
Dave H Avatar asked Jun 04 '13 16:06

Dave H


1 Answers

Instead of translating, just set the actor's position directly to the stage coordinates of your drag event:

tileActor.addListener(new DragListener() {
  private float offsetX, offsetY;

  @Override
  public void dragStart(InputEvent event, float x, float y, int pointer) {
    Actor target = event.getTarget();
    this.offsetX = event.getStageX() - target.getX();
    this.offsetY = event.getStageY() - target.getY();
  }

  @Override
  public void drag(InputEvent event, float x, float y, int pointer) {
    event.getTarget().setPosition(event.getStageX() - offsetX, event.getStageY() - offsetY);
  }
});

I'm computing the offsets in dragStart so that the actor doesn't immediately jump to wherever I clicked when I started dragging (making the drags relative to my mouse). Tested this and it works with any rotation.

like image 72
DannyMo Avatar answered Oct 26 '22 11:10

DannyMo