Java/Javafx 2D平台游戏:JFrame固定16:9比例与F11全屏实现
嘿,这个需求我刚好折腾过,给你分享一下JavaFX里的实现方案,分两部分说:
一、让窗口始终保持16:9比例
要避免32x32的方块拉伸变形,核心就是把窗口宽高比牢牢锁在16:9上。JavaFX里可以通过监听Stage的宽高属性变化,实时计算并调整对应的另一边尺寸,同时要注意加个标志位防止循环触发调整(比如改完宽度触发高度调整,又反过来触发宽度调整)。
下面是完整的示例代码:
private boolean isResizing = false; // 防止循环触发调整的标志位 @Override public void start(Stage primaryStage) { // 初始窗口用标准16:9尺寸,比如1280x720 primaryStage.setWidth(1280); primaryStage.setHeight(720); primaryStage.setTitle("你的2D平台游戏"); // 监听宽度变化,自动计算对应高度 primaryStage.widthProperty().addListener((observable, oldWidth, newWidth) -> { if (!isResizing) { isResizing = true; // 16:9比例计算:高度 = 宽度 / 16 * 9 double targetHeight = newWidth.doubleValue() / 16 * 9; primaryStage.setHeight(targetHeight); isResizing = false; } }); // 监听高度变化,自动计算对应宽度 primaryStage.heightProperty().addListener((observable, oldHeight, newHeight) -> { if (!isResizing) { isResizing = true; // 16:9比例计算:宽度 = 高度 * 16 / 9 double targetWidth = newHeight.doubleValue() * 16 / 9; primaryStage.setWidth(targetWidth); isResizing = false; } }); // 初始化你的游戏场景(比如Canvas、根布局等) Canvas gameCanvas = new Canvas(primaryStage.getWidth(), primaryStage.getHeight()); BorderPane root = new BorderPane(gameCanvas); Scene scene = new Scene(root); primaryStage.setScene(scene); primaryStage.show(); }
这里的isResizing标志位是关键,它能确保每次调整只触发一次计算,不会陷入循环。另外,记得同步调整你的游戏画布(Canvas)尺寸,不然渲染内容会和窗口不匹配。
二、F11键切换全屏模式
JavaFX的Stage自带全屏功能,我们只需要监听键盘事件,捕获F11键的按下动作,然后切换全屏状态即可。
在上面的基础上,给Scene添加键盘监听:
scene.setOnKeyPressed(event -> { if (event.getCode() == KeyCode.F11) { // 切换全屏:当前是全屏就退出,非全屏就进入 primaryStage.setFullScreen(!primaryStage.isFullScreen()); event.consume(); // 阻止事件传递,避免系统默认行为干扰 } });
解释一下:
primaryStage.setFullScreen()方法直接控制全屏状态,传入true进入全屏,false退出。event.consume()是为了防止F11的系统默认行为(比如某些系统的全局快捷键)影响你的游戏,加上更稳妥。- 默认全屏模式会自动隐藏窗口标题栏和边框,不需要额外设置
StageStyle.UNDECORATED,如果需要无装饰窗口可以单独加,但全屏时没必要。
如果你的游戏有UI元素(比如暂停菜单),全屏时可能需要调整布局,不过基础的全屏切换就这么简单。
内容的提问来源于stack exchange,提问作者Freeranger
相关产品推荐
相关产品推荐

