LibGDX如何在调整游戏窗口大小时保持16:9宽高比
实现LibGDX 3桌面端窗口固定16:9宽高比方案
一、关于config.setWindowSizeLimits()的可行性说明
这个方法可以用来设置全局的窗口尺寸上下限,比如限制窗口最小为854×480(对应480P的16:9尺寸)、最大为3840×2160(对应4K的16:9尺寸),但无法单独靠它实现拖动时自动保持比例的效果,需要配合窗口大小监听回调,实时调整窗口尺寸到符合16:9的数值。
注意LibGDX 3的桌面配置类是Lwjgl3ApplicationConfiguration,没有公开cfg.height这类直接属性,所有配置和参数获取都通过对应set/get方法操作。
二、桌面启动器侧完整实现(优先推荐)
不需要修改游戏核心代码,所有逻辑写在启动器即可:
1. 核心实现代码
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application; import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window; import com.badlogic.gdx.backends.lwjgl3.Lwjgl3WindowListener; public class DesktopLauncher { // 固定宽高比16:9 private static final float ASPECT_RATIO = 16f / 9f; private static Lwjgl3Window currentWindow; // 防止resize回调循环触发的标记 private static boolean isAdjusting = false; public static void main(String[] arg) { Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); config.setTitle("16:9固定比例窗口"); // 初始窗口大小设为16:9,示例为1280×720 int initWidth = 1280; int initHeight = 720; config.setWindowedMode(initWidth, initHeight); // 全局尺寸限制:最小480P,最大4K,均为16:9尺寸 config.setWindowSizeLimits(854, 480, 3840, 2160); // 注册窗口监听器,处理拖动大小逻辑 config.setWindowListener(new Lwjgl3WindowListener() { @Override public void created(Lwjgl3Window window) { currentWindow = window; } @Override public void resized(int width, int height) { if (isAdjusting) return; isAdjusting = true; // 计算符合16:9的目标尺寸 int targetWidth, targetHeight; // 以用户拖动的宽度为基准计算高度 targetWidth = width; targetHeight = Math.round(targetWidth / ASPECT_RATIO); // 如果计算出的高度和实际高度差过大,说明用户在拖动高度边框,改用高度为基准计算 if (Math.abs(targetHeight - height) > 10) { targetHeight = height; targetWidth = Math.round(targetHeight * ASPECT_RATIO); } // 调整窗口到符合比例的目标大小 currentWindow.setSize(targetWidth, targetHeight); isAdjusting = false; } // 其余接口空实现即可,不需要额外逻辑 @Override public void closing() {} @Override public void closed() {} @Override public void focusLost() {} @Override public void focusGained() {} @Override public void iconified(boolean isIconified) {} @Override public void maximized(boolean isMaximized) {} @Override public void refreshRequested() {} @Override public boolean closeRequested() { return true; } @Override public void filesDropped(String[] files) {} }); // 替换YourGameMainClass为你自己的游戏主类实例 new Lwjgl3Application(new YourGameMainClass(), config); } }
2. 桌面端获取窗口尺寸的方法
在启动器侧可以通过两种方式获取实时窗口尺寸:
- 窗口创建完成后,调用
currentWindow.getWidth()和currentWindow.getHeight()直接获取当前宽高 - 在
resized回调的入参中直接拿到调整后的宽高值
三、游戏侧resize()方法兼容实现
如果需要把逻辑写在游戏核心代码中,直接在游戏主类的resize方法中添加如下逻辑即可:
@Override public void resize(int width, int height) { float targetRatio = 16f /9f; // 比例误差小于0.01就不用调整,避免循环触发resize if (Math.abs((float) width / height - targetRatio) < 0.01) { viewport.update(width, height, true); return; } // 计算符合16:9的目标尺寸 int targetWidth, targetHeight; if ((float) width / height > targetRatio) { // 窗口过宽,以高度为基准计算宽度 targetHeight = height; targetWidth = Math.round(targetHeight * targetRatio); } else { // 窗口过高,以宽度为基准计算高度 targetWidth = width; targetHeight = Math.round(targetWidth / targetRatio); } // 调用桌面端接口调整窗口大小 if (Gdx.app instanceof Lwjgl3Application) { Lwjgl3Window window = ((Lwjgl3Application) Gdx.app).getWindow(); window.setSize(targetWidth, targetHeight); } }
内容的提问来源于stack exchange,提问作者JellySword
相关产品推荐
相关产品推荐

