You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LibGDX中ExtendViewport适配Android分辨率仍出现黑边求助

LibGDX ExtendViewport 移动端黑边问题解决

问题概述

使用LibGDX开发2D游戏时,配置了ExtendViewport(550, 850)的mainStage和uiStage,Android模拟器显示正常,但三星等高分辨率移动端设备出现右侧/顶部黑边。背景图尺寸与视口设置一致,调整视口参数无效,对世界坐标理解存在盲区。

核心问题分析

  1. 整数除法陷阱:尝试调整视口时使用850 *(hoehe/breite),因hoehe和breite均为整数,除法结果会被截断为整数,导致视口比例计算完全错误。
  2. 背景图适配不足:ExtendViewport会保持设定的世界比例,自动扩展短边以填满屏幕,但如果背景图仅按固定的550x850绘制,无法覆盖扩展后的区域,就会出现黑边。
  3. Android系统UI干扰:部分设备的状态栏、导航栏或刘海屏会占用屏幕空间,若未设置全屏模式,实际可用显示区域会小于Gdx获取的尺寸,引发黑边。

解决方案

1. 修正视口初始化与Resize逻辑

确保每个Stage使用独立的视口实例,Resize时显式指定居中对齐:

public BaseScreen() {
    assMan.loadAll();
    assMan.manager.finishLoading();
    // 为每个Stage创建独立的ExtendViewport
    Viewport mainViewport = new ExtendViewport(550, 850);
    mainStage = new Stage(mainViewport);
    Viewport uiViewport = new ExtendViewport(550, 850);
    uiStage = new Stage(uiViewport);
    initialize();
}

@Override
public void resize(int width, int height) {
    // 显式传入true,保证视口在屏幕居中
    mainStage.getViewport().update(width, height, true);
    uiStage.getViewport().update(width, height, true);
}

2. 背景图适配扩展视口

不要固定背景图尺寸为550x850,而是让它填满整个视口区域:

  • 使用SpriteBatch绘制:获取视口实际的世界宽高进行绘制
@Override
public void render(float delta) {
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    SpriteBatch batch = mainStage.getSpriteBatch();
    batch.begin();
    // 获取视口当前的世界宽高(ExtendViewport会自动调整其中一个轴)
    float worldWidth = mainStage.getViewport().getWorldWidth();
    float worldHeight = mainStage.getViewport().getWorldHeight();
    // 绘制背景覆盖整个视口
    batch.draw(backgroundTexture, 0, 0, worldWidth, worldHeight);
    batch.end();

    mainStage.act(delta);
    mainStage.draw();
    uiStage.act(delta);
    uiStage.draw();
}
  • 使用Image Actor:利用setFillParent(true)让背景自动填满Stage
// 在initialize方法中添加背景
Image background = new Image(assMan.manager.get("background.png", Texture.class));
background.setFillParent(true); // 自动适配视口尺寸
mainStage.addActor(background);

3. 适配Android全屏与刘海屏

修改AndroidManifest.xml,设置全屏主题并适配刘海屏:

<activity
    android:name=".AndroidLauncher"
    android:label="@string/app_name"
    android:theme="@style/Theme.NoTitleBar.Fullscreen">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <!-- 允许应用延伸至刘海区域 -->
    <meta-data android:name="android.notch_support" android:value="true" />
</activity>

在AndroidLauncher中设置沉浸式全屏:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 隐藏状态栏和导航栏,启用沉浸式模式
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().getDecorView().setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 
        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        | View.SYSTEM_UI_FLAG_FULLSCREEN
    );
    AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
    initialize(new MyGdxGame(), config);
}

关键原理回顾

ExtendViewport的核心逻辑是:保持设定的世界比例,将屏幕较长的轴匹配世界尺寸,扩展较短的轴以填满屏幕。因此,世界坐标的一个轴会始终是设定值(550或850),另一个轴会按比例放大,背景图必须适配这个动态变化的尺寸才能避免黑边。

内容的提问来源于stack exchange,提问作者HermannGo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 11:55:59