Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
444 views
in Technique[技术] by (71.8m points)

screen - Libgdx background and foreground in single stage

My requirements:

  1. Background filling entire physical screen (stretching if required)
  2. Preserve aspect ratio of foreground assets (Work with virtual width and height)

For this, I use two Stages in my Screen as shown in the code below.

public void render(float delta) {
    backgroundStage.act(delta);
    backgroundStage.draw();
    foregroundStage.act(delta);
    foregroundStage.draw();
    }

public void resize(int width, int height) {
    background.setWidth(width);
    background.setHeight(height);
    backgroundStage.setViewport(width, height, true);
    foregroundStage.setViewport(MainGame.WIDTH, MainGame.HEIGHT, true);
    foregroundStage.getCamera().position.set(-foregroundStage.getGutterWidth(),-foregroundStage.getGutterHeight(),0);
    }

In all the tutorials I have read, I have only seen one stage being used for each screen. So, how do I fulfill both the requirements in single stage? Is it too expensive to have separate stages? (I have read that SpriteBatch objects are heavy!)

This is how I solved the problem:

To get rid of background stage, I updated my render and resize functions as follows. Basically, I shifted the bottom right corner of background to (-gutterWidth,-gutterHeight) and added twice the values of gutter width and height to region width and height of the texture region. The stage is gone now :-)

public void render(float delta) {
    Gdx.gl.glClearColor(0, 1, 0, 0.5f);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    foregroundStage.getSpriteBatch().begin();
    foregroundStage.getSpriteBatch().draw(backgroundImage,-gw,-gh,backgroundImage.getRegionWidth()+2*gw,backgroundImage.getRegionHeight()+2*gh);
    foregroundStage.getSpriteBatch().end();
    foregroundStage.act(delta);
    foregroundStage.draw();


public void resize(int width, int height) {
    screenW = width;
    screenH = height;
    foregroundStage.setViewport(MainGame.WIDTH, MainGame.HEIGHT, true);
    gw = foregroundStage.getGutterWidth();
    gh = foregroundStage.getGutterHeight();
    foregroundStage.getCamera().translate(-gw,-gh,0);
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could use two stages, but for your case it would be better to just solve this problem by creating two groups inside a single stage:

Stage stage = new Stage();

Group background = new Group();
background.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Group foreground = new Group();
foreground.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

// Notice the order
stage.addActor(background);
stage.addActor(foreground);

foreground.addActor(new Actor());
// Or anything else you want to add like you normally would to the stage. 

background.addActor(new Image()); // your background image here.

Gdx.input.setInputProcessor(stage);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...