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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:51:22