From dbcefe254b9a173c962ff4410de8a94b6a11c408 Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Fri, 15 May 2026 15:11:07 +0200 Subject: [PATCH] Updated: Totem CHoice fxml and controller --- .../it/polimi/ingsw/gc14/ServerLauncher.java | 2 +- .../it/polimi/ingsw/gc14/View/GUI/GUI.java | 2 + .../gc14/View/GUI/TotemFXMLController.java | 195 +++++++++++++++++- src/main/resources/GUIScene/totem.fxml | 81 +++++++- 4 files changed, 265 insertions(+), 15 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java index 1fe83c8..9730192 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java +++ b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java @@ -265,7 +265,7 @@ public class ServerLauncher { break; } catch(RemoteException e){ - throw new RuntimeException(e); + System.out.println("Exception:"+e.getMessage()); } } } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java index de29419..9dd099e 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java @@ -84,11 +84,13 @@ public class GUI extends Application implements IView { Platform.runLater(() -> { controllerTotem.render(); primaryStage.setScene(totemScene); + primaryStage.setFullScreen(true); }); } else { Platform.runLater(() -> { controllerMain.render(); primaryStage.setScene(mainScene); + primaryStage.setFullScreen(true); }); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java index 5b606b3..4639277 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java @@ -1,40 +1,213 @@ package it.polimi.ingsw.gc14.View.GUI; import it.polimi.ingsw.gc14.Controller.ClientController; -import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Model.Totems; +import javafx.animation.*; import javafx.fxml.FXML; +import javafx.geometry.Pos; +import javafx.geometry.Rectangle2D; +import javafx.scene.Cursor; +import javafx.scene.control.Button; +import javafx.scene.control.Label; import javafx.scene.image.Image; import javafx.scene.image.ImageView; -import javafx.scene.layout.HBox; +import javafx.scene.layout.*; +import javafx.stage.Screen; +import javafx.util.Duration; import java.util.Locale; +import java.util.Objects; public class TotemFXMLController { + + public ImageView backgroundImage; @FXML private HBox mainHBox; + @FXML private Label turnBanner; + @FXML private Label selectedLabel; + @FXML private Button confirmButton; private ClientController controller; + private int selectedIndex = -1; + private StackPane selectedFrame = null; public void setController(ClientController controller) { - this.controller=controller; + this.controller = controller; } @FXML public void initialize() { - + Image img = new Image(getClass().getResourceAsStream("/GUIImages/Background.png")); + backgroundImage.setImage(img); + Rectangle2D screenBounds = Screen.getPrimary().getBounds(); + backgroundImage.setFitWidth(screenBounds.getWidth()); + backgroundImage.setFitHeight(screenBounds.getHeight()); } public void render() { mainHBox.getChildren().clear(); - for (Totems totem : controller.miniModel.availableTotems) { - ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_"+ String.valueOf(totem).toLowerCase(Locale.ROOT) +".png"))); - img.setFitHeight(240); - img.setPreserveRatio(true); - img.setOnMouseClicked(e -> controller.totemChoice(controller.myUsername, controller.miniModel.availableTotems.indexOf(totem))); - mainHBox.getChildren().add(img); + selectedIndex = -1; + selectedFrame = null; + selectedLabel.setText(""); + + String chooser = controller.miniModel.currentState.getCurrentPlayer().getUserName(); // adatta al tuo campo + boolean myTurn = chooser.equals(controller.myUsername); + + updateBanner(chooser, myTurn); + updateConfirmButton(false); + + for (int i = 0; i < controller.miniModel.availableTotems.size(); i++) { + Totems totem = controller.miniModel.availableTotems.get(i); + VBox card = buildCard(totem, i, myTurn); + mainHBox.getChildren().add(card); + + card.setOpacity(0); + card.setTranslateY(14); + PauseTransition delay = new PauseTransition(Duration.millis(80 + i * 65)); + delay.setOnFinished(e -> { + FadeTransition ft = new FadeTransition(Duration.millis(320), card); + ft.setToValue(1); + TranslateTransition tt = new TranslateTransition(Duration.millis(320), card); + tt.setToY(0); + new ParallelTransition(ft, tt).play(); + }); + delay.play(); } } + private void updateBanner(String chooser, boolean myTurn) { + if (myTurn) { + turnBanner.setText("✦ It's your turn to choice ✦"); + turnBanner.setStyle( + "-fx-font-family: 'Cinzel'; -fx-font-size: 13; -fx-letter-spacing: 3;" + + "-fx-text-fill: #f4c05a;" + + "-fx-background-color: rgba(244,192,90,0.1);" + + "-fx-border-color: rgba(244,192,90,0.45); -fx-border-width: 1;" + + "-fx-border-radius: 3; -fx-background-radius: 3;" + + "-fx-padding: 10 28 10 28;" + + "-fx-effect: dropshadow(gaussian, rgba(244,192,90,0.3), 18, 0, 0, 0);" + ); + } else { + turnBanner.setText("Waiting " + chooser + " chooses his totem…"); + turnBanner.setStyle( + "-fx-font-family: 'Cinzel'; -fx-font-size: 11; -fx-letter-spacing: 2;" + + "-fx-text-fill: rgba(200,155,90,0.6);" + + "-fx-background-color: rgba(120,60,10,0.18);" + + "-fx-border-color: rgba(200,120,20,0.22); -fx-border-width: 1;" + + "-fx-border-radius: 3; -fx-background-radius: 3;" + + "-fx-padding: 10 28 10 28;" + ); + } + } + private VBox buildCard(Totems totem, int idx, boolean interactive) { + ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + String.valueOf(totem).toLowerCase(Locale.ROOT) + ".png"))); + img.setFitHeight(150); + img.setPreserveRatio(true); -} + StackPane frame = new StackPane(img); + frame.setPrefSize(100, 145); + frame.setBackground(Background.EMPTY); + img.setStyle(frameStyle(false)); + + Region base = new Region(); + base.setPrefSize(100, 10); + + Label name = new Label(capitalize(totem)); + name.setStyle(nameStyle(false)); + + VBox card = new VBox(4, frame, base, name); + card.setAlignment(Pos.CENTER); + + if (!interactive) { + card.setOpacity(0.35); + card.setCursor(Cursor.DEFAULT); + return card; + } + + card.setCursor(Cursor.HAND); + + card.setOnMouseEntered(e -> { + if (frame != selectedFrame) { + ScaleTransition st = new ScaleTransition(Duration.millis(140), card); + st.setToX(1.06); st.setToY(1.06); st.play(); + } + }); + card.setOnMouseExited(e -> { + if (frame != selectedFrame) { + ScaleTransition st = new ScaleTransition(Duration.millis(140), card); + st.setToX(1.0); st.setToY(1.0); st.play(); + } + }); + + card.setOnMouseClicked(e -> { + // reset tutti + mainHBox.getChildren().forEach(n -> { + if (n instanceof VBox v) { + StackPane f = (StackPane) v.getChildren().get(0); + Label l = (Label) v.getChildren().get(2); + f.setStyle(frameStyle(false)); + l.setStyle(nameStyle(false)); + ScaleTransition st = new ScaleTransition(Duration.millis(130), v); + st.setToX(1.0); st.setToY(1.0); st.play(); + } + }); + + frame.setStyle(frameStyle(true)); + name.setStyle(nameStyle(true)); + selectedFrame = frame; + selectedIndex = idx; + + ScaleTransition pop = new ScaleTransition(Duration.millis(160), card); + pop.setToX(1.08); pop.setToY(1.08); + pop.setAutoReverse(true); pop.setCycleCount(2); pop.play(); + + selectedLabel.setText(capitalize(totem).toUpperCase() + " choice"); + updateConfirmButton(true); + }); + + return card; + } + + private void updateConfirmButton(boolean enabled) { + confirmButton.setDisable(!enabled); + confirmButton.setStyle( + "-fx-font-family: 'Cinzel'; -fx-font-size: 12; -fx-font-weight: bold;" + + "-fx-letter-spacing: 4; -fx-text-fill: #0c0601;" + + "-fx-background-color: linear-gradient(to right, #f4c05a, #c8791a, #f4c05a);" + + "-fx-padding: 12 48 12 48; -fx-background-radius: 2;" + + "-fx-opacity: " + (enabled ? "1.0" : "0.3") + ";" + + "-fx-cursor: " + (enabled ? "hand" : "default") + ";" + ); + } + + private String frameStyle(boolean selected) { + return " " + + "-fx-border-color: " + (selected ? "#f4c05a" : "rgba(200,120,20,0.28)") + ";" + + "-fx-border-width: " + (selected ? "2" : "0") + ";" + + "-fx-border-radius: 4 4 0 0; -fx-background-radius: 4 4 0 0;" + + (selected ? "-fx-effect: dropshadow(gaussian, rgba(244,192,90,0.35), 22, 0, 0, 0);" : ""); + } + + private String nameStyle(boolean selected) { + return "-fx-font-family: 'Cinzel'; -fx-font-size: 10; -fx-letter-spacing: 2;" + + "-fx-text-fill: " + (selected ? "#f4c05a" : "rgba(200,175,130,0.65)") + ";"; + } + + private String capitalize(Totems t) { + String s = t.name().toLowerCase(Locale.ROOT); + return Character.toUpperCase(s.charAt(0)) + s.substring(1); + } + + private String totemElement(Totems t) { + return switch (t) { + default -> t.name(); + }; + } + + @FXML + private void onConfirm() { + if (selectedIndex >= 0) { + controller.totemChoice(controller.myUsername, selectedIndex); + } + } +} \ No newline at end of file diff --git a/src/main/resources/GUIScene/totem.fxml b/src/main/resources/GUIScene/totem.fxml index 9e41caa..c28226b 100644 --- a/src/main/resources/GUIScene/totem.fxml +++ b/src/main/resources/GUIScene/totem.fxml @@ -1,6 +1,81 @@ - + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + +