JavaFx 游戏中的屏幕分辨率比例

问题描述 投票:0回答:1

我正在 JavaFx 中创建一个棋盘游戏,它在我的桌面 PC 上运行良好,屏幕分辨率为 1920x1080。当我尝试在我的笔记本电脑(也是 1920x1080,但默认屏幕尺寸为 125%)中打开它时,它不再正确显示元素(它们的尺寸超出了屏幕边界)。使应用程序正常工作的唯一方法是在 1920x1080 屏幕上运行它,默认屏幕尺寸为 100%

我需要一种方法将整个舞台缩放到正确的分辨率

这是我的 Main.java:

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws IOException {
        final double WIDTH = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
        final double HEIGHT = Toolkit.getDefaultToolkit().getScreenSize().getHeight();

        Parent board = FXMLLoader.load(getClass().getResource("/board.fxml"));

        Pane innerBoard = ((Pane)board.getChildrenUnmodifiable().get(0));
        Assert.assertCmp(innerBoard.getId(), "BOARD");

        Scene scene = new Scene(board, WIDTH, HEIGHT);

        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:

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" 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" layoutX="356.0" layoutY="-7.0" style="-fx-background-color: #cfffd1;">
         <children>
            <!-- Lots of children -->
         </children>
      </Pane>
   </children>
</Pane>
java user-interface javafx graphics screen-resolution
1个回答
0
投票

我建议您放弃窗格以及数字位置和大小。 您希望您的主板能够以任何分辨率显示; 明确的位置和大小直接与此相矛盾。

布局是使您的电路板适合任何尺寸的最佳方式。

(当然,布局仅适用于矩形板区域;我假设您不会选择复杂的东西,例如圆形或基于六边形的板,或具有蜿蜒路径的板。在这些情况下,Canvas可能是比窗格更好的选择。)

GridPane允许设置RowConstraintsColumnConstraints,每个都可以基于百分比。 如果行和列的大小是其父级宽度的百分比,则可以免费缩放。 这是大富翁棋盘的一个非常原始的再现:

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Node;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.Priority;

public class MonopolyBoard
extends Application {
    // Source:
    // https://commons.wikimedia.org/wiki/File:Store_Building_Flat_Icon_Vector.svg
    private static final String SIDE_SPACE_IMAGE_URI =
        "https://upload.wikimedia.org/wikipedia/commons/thumb/5/53"
        + "/Store_Building_Flat_Icon_Vector.svg"
        + "/240px-Store_Building_Flat_Icon_Vector.svg.png";

    // Source:
    // https://commons.wikimedia.org/wiki/File:Car_icon_transparent.png
    private static final String CORNER_SPACE_IMAGE_URI =
        "https://upload.wikimedia.org/wikipedia/commons/7/7e"
        + "/Car_icon_transparent.png";

    @Override
    public void start(Stage stage) {
        GridPane grid = new GridPane();

        Node[] row = new Node[11];

        row[0] = createSpace(CORNER_SPACE_IMAGE_URI);
        row[10] = createSpace(CORNER_SPACE_IMAGE_URI);
        for (int i = 1; i <= 9; i++) {
            row[i] = createSpace(SIDE_SPACE_IMAGE_URI);
        }
        grid.addRow(0, row);

        for (int i = 1; i <= 9; i++) {
            grid.add(createSpace(SIDE_SPACE_IMAGE_URI), 0, i);
            grid.add(createSpace(SIDE_SPACE_IMAGE_URI), 10, i);
        }

        row[0] = createSpace(CORNER_SPACE_IMAGE_URI);
        row[10] = createSpace(CORNER_SPACE_IMAGE_URI);
        for (int i = 1; i <= 9; i++) {
            row[i] = createSpace(SIDE_SPACE_IMAGE_URI);
        }
        grid.addRow(10, row);

        grid.getColumnConstraints().add(createColumnConstraints(2 / 11.0));
        for (int i = 1; i <= 9; i++) {
            grid.getColumnConstraints().add(createColumnConstraints(1 / 11.0));
        }
        grid.getColumnConstraints().add(createColumnConstraints(2 / 11.0));

        grid.getRowConstraints().add(createRowConstraints(2 / 11.0));
        for (int i = 1; i <= 9; i++) {
            grid.getRowConstraints().add(createRowConstraints(1 / 11.0));
        }
        grid.getRowConstraints().add(createRowConstraints(2 / 11.0));

        stage.setScene(new Scene(grid, 50 * 11, 50 * 11));
        stage.setTitle("Monopoly");
        stage.show();
    }

    private ColumnConstraints createColumnConstraints(double percentage) {
        ColumnConstraints constraints = new ColumnConstraints();
        constraints.setPercentWidth(percentage * 100);
        constraints.setHgrow(Priority.ALWAYS);
        return constraints;
    }

    private RowConstraints createRowConstraints(double percentage) {
        RowConstraints constraints = new RowConstraints();
        constraints.setPercentHeight(percentage * 100);
        constraints.setVgrow(Priority.ALWAYS);
        return constraints;
    }

    private Node createSpace(String imageURI) {
        BorderPane container = new BorderPane();
        container.setStyle(
            "-fx-border-width: 1px;"
            + " -fx-border-style: solid;"
            + " -fx-background-image: url('" + imageURI + "');"
            + " -fx-background-position: center;"
            + " -fx-background-repeat: no-repeat;"
            + " -fx-background-size: contain;");

        return container;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

除了使用 RowConstraints 和 ColumnConstraints 的百分比属性之外,上面的代码还利用了 CSS 图像缩放功能,使用 -fx-background-size: contain

调整窗口大小(或最大化)以查看缩放效果。 显然,如果是全屏,则将应用相同的缩放比例。

© www.soinside.com 2019 - 2024. All rights reserved.