【问题标题】:How to use ViewPorts to scale ImageButtons for different resolutions in libgdx?如何使用 ViewPorts 为 libgdx 中的不同分辨率缩放 ImageButtons?
【发布时间】:2019-03-23 02:59:13
【问题描述】:

我是尝试制作游戏的 libgdx 框架的新手,但这里的问题是我不知道如何缩放 ImageButton 以适应不同的屏幕尺寸,它在桌面上看起来很大,但在 Android 设备上看起来很小。我正在使用几个不同大小的ImageButtons 并使用表格来组织它们。任何人都可以进行一些代码更改,以便我了解如何使用视口缩放此处的图像吗?

public class BabyPhone extends Game {

public static final int WIDTH = 480;
public static final int HEIGHT = 800;

public void create () {


    bg = new BabyActor();
    bg.setTexture(new Texture("background-orange.png"));
    bg.setSize(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());


    phone = new BabyActor();
    phone.setTexture(new Texture("blue-phone.png"));
    phone.setSize(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());


    TextureRegion btLeft = new TextureRegion(new Texture("10OFF.png"));
    Drawable drawableLeft = new TextureRegionDrawable(new TextureRegion(btLeft));
    buttonLeft = new ImageButton(drawableLeft);

    TextureRegion btRight = new TextureRegion(new Texture("12OFF.png"));
    Drawable drawableRight = new TextureRegionDrawable(new TextureRegion(btRight));
    buttonRight = new ImageButton(drawableRight);

    TextureRegion btCenter = new TextureRegion(new Texture("11OFF.png"));
    Drawable drawableCenter = new TextureRegionDrawable(new TextureRegion(btCenter));
    buttonCenter = new ImageButton(drawableCenter);

    TextureRegion bt1 = new TextureRegion(new Texture("1OFF.png"));
    Drawable drawable = new TextureRegionDrawable(new TextureRegion(bt1));
    button1 = new ImageButton(drawable);

    TextureRegion bt2 = new TextureRegion(new Texture("2OFF.png"));
    Drawable drawable1 = new TextureRegionDrawable(new TextureRegion(bt2));
    button2 = new ImageButton(drawable1);

    TextureRegion bt3 = new TextureRegion(new Texture("3OFF.png"));
    Drawable drawable2 = new TextureRegionDrawable(new TextureRegion(bt3));
    button3 = new ImageButton(drawable2);

    TextureRegion bt4 = new TextureRegion(new Texture("4OFF.png"));
    Drawable drawable3 = new TextureRegionDrawable(new TextureRegion(bt4));
    button4 = new ImageButton(drawable3);

    TextureRegion bt5 = new TextureRegion(new Texture("5OFF.png"));
    Drawable drawable4 = new TextureRegionDrawable(new TextureRegion(bt5));
    button5 = new ImageButton(drawable4);

    TextureRegion bt6 = new TextureRegion(new Texture("6OFF.png"));
    Drawable drawable5 = new TextureRegionDrawable(new TextureRegion(bt6));
    button6 = new ImageButton(drawable5);

    TextureRegion bt7 = new TextureRegion(new Texture("7OFF.png"));
    Drawable drawable6 = new TextureRegionDrawable(new TextureRegion(bt7));
    button7 = new ImageButton(drawable6);

    TextureRegion bt8 = new TextureRegion(new Texture("8OFF.png"));
    Drawable drawable7 = new TextureRegionDrawable(new TextureRegion(bt8));
    button8 = new ImageButton(drawable7);

    TextureRegion bt9 = new TextureRegion(new Texture("9OFF.png"));
    Drawable drawable8 = new TextureRegionDrawable(new TextureRegion(bt9));
    button9 = new ImageButton(drawable8);


    gamecam = new OrthographicCamera(WIDTH,HEIGHT);
    gamecam.position.set(WIDTH/2,HEIGHT/2,0);
    gamePort = new ScreenViewport(gamecam);
    backStage = new Stage(gamePort);
    fitPort = new FitViewport(gamecam.viewportWidth,gamecam.viewportHeight,gamecam);
    frontStage = new Stage(fitPort);
    backStage.addActor(bg);
    frontStage.addActor(phone);

    Table table = new Table();
    table.padLeft(40);
    table.setPosition(phone.getWidth()/2,phone.getHeight()/2*0.6f);
    table.row().size(95,95);
    table.add(buttonLeft);
    table.add(buttonCenter);
    table.add(buttonRight);
    table.row().size(95,95);
    table.add(button1);
    table.add(button2);
    table.add(button3);
    table.row().size(95,95);
    table.add(button4);
    table.add(button5);
    table.add(button6);
    table.row().size(95,95);
    table.add(button7);
    table.add(button8);
    table.add(button9);

    frontStage.addActor(table);


}
public void render(){

    backStage.act(Gdx.graphics.getDeltaTime());
    frontStage.act(Gdx.graphics.getDeltaTime());
    backStage.draw();
    frontStage.draw();


}

@Override
public void resize(int width, int height) {
    gamePort.update(width, height);
    frontStage.getViewport().update(width, height);

}

【问题讨论】:

  • 为什么使用两个阶段?尝试使用一个带有 ExtendViewport 的舞台,然后使背景图像大于视口的大小。因此,如果某人的屏幕比例更高,他们会看到更多的背景,但按钮的比例仍然相同

标签: java android libgdx


【解决方案1】:

我只是将其设置为设备大小的百分比。好像是这样的。

float BUTTON_SIZE = 0.1f;
table.add(button2).size(Gdx.graphics.getWidth()*BUTTON_SIZE,Gdx.graphics.getWidth()*BUTTON_SIZE);

【讨论】:

  • 我想问一下为什么它在所有按钮之间显示填充?
  • 如果您希望不同设备上的宽高比相同,这将不起作用。在尺寸为 200:100 的设备上,按钮的比例为 2:1,在尺寸为 500:100 的设备上,按钮的比例为 5:1。
  • 是的,这不是一个普遍的决定,但大多数情况下你有一个主要方向,如果你以这种方式扩展它对我来说看起来不错
【解决方案2】:

如果您想使用视口,您必须选择要使用的视口。

屏幕视口

ScreenViewport 将始终填满整个屏幕,并将您的纹理等拉伸到全屏。

FitViewport

FitViewport 不会拉伸您的纹理,它看起来宽度和高度之间的比率将始终相同。如果屏幕与定义的比例不匹配,此视口将在侧面生成侧边栏。所以较短的边会与屏幕相匹配。

填充视口

FillViewport 不会拉伸您的纹理,它看起来宽度和高度之间的比率将始终相同。此 Viewport 不会像 FitViewport 那样创建侧边栏,因为它会将较长的一侧与屏幕匹配。所以可能会发生某些事情被切断的情况。

更多视口:https://github.com/libgdx/libgdx/wiki/Viewports

在我的示例中,我将使用 FitViewport。

要使用 FitViewport,我们必须创建一个相机。我们创建一个 OrthographicCamera。使用这个相机,我们可以定义我们视口的虚拟宽度和高度,以便我们可以看到的宽度和高度。

Camera camera = new OrthographicCamera(100,100);

现在重要的是,您要考虑我们定义的这个虚拟大小,而不是像素。所以我们的尺寸是 100 x 100 单位。

现在让我们用相机创建 FitViewport:

FitViewport viewport = new FitViewport(camera.viewportWidth, camera.viewportHeight, camera);

最后用视口创建我们的舞台:

Stage stage = new Stage(viewport);

因此,如果我们现在将按钮添加到表格中,我们可以在虚拟尺寸中定义按钮的尺寸。

所以如果我们像这样添加我们的按钮:

table.add(button1).size(10,10);

按钮将始终占屏幕的 10%,因为按钮在 100 个单位的世界中是 10 个单位

FitViewport 现在的优势是:我们将 Button 定义为 10x10,因此比例为 1:1,一个正方形。如果我们现在调整屏幕大小或使用不同的屏幕大小,按钮将始终为正方形,并且将始终填充 100 个屏幕单位中的 10 个。

这可能会与虚拟大小有点混淆。如果你想了解更多,这里有一个更好的描述:How Camera works in Libgdx and together with Viewport

在 Viewport 完美运行之前,我们还必须做一件事。

我们必须在 resize 方法中更新 Viewport:

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

我希望这将帮助您使用视口。


你已经写到你是 LibGdx 的新手,所以我会给你一些额外的建议。

这行不通:

Gdx.input.setInputProcessor(stage);
Gdx.input.setInputProcessor(stage1);

Gdx.input 每次只能保存一个 InputProcessor,因此 stage1 将覆盖 stage。如果您将使用多个 InputProcessor,请使用 InputMultiplexer:https://github.com/libgdx/libgdx/wiki/Event-handling

如果你使用一个表格并且一行中的每个演员都有相同的大小。而不是每个演员都写:table.add(button1).size(10,10);
Table 有一个特殊的功能,如果你设置一些东西到 row() 这将适用于该行中的所有演员。

所以不要写这个:

table.add(button1).size(10,10);
table.add(button2).size(10,10);
table.add(button3).size(10,10);
table.row();
table.add(button4).size(10,10);
table.add(button5).size(10,10);
table.add(button6).size(10,10);

你可以这样写:

table.row().size(10,10);
table.add(button1);
table.add(button2);
table.add(button3);
table.row().size(10,10);
table.add(button4);
table.add(button5);
table.add(button6);

希望这些小建议对你有所帮助。

【讨论】:

  • 我现在正在使用 fitviewport,但背景两侧显示黑线。我应该使用带背景的屏幕视口吗?
  • 现在我正在使用extendviewport,但背景图像仍然没有覆盖整个背景,而且黑线也出现了。
  • @danish FitViewport 在侧面显示黑线,因为视口会切开屏幕,因此您始终具有相同的宽度和高度比率。 Extendviewport 的效果与 FitViewport 相同,只是他不剪切屏幕。他扩展了屏幕,所以在具有更大宽度和高度比的屏幕上你会看到更多。 ExtendViewport 不应创建黑条,除非您定义了最大值。你用的是哪个 ExtendViewport 的构造函数?
  • 我正在用代码和图像更新我的问题,请检查它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-29
  • 2016-04-02
  • 1970-01-01
  • 1970-01-01
  • 2016-03-01
  • 2016-10-05
  • 1970-01-01
相关资源
最近更新 更多