【问题标题】:Libgdx Scene2dUi and ViewportLibgdx Scene2dUi 和视口
【发布时间】:2015-12-06 10:53:55
【问题描述】:

我已经在场景 2d 中进行了布局并实现了它。但是尺寸是问题。它在我的 Android 手机和桌面上具有不同的对齐方式。

虽然我认为解决方案是使用视口但我不知道如何正确实现它。

我实现它的方式给了我一个白屏

 @Override
  public void show() {
    width=GameScreen.getGameWidth();
    height=GameScreen.getGameHeight();
    camera = new OrthographicCamera();
    camera.setToOrtho(true,width ,height);

    stage = new Stage(new FillViewport(width, height,camera)); 

    parameter.size = 40;
    parameter.color=Color.WHITE;
    parameter.flip=false;
    font12 = generator.generateFont(parameter); // font size 12 pixels
    generator.dispose();

    TextureAtlas atlas= new TextureAtlas(Gdx.files.internal("data/uiAtlas.atlas"));
    skin = new Skin(Gdx.files.internal("data/uiskin.json"));
    skin2= new Skin(Gdx.files.internal("data/achievementSkin.json"),atlas);
    Gdx.input.setInputProcessor(stage);

    mainTable = new Table();
    levelTable = new Table();

    stage.addActor(mainTable);
    mainTable.setFillParent(true);

    scrollPane = new ScrollPane(levelTable, skin);
    scrollPane.setFlickScroll(true);
    scrollPane.setFadeScrollBars(true);

    labelStyle=new LabelStyle();
    labelStyle.font=font12;

    makeLevelMenu();
}



public void makeLevelMenu() {
    for (int i = 0; i < 10; i++) {
        columnTable.add(new Table());

        // Image
        button.add(new ImageButton(skin2, "playButton"));
        columnTable.get(i).add(button.get(i)).colspan(2).padBottom(100)
                .padLeft(100).padRight(100).padTop(100);

        columnTable.get(i).row();
        // Enemy Label
        enemyLabel.add(new Label("Enemy " + (i + 1), labelStyle));
        columnTable.get(i).add(enemyLabel.get(i)).left().padBottom(300)
                .padTop(100);

        columnTable.get(i).row();
        // Battle Style
        battleStyle.add(new Label("Battle Style " + (i + 1), labelStyle));
        columnTable.get(i).add(battleStyle.get(i)).left().padBottom(100);

        levelTable.add(columnTable.get(i)).expand();
    }
    levelTable.debug();
    // achievementsTable.setFillParent(true);
    for (int i = 0; i < button.size(); i++) {
        final int k = i;
        button.get(k).addListener(new InputListener() {
            public boolean touchDown(InputEvent event, float x, float y,
                    int pointer, int button) {
                System.out.println("Level " + (k + 1) + "touchDown");
                return true;
            }

            public void touchUp(InputEvent event, float x, float y,
                    int pointer, int button) {

            }
        });
    }
    scrollPane.setScrollingDisabled(false, false);
    mainTable.add(scrollPane).expand().fill();
}



@Override
public void render(float delta) {
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    Gdx.gl20.glClearColor(1, 1, 1, 1);
    stage.act(delta);
    stage.draw();
}

@Override
public void resize(int width, int height) {
    stage.getViewport().update(width, height, true);
}

【问题讨论】:

  • 你能提供你的render() Screen 方法吗?
  • 你确定。我已经编辑了 qs。
  • 下面的两个答案都有效!!

标签: android libgdx viewport scene2d


【解决方案1】:

LibGDX 确实提供了Vieworts 来帮助您处理不同的分辨率。就我个人而言,我主要使用FitViewport,它保持纵横比,其余的都是“黑”框。还有许多其他视口,例如 StretchViewport,它们完全符合您的期望。

如果您设置正确,您可以轻松测试适合您游戏的内容。 The following code is straight from www.gamesfromscratch.com。它们描述了不太明显的视口的行为。

public class ViewportDemo extends ApplicationAdapter {
   SpriteBatch batch;
   Sprite aspectRatios;
   OrthographicCamera camera;
   Viewport viewport;

   @Override
   public void create () {
      batch = new SpriteBatch();
      aspectRatios = new Sprite(new Texture(Gdx.files.internal("Aspect.jpg")));
      aspectRatios.setPosition(0,0);
      aspectRatios.setSize(100,100);

      camera = new OrthographicCamera();
      viewport = new FillViewport(100,100,camera);
      viewport.apply();

      camera.position.set(camera.viewportWidth/2,camera.viewportHeight/2,0);
   }

   @Override
   public void render () {

      camera.update();
      Gdx.gl.glClearColor(1, 0, 0, 1);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

      batch.setProjectionMatrix(camera.combined);
      batch.begin();
      aspectRatios.draw(batch);
      batch.end();
   }

   @Override
   public void dispose(){
      aspectRatios.getTexture().dispose();
   }

   @Override
   public void resize(int width, int height){
      viewport.update(width,height);
      camera.position.set(camera.viewportWidth/2,camera.viewportHeight/2,0);
   }

你可以自己做。创建任何图像,将其粘贴到舞台上并使用不同的视口和屏幕尺寸进行播放。还要忘记使用像素,因为像素是硬件。

编辑

来自 www.gamesfromscratch.com 的上述实现并未展示如何在一个阶段中使用该实现。然而,这很简单。

stage = new Stage(viewport, batch);

现在舞台将使用您提供的视口和批处理。现在只需向舞台添加东西并像往常一样绘制它。

以下是我的代码,它使用舞台和 fitviewport 创建了一个非常基本的菜单屏幕。你确实需要自己的地图集和皮肤才能完成这项工作,check my answer here on SO to learn more about that.

public class MenuScreen implements Screen{

    private SpriteBatch batch;
    protected Stage stage;
    private Viewport viewport;
    private OrthographicCamera camera;
    private TextureAtlas atlas;
    protected Skin skin;

    public MenuScreen()
    {
        atlas = new TextureAtlas("atlas.txt");
        skin = new Skin(Gdx.files.internal("skin.json"), atlas);

        batch = new SpriteBatch();
        camera = new OrthographicCamera();
        viewport = new FitViewport(RealmOfConflict.WorldWidth, RealmOfConflict.WorldHeight, camera);
        viewport.apply();

        camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
        camera.update();

        stage = new Stage(viewport, batch);

        //Stage should controll input:
        Gdx.input.setInputProcessor(stage);
    }    

    @Override
    public void show() {
        //Create Table
        Table mainTable = new Table();
        //Set table to fill stage
        mainTable.setFillParent(true);
        //Set alignment of contents in the table.
        mainTable.top();

        //Create buttons
        TextButton playButton = new TextButton("Play", skin);
        TextButton optionsButton = new TextButton("Options", skin);
        TextButton exitButton = new TextButton("Exit", skin);

        //Add listeners to buttons
        playButton.addListener(new ClickListener(){
            @Override
            public void clicked(InputEvent event, float x, float y) {
                ((Game)Gdx.app.getApplicationListener()).setScreen(new PlayScreen());
            }
        });
        exitButton.addListener(new ClickListener(){
            @Override
            public void clicked(InputEvent event, float x, float y) {
                Gdx.app.exit();
            }
        });

        //Add buttons to table
        mainTable.add(playButton);
        mainTable.row();
        mainTable.add(optionsButton);
        mainTable.row();
        mainTable.add(exitButton);

        //Add table to stage
        stage.addActor(mainTable);
    }

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

        stage.act();
        stage.draw();
    }

    @Override
    public void resize(int width, int height) {
        viewport.update(width, height);
        camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
        camera.update();
    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {
        skin.dispose();
        atlas.dispose();
    }
}

【讨论】:

  • 实际上我在使用批处理器时没有任何问题,因为我已经在做 ti。但问题只出在我使用舞台时。
  • 如果我没看错,你是在要求一个 vieport 实现,这就是你的做法。 Stage 在构造函数中使用Viewport 和Batch,所以只需执行stage = new Stage(yourViewport, batch); 就可以了。如果您仍然遇到问题,请尝试使用较小的程序,例如在舞台上使用单个图像或按钮的单个表格。如果你能用它来玩,直到你理解得更好。
  • 如果您查看我的代码,您会发现它被提及为舞台。是的,我也试过你的东西。也许我会建议一次做很少的事情
  • 我提供的代码是用于舞台的。我总是使用这个...(Stage stage = new Stage(viewport, batch),你的舞台将使用视口,因为它是“画布”。
  • 忘记我提供的代码的渲染方法中的批处理。它只是来自 www.gamesfromscratch.com 的副本。只需将视口和批处理添加到舞台,然后在render() 中绘制舞台,就像stage.draw() 一样。
【解决方案2】:

问题出在视口的相机上。您正在创建自己的相机,而不是设置它的位置,也没有更新它。

如果没有理由创建自己的相机,请使用默认的舞台相机。而不是:

    camera = new OrthographicCamera();
    camera.setToOrtho(true,width ,height);

    stage = new Stage(new FillViewport(width, height,camera));

使用

    //no camera defining
    stage = new Stage(new FillViewport(width, height));

然后你的应用程序的正常流程

【讨论】:

  • 好吧,让我试试,但我之前做过同样的事情,它显示一个白屏。
  • 在添加到舞台之前尝试同时填充所有演员
  • 是的,我试过了。但不幸的是,白屏又出现了!!
  • 如何使用填充演员
  • 我并不是说 fill 喜欢做一些特别的事情——当它们完全设置好时,只需在 show() 方法的最后将它们添加到舞台上。例如,您有 stage.addActor(mainTable); 但稍后将滚动添加到 mainTable。
猜你喜欢
  • 2012-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-15
相关资源
最近更新 更多