Reputation:
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
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
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