JavaFX棋盘游戏屏幕分辨率适配缩放问题求助
解决JavaFX高DPI缩放导致游戏元素超屏问题
问题出在系统开启高DPI缩放(比如125%)时,JavaFX会默认应用系统缩放比例,但你的游戏界面元素是基于1920x1080固定尺寸设计的,缩放后元素实际显示尺寸超过屏幕边界,导致异常。下面是具体解决方案:
核心思路
- 获取系统的实际缩放因子,对整个界面进行反向缩放,抵消系统的高DPI缩放影响
- 调整FXML布局,让根容器能够自适应屏幕尺寸,避免固定尺寸限制
修改后的代码实现
Main.java
import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.stage.Screen; import javafx.stage.Stage; import javax.swing.*; import java.io.IOException; public class Main extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) throws IOException { // 获取系统高DPI缩放因子 double scaleX = Screen.getPrimary().getOutputScaleX(); double scaleY = Screen.getPrimary().getOutputScaleY(); Parent board = FXMLLoader.load(getClass().getResource("/board.fxml")); Pane innerBoard = ((Pane) board.getChildrenUnmodifiable().get(0)); // 替换自定义断言为常规判断,避免依赖自定义类 if (!"BOARD".equals(innerBoard.getId())) { throw new RuntimeException("找不到ID为BOARD的容器"); } // 对根容器进行反向缩放,抵消系统缩放 board.setScaleX(1 / scaleX); board.setScaleY(1 / scaleY); // 获取缩放后的屏幕可用尺寸 double screenWidth = Screen.getPrimary().getVisualBounds().getWidth(); double screenHeight = Screen.getPrimary().getVisualBounds().getHeight(); Scene scene = new Scene(board, screenWidth, screenHeight); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); primaryStage.setScene(scene); primaryStage.setFullScreen(true); primaryStage.setResizable(true); innerBoard.setVisible(false); primaryStage.setFullScreenExitHint(""); primaryStage.show(); innerBoard.setVisible(true); } }
修改后的FXML文件
<?xml version="1.0" encoding="UTF-8"?> <Pane maxHeight="USE_COMPUTED_SIZE" maxWidth="USE_COMPUTED_SIZE" minHeight="USE_COMPUTED_SIZE" minWidth="USE_COMPUTED_SIZE" prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <children> <Pane id="BOARD" fx:id="innerBoard" style="-fx-background-color: #cfffd1;"> <children> <!-- 保留你的子元素 --> </children> </Pane> </children> </Pane>
额外说明
- 如果你使用的是JavaFX 8版本,
Screen.getOutputScaleX()可能不支持,这时可以用以下方式计算缩放因子:// JavaFX 8兼容的缩放因子计算 double defaultDpi = 96.0; double currentDpi = Toolkit.getDefaultToolkit().getScreenResolution(); double scale = currentDpi / defaultDpi; - 移除了FXML中
innerBoard的固定layoutX和layoutY,避免布局偏移,建议后续使用AnchorPane或BorderPane等布局容器管理元素位置,而非固定坐标。
内容的提问来源于stack exchange,提问作者user8322140
相关产品推荐
相关产品推荐

