user3192180
user3192180

Reputation:

Splint screen into 3 in Libgdx

As mentioned in the title , I'm having problem with splitting screen into 3 parts using Libgdx. I'm trying to make a card game with 3 areas: board, player's cards and menu. While looking for the solution in SO i found out that i should use Stage for each part of the screen and change viewport with setScreenBounds func. However it doesnt work as expected. Here is my code :

public void create(){
        board = new Stage();
        userCards = new Stage();

        Gdx.input.setInputProcessor(board);

        skin = new Skin(Gdx.files.internal("data/uiskin.json"));

        TextButton asd = new TextButton("asd", skin);
        TextButton asd2 = new TextButton("asd", skin);

        Table tab = new Table();
        Table tab2 = new Table();

        tab.setFillParent(true);
        tab2.setFillParent(true);

        tab.debug();
        tab2.debug();

        board.addActor(tab);

        userCards.addActor(tab2);

        tab.addActor(asd);
        tab2.addActor(asd2);

        board.getViewport().setScreenBounds(0, 0, 960, 270);
        userCards.getViewport().setScreenBounds(0, 270, 960, 270);

    }


    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);       

          userCards.getViewport().apply();
          userCards.act(delta); 
          userCards.draw();

          board.getViewport().apply();
          board.act(delta);  
          board.draw();   


    }

As u can see I'm testing it on 960x540 window size. Screen is splitted as i wanted to ( into 2 parts ) however buttons don't look normal ( their height is scaled down). What am I doing wrong? Also, how can i set input processor for all stages? Calling Gdx.input.setInputProcessor() sets it only for last called stage. Hope you can help me. Thanks in advance.

UPDATE So my code looks like this now :

public class GameScreen implements Screen{
    Skin skin;
    Stage board;
    Stage userCards;    
    Game g;
    Viewport viewportB, viewportUC;

    public GameScreen(Game g){
        create();
        this.g=g;
    }

    public GameScreen(){
        create();
    }
    public void create(){
        board = new Stage();
        userCards = new Stage();

        InputMultiplexer inputMultiplexer = new InputMultiplexer();

        inputMultiplexer.addProcessor(board);
        inputMultiplexer.addProcessor(userCards);


        Gdx.input.setInputProcessor(inputMultiplexer);


        viewportB = new ExtendViewport(Gdx.graphics.getWidth(), 540/3*2);
        board.setViewport(viewportB);

        viewportUC = new ExtendViewport(Gdx.graphics.getWidth(), 540/3);
        userCards.setViewport(viewportUC);

        skin = new Skin(Gdx.files.internal("data/uiskin.json"));

        TextButton asd = new TextButton("asd", skin);
        TextButton asd2 = new TextButton("asd", skin);


        Table tab = new Table();
        Table tab2 = new Table();

        tab.setFillParent(true);
        tab2.setFillParent(true);

        tab.debug();
        tab2.debug();

        board.addActor(tab);

        userCards.addActor(tab2);

        tab.addActor(asd);      
        tab2.addActor(asd2);

    }

    @Override
    public void show() {
        // TODO Auto-generated method stub

    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);       

         viewportUC.update(Gdx.graphics.getWidth(),  Gdx.graphics.getHeight()/3); //set the currentWindow... variables in the resize method to keep proper ratio
          userCards.act(delta); 
          userCards.draw();

         viewportB.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()/3*2);
          board.act(delta);  
          board.draw();   


    }

Dunno if it is important however i didn't change resize metod at all ( is blank ). My output : windowImg

Size of buttons seems ok now but its position isn't i guess or i'm missing something. Do you know how to fix this?

UPDATE 2 Code looks like this now : http://pastebin.com/e5K8Y2fN. Problems : tables aren't centered on stages + adding elements to table doesnt work properly.

Upvotes: 0

Views: 193

Answers (1)

m.antkowicz
m.antkowicz

Reputation: 13591

The effect you observe is about stretching the graphics due to characteristics of default Stage viewport which is type of ScalingViewport. You have to create your own ExtendViewport which actually does not scale anything and set it bounds to one third of screen then set it to the stage.

    //in the show() method
    viewport = new ExtendViewport(SCREEN_WIDTH, Runner.SCREEN_HEIGHT/3);
    stage.setViewport( viewport );

    //in the render method
    viewport.update(currentWindowWidth, currentWindowHeight/3); //set the currentWindow... variables in the resize method to keep proper ratio
    stage.act();
    stage.draw();

You can read more about viewports here


To set more than one inputProcessor you should use InputMultiplexer instance

    InputMultiplexer inputMultiplexer = new InputMultiplexer();

    inputMultiplexer.addProcessor(stage1);
    inputMultiplexer.addProcessor(stage2);
    inputMultiplexer.addProcessor(stage3);
    ...

    Gdx.input.setInputProcessor(inputMultiplexer);

----------

UPDATE

Two things that you are missing are

  • centering camera position - that's why stages are on on the center but somwhere on the right
  • setting viewports position - after camera centering you will observe that one of the stage overlaps second so you need to move the first over the second which will do split actually

The example code to achieve this:

    ExtendViewport viewport1, viewport2;
    Stage stage1 = new Stage(), stage2 = new Stage();

    @Override
    public void show() 
    {
        viewport1 = new ExtendViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()/3*2); 
        stage1.setViewport(viewport1);  

        viewport2 = new ExtendViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()/3);        
        stage2.setViewport(viewport2); 

        //... adding actors etc     
    }


    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        //here you are centering camera
        viewport2.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()/3, true); 
        stage2.act(delta); 
        stage2.draw(); 

        //here you are centering camera
        viewport1.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()/3*2, true);

        //here you are positioning the viewport on the screen
        viewport1.setScreenY(Gdx.graphics.getHeight()/3);
        viewport1.apply(true);

        stage1.act(delta); 
        stage1.draw();         
    }

Upvotes: 1

Related Questions