【问题标题】:Stage, viewport, camera, scaling, and Nexus 7舞台、视口、相机、缩放和 Nexus 7
【发布时间】:2013-11-02 11:42:47
【问题描述】:

我是 Android 新手,我也在学习如何使用 libgdx。我找到了一些使用“DisplayScreen extends AbstractScreen”编码技术的教程,它们使用 Stage 和 Actor 来显示输出。我对这种编码技术的解释是 DisplayScreen 将使用 AbstractScreen 中的任何内容,除非它是 @Override(如果我错了,请纠正我)。

因此,如果我将代码放在 AbstractScreen resize() 中以将显示缩放到更大的屏幕,同时保持纵横比; DisplayScreen 中的舞台应调整其大小以适应更大的屏幕。主要目标是我只想将我的游戏开发集中在 800x480 环境中,而完全忽略所有不同的尺寸/分辨率。 AbstractScreen 中的 resize() 将尽一切努力将我的游戏缩放并适应任何分辨率。

请允许我使用我的测试示例以获得更好的解释。我在手机上显示 800x480 黑色背景没有问题。但是,在 Nexus 7 上显示了相同的背景,但没有保持其纵横比。

这个turorial 解决了我上面提到的问题(我采用在屏幕两侧有两个黑条)。但是,我在将此解决方案集成到“DisplayScreen extends AbstractScreen”技术时遇到了一个小问题。

请查看此屏幕截图here。我的问题是:

  1. 为什么我的黑框没有调整大小以适应屏幕,却在屏幕两侧留下两个红条?
  2. 我不明白为什么我的 Nexus 7 上的黑色图像仅显示 766x480?

如果有人能指出正确的方向,那就太好了。

awesomegame 的代码

package com.example.somegame;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.assets.AssetManager;
import com.example.somegame.screens.DisplayScreen;

public class awesomegame extends Game {

public static AssetManager AssetManager = new AssetManager();

@Override
public void create() {
}

@Override
public void render() {
    super.render();
}

@Override
public void resize(int width, int height) {
    super.resize(width, height);
    setScreen( new DisplayScreen(this) );

}

@Override
public void setScreen(Screen screen) {
    super.setScreen( screen );
}

AbstractScreen 的代码

package com.example.somegame.screens;

import com.example.somegame.awesomegame;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.Scaling;

public class AbstractScreen implements Screen{

private awesomegame awesomegame;
private Stage stage;

private BitmapFont font;
    private SpriteBatch batch;
private OrthographicCamera camera;

public AbstractScreen(awesomegame awesomegame) {
    this.awesomegame = awesomegame;

    camera = new OrthographicCamera();
    camera.setToOrtho(false, 800, 480);
    camera.update();

    stage = new Stage(800, 480, false);
}

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

    stage.draw();
}

@Override
public void resize(int width, int height) {
    Vector2 size = Scaling.fit.apply(800, 480, width, height);
    int viewportX = (int)(width - size.x) / 2;
    int viewportY = (int)(height - size.y) / 2;
    int viewportWidth = (int)size.x;
    int viewportHeight = (int)size.y;
    Gdx.gl.glViewport(viewportX, viewportY, viewportWidth, viewportHeight);
    stage.setViewport(800, 480, true);
}

DisplayScreen 代码

package com.example.somegame.screens;

import com.example.somegame.awesomegame;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;

public class DisplayScreen extends AbstractScreen {

private Image loadingBg;

private Stage stage;

float loadingPercent;

public DisplayScreen(awesomegame awesomegame) {
    super (awesomegame);
}

@Override
public void show()
{
    super.show();

    awesomegame.AssetManager.load("img/loading.atlas", TextureAtlas.class);
    awesomegame.AssetManager.finishLoading();

    stage = new Stage();

    TextureAtlas atlas = awesomegame.AssetManager.get("img/loading.atlas", TextureAtlas.class);


    loadingBg = new Image(atlas.findRegion("loadingBg"));

    loadingBg.setSize(800, 480);
    loadingBg.setX(0);
    loadingBg.setY(0);

    stage.addActor(loadingBg);

    // add all asset need to be loaded here. for example
    // awesomegame.AssetManager.load("img/whatever.pack", TextureAtlas.class);

}

@Override
public void render(float delta) {
    Gdx.gl.glClearColor( 1f, 0f, 0f, 1f );
    stage.draw();

}

【问题讨论】:

    标签: camera libgdx viewport scaling stage


    【解决方案1】:

    Nexus 7 的屏幕分辨率为 1280 x 800,但部分高度用于屏幕菜单面板(带有返回/主页/菜单按钮)。

    代码中的罪魁祸首在这里,您尝试强制执行不适合此调整后尺寸的特定纵横比,从而导致侧面出现这些条:

    public void resize(int width, int height) {
        Vector2 size = Scaling.fit.apply(800, 480, width, height);
        ...
    }
    

    看起来您从另一个 stackoverflow 帖子中删除了 resize 函数。我也做了同样的事情,但是当我遇到同样的问题时切换到更简单的东西:

    public void resize(int width, int height) {
        stage.setViewport(true, width,height);
        stage.getCamera().setToOrtho(false,width,height);
        ...
    }
    

    【讨论】:

      【解决方案2】:

      此代码适用于我的最新更新:

      OrthographicCamera 是凸轮,这不会进行裁剪,只是更改视口,因此宽度仍然比实际窗口/设备大“那么多”倍

      public void resize(int width, int height) {
          int newW = width, newH = height;
          if (cam.viewportWidth > width) {
              float scale = (float) cam.viewportWidth / (float) width;
              newW *= scale;
              newH *= scale;
          }
      
          // true here to flip the Y-axis
          cam.setToOrtho(true, newW, newH);
      }
      

      【讨论】:

        猜你喜欢
        • 2013-07-02
        • 2014-06-01
        • 2014-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多