From 571da6552da9044d459b0fa0932471a42bb32d90 Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Sat, 16 May 2026 00:52:28 +0200 Subject: [PATCH] Added: Leaderboard FXML Scene --- .../it/polimi/ingsw/gc14/View/GUI/GUI.java | 19 +- .../View/GUI/LeaderboardFXMLController.java | 357 ++++++++++++++++++ .../resources/GUIImages/Icons/Building.png | Bin 0 -> 4581 bytes src/main/resources/GUIScene/standing.fxml | 30 ++ 4 files changed, 405 insertions(+), 1 deletion(-) create mode 100644 src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java create mode 100644 src/main/resources/GUIImages/Icons/Building.png create mode 100644 src/main/resources/GUIScene/standing.fxml 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 5081e6b..2b1e3d3 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 @@ -1,6 +1,7 @@ package it.polimi.ingsw.gc14.View.GUI; import it.polimi.ingsw.gc14.Controller.ClientController; +import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; import it.polimi.ingsw.gc14.Model.MiniModel; import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.View.GUI.LoginFXMLController; @@ -32,6 +33,11 @@ public class GUI extends Application implements IView { MainFXMLController controllerMain; MiniModel miniModel; + FXMLLoader loaderLeaderboard; + Scene leaderboardScene; + LeaderboardFXMLController controllerLeaderboard; + + private ClientController controller; public GUI(Stage stage) { @@ -58,6 +64,12 @@ public class GUI extends Application implements IView { controllerMain.setController(controller); return controllerMain; }); + + loaderLeaderboard = new FXMLLoader(getClass().getResource("/GUIScene/standing.fxml")); + leaderboardScene = new Scene(loaderLeaderboard.load()); + controllerLeaderboard = loaderLeaderboard.getController(); + controllerLeaderboard.setController(controller); + mainScene = new Scene(loaderMain.load()); controllerMain = loaderMain.getController(); @@ -86,7 +98,12 @@ public class GUI extends Application implements IView { if (controller.miniModel.currentState.getGameStage() == TOTEM_CHOICE) { controllerTotem.render(); primaryStage.setScene(totemScene); - } else { + } + else if (controller.miniModel.currentState.getGameStage() == GameStages.ENDED) { + controllerLeaderboard.render(); + primaryStage.setScene(leaderboardScene); + primaryStage.setFullScreen(true); + }else { controllerMain.render(event); primaryStage.setScene(mainScene); } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java new file mode 100644 index 0000000..0aa8e3b --- /dev/null +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java @@ -0,0 +1,357 @@ +package it.polimi.ingsw.gc14.View.GUI; + +import it.polimi.ingsw.gc14.Controller.ClientController; +import it.polimi.ingsw.gc14.Model.Player; +import javafx.animation.ScaleTransition; +import it.polimi.ingsw.gc14.Model.PlayableCard; +import javafx.event.Event; +import javafx.fxml.FXML; +import javafx.stage.Popup; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Cursor; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.effect.DropShadow; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.*; +import javafx.scene.paint.Color; +import javafx.scene.paint.LinearGradient; +import javafx.scene.paint.Stop; +import javafx.scene.paint.CycleMethod; +import javafx.scene.text.Font; +import javafx.stage.Window; +import javafx.util.Duration; + +import java.util.*; + +public class LeaderboardFXMLController { + + @FXML private StackPane rootPane; + @FXML private VBox mainVBox; + @FXML private VBox rankingList; + // titleLabel rimossa: il testo Winner/GameOver è aggiunto dinamicamente in render() + + private ClientController controller; + + private Popup popup; + private VBox popupContent; + + // Cache condivisa con MainFXMLController + private static final Map imageCache = new HashMap<>(); + + private Image loadImage(String path) { + return imageCache.computeIfAbsent(path, + p -> new Image(getClass().getResourceAsStream(p))); + } + + + public void setController(ClientController controller) { + this.controller = controller; + } + + + @FXML + public void initialize() { + Font.loadFont(getClass().getResourceAsStream("/Fonts/InknutAntiqua-Regular.ttf"), 14); + mainVBox.sceneProperty().addListener((obs, oldScene, newScene) -> { + if (newScene != null) newScene.getRoot().applyCss(); + }); + renderBackground(); + initPopup(); + } + + + public void render() { + rankingList.getChildren().clear(); + + List sorted = new ArrayList<>(controller.miniModel.players.values()); + sorted.sort(Comparator.comparingInt(Player::getPrestigeValue).reversed()); + + boolean iWon = sorted.get(0).getUserName().equals(controller.myUsername); + + // Label grande Winner / Game Over + Label outcomeLabel = new Label(iWon ? "\uD83C\uDFC6 WINNER! \uD83C\uDFC6" : "GAME OVER"); + outcomeLabel.setStyle( + "-fx-font-size: 64px;" + + "-fx-font-weight: bold;" + + "-fx-text-fill: " + (iWon ? "#FFD700;" : "#FF4444;") + ); + DropShadow glow = new DropShadow(); + glow.setColor(iWon ? Color.rgb(255, 200, 0, 0.95) : Color.rgb(220, 0, 0, 0.95)); + glow.setRadius(35); + glow.setSpread(0.35); + outcomeLabel.setEffect(glow); + rankingList.getChildren().add(outcomeLabel); + + // Separatore + Region sep = new Region(); + sep.setPrefHeight(16); + rankingList.getChildren().add(sep); + + for (int i = 0; i < sorted.size(); i++) { + rankingList.getChildren().add(createPlayerRow(i + 1, sorted.get(i))); + } + } + + + // ==== EFFECTS ==== + private void addHoverZoom(Node node) { + ScaleTransition scaleUp = new ScaleTransition(Duration.millis(150), node); + scaleUp.setToX(1.02); + scaleUp.setToY(1.02); + ScaleTransition scaleDown = new ScaleTransition(Duration.millis(150), node); + scaleDown.setToX(1.0); + scaleDown.setToY(1.0); + node.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> { scaleUp.play(); node.setCursor(Cursor.HAND); }); + node.addEventHandler(MouseEvent.MOUSE_EXITED, e -> { scaleDown.play(); node.setCursor(Cursor.DEFAULT); }); + } + + private void addShadow(Node node) { + DropShadow shadow = new DropShadow(); + shadow.setColor(Color.rgb(0, 0, 0, 0.6)); + shadow.setRadius(12); + shadow.setOffsetX(3); + shadow.setOffsetY(3); + node.setEffect(shadow); + } + + + // ==== ROW ==== + private HBox createPlayerRow(int position, Player player) { + HBox row = new HBox(20); + row.setAlignment(Pos.CENTER_LEFT); + row.setPadding(new Insets(14, 28, 14, 28)); + row.setMaxWidth(Double.MAX_VALUE); + + // Sfumatura scura semitrasparente come sfondo della riga + LinearGradient gradient = new LinearGradient( + 0, 0, 1, 0, true, CycleMethod.NO_CYCLE, + new Stop(0.0, Color.rgb(0, 0, 0, 0.75)), + new Stop(0.5, Color.rgb(0, 0, 0, 0.60)), + new Stop(1.0, Color.rgb(0, 0, 0, 0.75)) + ); + row.setBackground(new Background(new BackgroundFill( + gradient, + new CornerRadii(12), + Insets.EMPTY + ))); + addShadow(row); + addHoverZoom(row); + + // Posizione medaglia + Label posLabel = new Label(position + "°"); + posLabel.setMinWidth(55); + String medalColor = switch (position) { + case 1 -> "#FFD700"; // oro + case 2 -> "#C0C0C0"; // argento + case 3 -> "#CD7F32"; // bronzo + default -> "#EEEEEE"; + }; + posLabel.setStyle("-fx-font-size: 28px; -fx-font-weight: bold; -fx-text-fill: " + medalColor + ";"); + + + // Totem + ImageView totem = new ImageView(loadImage( + "/GUIImages/Totems/totem_" + player.totem.toString().toLowerCase(Locale.ROOT) + ".png")); + totem.setFitHeight(55); + totem.setPreserveRatio(true); + + // Username + Label nameLabel = new Label(player.getUserName()); + nameLabel.setStyle( + "-fx-font-size: 22px; -fx-font-weight: bold; -fx-text-fill: " + + (player.getUserName().equals(controller.myUsername) ? "#ff6b6b;" : "#FFFFFF;") + ); + HBox.setHgrow(nameLabel, Priority.ALWAYS); + + // Statistiche (icona + numero) + HBox stats = createStatsBox(player); + + // Punti prestigio in evidenza a destra + HBox ppBox = new HBox(6); + ppBox.setAlignment(Pos.CENTER); + ImageView ppIcon = new ImageView(loadImage("/GUIImages/Icons/PrestigePoint.png")); + ppIcon.setFitHeight(45); + ppIcon.setPreserveRatio(true); + Label ppLabel = new Label(String.valueOf(player.getPrestigeValue())); + ppLabel.setStyle("-fx-font-size: 28px; -fx-font-weight: bold; -fx-text-fill: #FFD700;"); + ppBox.getChildren().addAll(ppIcon, ppLabel); + + row.getChildren().addAll(posLabel, totem, nameLabel, stats, ppBox); + row.setOnMouseClicked(e -> openPlayerPopup(player)); + return row; + } + + private HBox createStatsBox(Player player) { + HBox stats = new HBox(14); + stats.setAlignment(Pos.CENTER); + + stats.getChildren().add(createStatItem("/GUIImages/Icons/Food.png", String.valueOf(player.getFoodValue()), 26)); + stats.getChildren().add(createStatItem("/GUIImages/Icons/Artist.png", String.valueOf(player.artists.size()), 26)); + stats.getChildren().add(createStatItem("/GUIImages/Icons/Gatherer.png", String.valueOf(player.gatherers.size()), 26)); + stats.getChildren().add(createStatItem("/GUIImages/Icons/Inventor.png", String.valueOf(player.inventors.size()), 26)); + stats.getChildren().add(createStatItem("/GUIImages/Icons/Builder.png", String.valueOf(player.builders.size()), 26)); + stats.getChildren().add(createStatItem("/GUIImages/Icons/Shaman.png", String.valueOf(player.shamans.size()), 26)); + stats.getChildren().add(createStatItem("/GUIImages/Icons/Hunter.png", String.valueOf(player.hunters.size()), 26)); + stats.getChildren().add(createStatItem("/GUIImages/Icons/Building.png", String.valueOf(player.buildingCards.size()), 26)); + + return stats; + } + + private HBox createStatItem(String iconPath, String value, double iconHeight) { + HBox box = new HBox(4); + box.setAlignment(Pos.CENTER); + ImageView icon = new ImageView(loadImage(iconPath)); + icon.setFitHeight(iconHeight); + icon.setPreserveRatio(true); + Label label = new Label(value); + label.setStyle("-fx-font-size: 16px; -fx-text-fill: #FFFFFF; -fx-font-weight: bold;"); + // Ombra sul testo per leggibilità extra + DropShadow textShadow = new DropShadow(); + textShadow.setColor(Color.rgb(0, 0, 0, 0.9)); + textShadow.setRadius(4); + label.setEffect(textShadow); + box.getChildren().addAll(icon, label); + return box; + } + + + // ==== POPUP ==== + private void initPopup() { + popupContent = new VBox(12); + popupContent.setAlignment(Pos.CENTER); + popupContent.setPadding(new Insets(16)); + popupContent.setStyle( + "-fx-background-color: rgba(20,10,5,0.97);" + + "-fx-border-color: #8B4513;" + + "-fx-border-width: 3;" + + "-fx-border-radius: 14;" + + "-fx-background-radius: 14;" + ); + + popup = new Popup(); + popup.getContent().add(popupContent); + popup.setAutoHide(true); + popup.addEventHandler(Event.ANY, e -> { + if (popup.getScene() != null) popup.getScene().setFill(Color.TRANSPARENT); + }); + } + + private void openPlayerPopup(Player player) { + popupContent.getChildren().clear(); + + // Intestazione con totem + nome + HBox header = new HBox(10); + header.setAlignment(Pos.CENTER); + ImageView totem = new ImageView(loadImage( + "/GUIImages/Totems/totem_" + player.totem.toString().toLowerCase(Locale.ROOT) + ".png")); + totem.setFitHeight(30); + totem.setPreserveRatio(true); + Label nameLabel = new Label(player.getUserName()); + nameLabel.setStyle("-fx-font-size: 18px; -fx-font-weight: bold; -fx-text-fill: #FFD700;"); + header.getChildren().addAll(totem, nameLabel); + popupContent.getChildren().add(header); + + // Tutte le carte in un unico FlowPane, raggruppate per tipo con separatore icona + String[][] types = { + {"Artist", "artists"}, + {"Gatherer", "gatherers"}, + {"Inventor", "inventors"}, + {"Builder", "builders"}, + {"Shaman", "shamans"}, + {"Hunter", "hunters"}, + {"Building", "buildingCards"} + }; + + // Griglia unica: icona tipo | carte... per ogni riga + VBox grid = new VBox(6); + grid.setAlignment(Pos.CENTER_LEFT); + boolean hasAnyCard = false; + + for (String[] type : types) { + String typeName = type[0]; + String field = type[1]; + ArrayList cards = getPlayerCards(player.getUserName(), field); + if (cards.isEmpty()) continue; + hasAnyCard = true; + + HBox row = new HBox(6); + row.setAlignment(Pos.CENTER_LEFT); + + // Icona tipo come intestazione riga + ImageView typeIcon = new ImageView(loadImage("/GUIImages/Icons/"+typeName+".png")); + typeIcon.setFitHeight(22); + typeIcon.setPreserveRatio(true); + row.getChildren().add(typeIcon); + + // Carte piccole in riga + for (PlayableCard card : cards) { + ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png")); + img.setFitHeight(160); + img.setPreserveRatio(true); + // Tooltip al hover: mostra la carta grande in un secondo popup + img.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> img.setFitHeight(180)); + img.addEventHandler(MouseEvent.MOUSE_EXITED, e -> img.setFitHeight(160)); + img.setCursor(Cursor.HAND); + row.getChildren().add(img); + } + + grid.getChildren().add(row); + } + + if (!hasAnyCard) { + Label empty = new Label("Nessuna carta"); + empty.setStyle("-fx-font-size: 14px; -fx-text-fill: #888888;"); + grid.getChildren().add(empty); + } + + grid.setMaxHeight(460); + grid.setMaxWidth(680); + popupContent.getChildren().add(grid); + + Window window = rootPane.getScene().getWindow(); + popup.show(window, 0, 0); + popup.getScene().setFill(Color.TRANSPARENT); + popup.setX(window.getX() + (window.getWidth() - popup.getWidth()) / 2); + popup.setY(window.getY() + (window.getHeight() - popup.getHeight()) / 2); + } + + private ArrayList getPlayerCards(String username, String type) { + Player p = controller.miniModel.players.get(username); + return switch (type) { + case "artists" -> new ArrayList<>(p.artists); + case "gatherers" -> new ArrayList<>(p.gatherers); + case "inventors" -> new ArrayList<>(p.inventors); + case "builders" -> new ArrayList<>(p.builders); + case "shamans" -> new ArrayList<>(p.shamans); + case "hunters" -> new ArrayList<>(p.hunters); + case "buildingCards" -> new ArrayList<>(p.buildingCards); + default -> new ArrayList<>(); + }; + } + + // ==== BACKGROUND ==== + private void renderBackground() { + BackgroundSize size = new BackgroundSize( + BackgroundSize.AUTO, BackgroundSize.AUTO, + false, false, true, true + ); + rootPane.setBackground(new Background(new BackgroundImage( + loadImage("/GUIImages/Background.png"), + BackgroundRepeat.NO_REPEAT, + BackgroundRepeat.NO_REPEAT, + BackgroundPosition.CENTER, + size + ))); + } + + + // ==== ACTIONS ==== + @FXML + private void onNewGame() { + //controller.requestNewGame(); + } +} diff --git a/src/main/resources/GUIImages/Icons/Building.png b/src/main/resources/GUIImages/Icons/Building.png new file mode 100644 index 0000000000000000000000000000000000000000..b140952f4d46c35c5a87331a3c9565c683d957e7 GIT binary patch literal 4581 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 P00000NkvXXu0mjfB$x<} literal 0 HcmV?d00001 diff --git a/src/main/resources/GUIScene/standing.fxml b/src/main/resources/GUIScene/standing.fxml new file mode 100644 index 0000000..de0ffa8 --- /dev/null +++ b/src/main/resources/GUIScene/standing.fxml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + +