From a05818cbe41168b749943b5d0ba19e5376d9004e Mon Sep 17 00:00:00 2001 From: Peter <pt033@hdm-stuttgart.de> Date: Thu, 4 Jan 2024 14:05:39 +0100 Subject: [PATCH] add(ui): add screen calculator for responsive ui #14 --- .../Controller/GameSceneController.java | 57 ++++++++++++++----- .../Controller/Utilities/ScreenClasses.java | 28 +++++++++ .../Utilities/ScreenDimensionCalculator.java | 12 ++++ src/main/java/module-info.java | 2 + src/main/resources/fxml/GameScene.fxml | 13 +++-- 5 files changed, 93 insertions(+), 19 deletions(-) create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Controller/Utilities/ScreenClasses.java create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Controller/Utilities/ScreenDimensionCalculator.java diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java index 82dc6a44..1743c096 100644 --- a/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java +++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java @@ -1,5 +1,7 @@ package de.hdm_stuttgart.battlearena.Controller; +import de.hdm_stuttgart.battlearena.Controller.Utilities.ScreenClasses; +import de.hdm_stuttgart.battlearena.Controller.Utilities.ScreenDimensionCalculator; import de.hdm_stuttgart.battlearena.Model.Entity.EntityClass; import de.hdm_stuttgart.battlearena.Model.Entity.EntityFactory; import de.hdm_stuttgart.battlearena.Model.Entity.EntityType; @@ -10,10 +12,14 @@ import de.hdm_stuttgart.battlearena.Model.Map.TileManager; import javafx.animation.AnimationTimer; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.geometry.Insets; +import javafx.geometry.Rectangle2D; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.control.Slider; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.scene.shape.Rectangle; import javafx.scene.text.Font; @@ -39,8 +45,12 @@ public class GameSceneController implements Initializable { private VBox healthVBox, hpVBox; @FXML private Text playerHp, enemyHp; - private final int health = 900; - final private double healthBarWidth = Screen.getPrimary().getVisualBounds().getWidth() / 2.844; + @FXML + private StackPane stackPane; + Screen screen = Screen.getPrimary(); + Rectangle2D visualBounds = screen.getVisualBounds(); + final private double healthBarWidth = screen.getBounds().getWidth() / 2.844; + ScreenDimensionCalculator screenCalculator = new ScreenDimensionCalculator(); private GraphicsContext graphicsContext2D; @@ -81,6 +91,8 @@ public class GameSceneController implements Initializable { @Override public void initialize(URL url, ResourceBundle resourceBundle) { + double diagonalInches = screenCalculator.calculateDiagonalInches(visualBounds.getWidth(), + visualBounds.getHeight(), screen.getDpi()); // for some reason scene builder overwrites css fonts bruh playerHp.setFont(Font.loadFont(getClass().getResourceAsStream("/fonts/StarshipShadow.ttf"), 55)); enemyHp.setFont(Font.loadFont(getClass().getResourceAsStream("/fonts/StarshipShadow.ttf"), 55)); @@ -95,10 +107,37 @@ public class GameSceneController implements Initializable { playerHealth.setWidth(healthBarWidth); enemyHealth.setWidth(healthBarWidth); +// make it responsive + if (ScreenClasses.inRange((int) diagonalInches) == ScreenClasses.INCH27) { + canvas2D.setScaleX(1.2); + canvas2D.setScaleY(1.2); + } else if (ScreenClasses.inRange((int) diagonalInches) == ScreenClasses.INCH13_SURFACE) { +// TODO: make a enum for MacBook screens + } else { + canvas2D.setScaleX(0.87); + canvas2D.setScaleY(0.87); + playerHealth.setHeight(50); + enemyHealth.setHeight(50); + BorderPane.setMargin(stackPane, new Insets(-40, 0, 0, 0)); + } + System.out.println("dpi: " + screen.getDpi()); + +// testing hp bar + slider.valueProperty().addListener((observableValue, oldValue, newValue) -> { + double newWidth = healthBarWidth * (newValue.doubleValue() / 100); + playerHealth.setWidth(newWidth); + playerHp.setText(newValue.intValue() + "%"); + }); + slider2.valueProperty().addListener((observableValue, oldValue, newValue) -> { + double newWidth = healthBarWidth * (newValue.doubleValue() / 100); + enemyHealth.setWidth(newWidth); + enemyHp.setText(newValue.intValue() + "%"); + }); + + System.out.println("inches: " + diagonalInches); + graphicsContext2D = canvas2D.getGraphicsContext2D(); graphicsContext2D.setImageSmoothing(false); - canvas2D.setScaleX(1.2); - canvas2D.setScaleY(1.2); player = EntityFactory.createEntity(EntityType.PLAYER, graphicsContext2D, inputHandler, playerClass, this); enemy = EntityFactory.createEntity(EntityType.ENEMY_PLAYER, graphicsContext2D, inputHandler, enemyClass, this); @@ -115,16 +154,6 @@ public class GameSceneController implements Initializable { }; gameLoop.start(); log.debug("Game loop started"); - -// testing - slider.valueProperty().addListener((observableValue, oldValue, newValue) -> { - playerHealth.setWidth(health * (newValue.doubleValue() / 100)); - playerHp.setText(newValue.intValue() + "%"); - }); - slider2.valueProperty().addListener((observableValue, oldValue, newValue) -> { - enemyHealth.setWidth(health * (newValue.doubleValue() / 100)); - enemyHp.setText(newValue.intValue() + "%"); - }); } private void updateContent() { diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/Utilities/ScreenClasses.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Utilities/ScreenClasses.java new file mode 100644 index 00000000..469d628a --- /dev/null +++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Utilities/ScreenClasses.java @@ -0,0 +1,28 @@ +package de.hdm_stuttgart.battlearena.Controller.Utilities; + +public enum ScreenClasses { +// enums have a range because the screen calculations are not precise, especially with screen scaling in the OS settings + INCH27(26, 28), + INCH24(23, 25), + INCH13_SURFACE(12, 14); + + final int lBound, uBound; + + ScreenClasses(int lBound, int uBound) { + this.lBound = lBound; + this.uBound = uBound; + } + + public static ScreenClasses inRange(int inches) { + for (ScreenClasses screens : ScreenClasses.values()) { + if (screens.isInRange(inches)) { + return screens; + } + } + return null; + } + + private boolean isInRange(int inches) { + return inches >= lBound && inches <= uBound; + } +} diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/Utilities/ScreenDimensionCalculator.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Utilities/ScreenDimensionCalculator.java new file mode 100644 index 00000000..4dee18cf --- /dev/null +++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Utilities/ScreenDimensionCalculator.java @@ -0,0 +1,12 @@ +package de.hdm_stuttgart.battlearena.Controller.Utilities; + +public class ScreenDimensionCalculator { + public double calculateDiagonalInches(double width, double height, double dpi) { + double diagonalPixels = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); + double diagonalInches = diagonalPixels / dpi; + System.out.println("diagonal pixels: " + diagonalPixels); + System.out.println("width: " + width); + System.out.println("height: " + height); + return diagonalInches; + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 13a3d1d3..8a313280 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -12,4 +12,6 @@ module gui { exports de.hdm_stuttgart.battlearena.Model.Entity; exports de.hdm_stuttgart.battlearena.Model.Inputs; exports de.hdm_stuttgart.battlearena.Model.Map; + exports de.hdm_stuttgart.battlearena.Controller.Utilities; + opens de.hdm_stuttgart.battlearena.Controller.Utilities to javafx.fxml; } \ No newline at end of file diff --git a/src/main/resources/fxml/GameScene.fxml b/src/main/resources/fxml/GameScene.fxml index 2eaf6522..a85f39a2 100644 --- a/src/main/resources/fxml/GameScene.fxml +++ b/src/main/resources/fxml/GameScene.fxml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> +<?import javafx.geometry.Insets?> <?import javafx.scene.canvas.Canvas?> <?import javafx.scene.control.Slider?> <?import javafx.scene.layout.BorderPane?> @@ -11,13 +12,15 @@ <?import javafx.scene.text.Font?> <?import javafx.scene.text.Text?> - <BorderPane fx:id="gameScene" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.hdm_stuttgart.battlearena.Controller.GameSceneController"> <center> - <StackPane prefHeight="400.0" prefWidth="600.0" BorderPane.alignment="CENTER"> + <StackPane fx:id="stackPane" prefHeight="400.0" prefWidth="600.0" BorderPane.alignment="CENTER"> <children> <Canvas fx:id="canvas2D" height="864.0" width="864.0" /> </children> + <BorderPane.margin> + <Insets /> + </BorderPane.margin> </StackPane> </center> <top> @@ -30,7 +33,7 @@ <Rectangle fx:id="enemyHealth" arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="70.0" stroke="BLACK" strokeType="INSIDE" strokeWidth="0.0" width="900.0" /> </children> </VBox> - <VBox fx:id="hpVBox" alignment="CENTER_LEFT" spacing="20.0"> + <VBox fx:id="hpVBox" alignment="CENTER_LEFT" spacing="20.0" HBox.hgrow="NEVER"> <children> <Pane VBox.vgrow="ALWAYS" /> <Text fx:id="playerHp" strokeType="OUTSIDE" strokeWidth="0.0" VBox.vgrow="ALWAYS"> @@ -51,8 +54,8 @@ <left> <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" BorderPane.alignment="CENTER"> <children> - <Slider fx:id="slider2" orientation="VERTICAL" /> - <Slider fx:id="slider" orientation="VERTICAL" /> + <Slider fx:id="slider" orientation="VERTICAL" value="100.0" /> + <Slider fx:id="slider2" orientation="VERTICAL" value="100.0" /> </children> </VBox> </left> -- GitLab