Jammo
Jammo

Reputation: 2192

Libgdx adding a UI button separated from the gamescreen

I've got a GameScreen where I have 100 "dots" randomly bounce around the screen. I'm currently adding a UI button in order to rotate the screen; one on the left and one on the right. The button works, however, the button is "linked" to the camera because as the screen rotates (the playing field for the dots spins because the camera rotates), the button rotates with it. I want the button(s) to be fixed to the device screen, and not rotate with the underlying field of dots.

Do I have to unproject the button somehow, or create a separate stage for any UI elements (buttons, statusbar title alone the top, etc)? Many thanks.

Here's my code:

public class GameScreen implements Screen {

final jGdxDots game;
final MyGestureListener myGestureListener;

OrthographicCamera camera;
private Skin skin;

final int NUMBER_OF_DOTS = 100;
int dotTotal;

private Stage stage;

FPSLogger fpsLogger;

float cameraRotate = 0f;


public GameScreen(final jGdxDots gam) {
    this.game = gam;
    fpsLogger = new FPSLogger();

    camera = new OrthographicCamera();
    camera.setToOrtho(false, 800, 480); //boolean = YDOWN or YUP axis.

    //create stage
    stage = new Stage(Gdx.graphics.getWidth(),Gdx.graphics.getHeight(),true);
    //set stage to handle the inputs
    //Gdx.input.setInputProcessor(stage);

    stage.setCamera(camera);
    //stage.setViewport(800, 480, true);

    //multiplex the gesture listeners (both for stage and my listener)
    myGestureListener = new MyGestureListener();
    GestureDetector gd = new GestureDetector(myGestureListener);
    InputMultiplexer im = new InputMultiplexer(gd, stage); // Order matters here!
    Gdx.input.setInputProcessor(im);


    //UI button
    skin = new Skin(Gdx.files.internal("data/uiskin.json"));
    final TextButton button = new TextButton("Rotate", skin, "default");
    button.setWidth(100f); //200f
    button.setHeight(100f); //20f
    button.setPosition(10f, 10f);
    button.addListener(new ClickListener(){
        @Override
        public boolean touchDown(InputEvent event, float x, float y,
                int pointer, int button) {
            // TODO Auto-generated method stub

            cameraRotate = 1f;

            return super.touchDown(event, x, y, pointer, button);


        }

        @Override
        public void touchUp(InputEvent event, float x, float y,
                int pointer, int button) {
            // TODO Auto-generated method stub
            super.touchUp(event, x, y, pointer, button);

            cameraRotate = 0f;
        }

    });

    stage.addActor(button);

    spawnDots(stage);


}

private void spawnDots(Stage theStage) {
    //Rectangle raindrop = new Rectangle();

    for (int i=0; i < NUMBER_OF_DOTS; i++) {

        DotActor dot = new DotActor();
        dot.setOrigin(8,8); //(dot.getWidth()/2, dot.getHeight()/2);
        dot.vector.set(MathUtils.random(1,4), MathUtils.random(1,4));
        dot.actorX = MathUtils.random(0, 800 - dot.getWidth());
        dot.actorY = MathUtils.random(0, 480 - dot.getHeight());
        stage.addActor(dot);

    }

    dotTotal = NUMBER_OF_DOTS;
}

@Override
public void dispose() {
    stage.dispose();
}


@Override
public void render(float delta) {
    //clear screen
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    //logger
    fpsLogger.log();

    //camera.zoom += 0.005f;
    camera.rotate(cameraRotate); //(1.0f);


    camera.update();

    //run act() method of each actor 
    stage.act(Gdx.graphics.getDeltaTime());

    //run each actor's draw() method who are members of this stage
    stage.draw();

}



}

Upvotes: 0

Views: 956

Answers (1)

LairdPleng
LairdPleng

Reputation: 974

I had this problem too. Create a separate stage, or you might just want to draw directly with a sprite batch in a 'renderer' class

Mine looks something like this:

public OverlayRenderer()
{
    this.spriteBatch = new SpriteBatch();
    this.loadTextures();
}

public void render(String _message)
{
    this.spriteBatch.begin();
    this.spriteBatch.draw(TEXTURES.UI, 0, 0);
    ....
}

and directly after your

stage.draw();

line, I would add

overLayRenderer.render();

Upvotes: 1

Related Questions