简体   繁体   中英

LibGDX Rotate 2D image with touchDragged() event

Objective: to rotate an image in the center of the screen with movement equal to left or right touchDragged event.

Right now I have a basic Stage that is created and adds an actor (centerMass.png) to the stage. it is created and rendered like this:

public class Application extends ApplicationAdapter {
Stage stageGamePlay;

@Override
public void create () {
    //setup game stage variables
    stageGamePlay = new Stage(new ScreenViewport());
    stageGamePlay.addActor(new CenterMass(new Texture(Gdx.files.internal("centerMass.png"))));

    Gdx.input.setInputProcessor(stageGamePlay);

}

@Override
public void render () {
    Gdx.gl.glClearColor(255f/255, 249f/255, 236f/255, 1f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    //before drawing, updating actions that have changed
    stageGamePlay.act(Gdx.graphics.getDeltaTime());
    stageGamePlay.draw();

    }
}

I then have a separate class file that contains the CenterMass class, extending Image. I am familiar enough to know I could extend Actor, but I am not sure the benefit I would gain using Actor vs Image.

In the CenterMass class I create the texture, set bounds, set touchable and center it on the screen.

Inside CenterMass class I also have an InputListener listening for events. I have an override set for touchDragged where I am trying to get the X and Y of the drag, and use that to set the rotate actions accordingly. That class looks like this:

//extend Image vs Actor classes
public class CenterMass extends Image {
public CenterMass(Texture centerMassSprite) {
    //let parent be aware
    super(centerMassSprite);
    setBounds(getX(), getY(), getWidth(), getHeight());
    setTouchable(Touchable.enabled);
    setPosition(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2);
    setRotation(90f);


    addListener(new InputListener(){
        private int dragX, dragY;
        private float duration;
        private float rotateBy = 30f;

        @Override
        public void touchDragged(InputEvent event, float x, float y, int pointer) {
            //get
            float dX = (float)(x-dragX)/(float)Gdx.graphics.getWidth();
            float dY = (float)(dragY-y)/(float)Gdx.graphics.getHeight();

            duration = 1.0f; // 1 second

            Actions.sequence(
                    Actions.parallel(
                            Actions.rotateBy(rotateBy, duration),
                            Actions.moveBy( dX, dY, duration)
                    )
            );


        }
    });
}

@Override
protected void positionChanged() {
    //super.positionChanged();
}

@Override
public void draw(Batch batch, float parentAlpha) {
    //draw needs to be available for changing color and rotation, I think
    batch.setColor(this.getColor());
    //cast back to texture because we use Image vs Actor and want to rotate and change color safely
    ((TextureRegionDrawable)getDrawable()).draw(batch, getX(), getY(),
            getOriginX(), getOriginY(),
            getWidth(), getHeight(),
            getScaleX(), getScaleY(),
            getRotation());
}

@Override
public void act(float delta) {
    super.act(delta);
    }
}

The Problem: I have not been able to get it to rotate the way I would like. I have been able to get it to shift around in unpredictable ways. Any guidance would be much appreciated.

As from you code it seems everything is good. except you don't set any origin of the image. without setting the origin it is by default set to 0,0.(bottom left of your image) So if yow want to rotate the image with origin to centre you have to set the origin to imageWidth/2. imageHeight/2.

 setOrigin(imageWidth/2,imageHeight/2)// something like this

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM