diff --git a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java index 0322b97..f7737dc 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java +++ b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java @@ -29,6 +29,7 @@ public class ClientController { public String myUsername; + /** * Constructs the ClientController. * Initializes all attributes. @@ -37,6 +38,7 @@ public class ClientController { public ClientController(IView view) { this.view = view; this.client = null; + this.miniModel = new MiniModel(); } @@ -54,7 +56,12 @@ public class ClientController { * @param model the model to set */ public void setModel(MiniModel model) { - this.miniModel = model; + this.miniModel.currentState=model.currentState; + this.miniModel.availableTotems=model.availableTotems; + this.miniModel.board=model.board; + this.miniModel.orderLogicCard= model.orderLogicCard; + this.miniModel.players=model.players; + this.miniModel.slotPlayerMap=model.slotPlayerMap; view.setModel(miniModel); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java b/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java index 830175c..4a51fb8 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/MiniModel.java @@ -6,64 +6,109 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character; import it.polimi.ingsw.gc14.Model.GamePackage.Board; import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import java.io.Serializable; -import java.rmi.RemoteException; import java.util.*; -//TODO + public class MiniModel implements Serializable { + + private final PropertyChangeSupport support = new PropertyChangeSupport(this); + public Board board; - public Map slotPlayerMap; + public Map slotPlayerMap; public OrderLogicCard orderLogicCard; - public CurrentState currentState; - public Map players; - public ListavailableTotems; + public CurrentState currentState; + public Map players; + public List availableTotems; + + // --- Costruttori invariati --- + + public MiniModel() { + + } + public MiniModel(Board board) { this.board = board; } - public MiniModel(Board board, Map slotPlayerMap, OrderLogicCard orderLogicCard, CurrentState currentState, List players, ListavailableTotems) { + + public MiniModel(Board board, Map slotPlayerMap, OrderLogicCard orderLogicCard, + CurrentState currentState, List players, List availableTotems) { this.board = board; this.slotPlayerMap = slotPlayerMap; this.orderLogicCard = orderLogicCard; this.currentState = currentState; - this.players=new HashMap<>(); - this.availableTotems=availableTotems; + this.players = new HashMap<>(); + this.availableTotems = availableTotems; setPlayers(players); } + + // --- Gestione listener --- + + public void addPropertyChangeListener(PropertyChangeListener listener) { + support.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + support.removePropertyChangeListener(listener); + } + + // --- Setter con notifica --- + public void setBoard(Board board) { + Board old = this.board; this.board = board; + support.firePropertyChange("board", old, board); } - public void setAvailableTotems(ListavailableTotems) { + + public void setAvailableTotems(List availableTotems) { + List old = this.availableTotems; this.availableTotems = availableTotems; + support.firePropertyChange("availableTotems", old, availableTotems); } - public void setSlotPlayerMap(Map slotPlayerMap) { + + public void setSlotPlayerMap(Map slotPlayerMap) { + Map old = this.slotPlayerMap; this.slotPlayerMap = slotPlayerMap; + support.firePropertyChange("slotPlayerMap", old, slotPlayerMap); } + public void setOrderLogicCard(OrderLogicCard orderLogicCard) { + OrderLogicCard old = this.orderLogicCard; this.orderLogicCard = orderLogicCard; + support.firePropertyChange("orderLogicCard", old, orderLogicCard); } + public void setCurrentState(CurrentState currentState) { + CurrentState old = this.currentState; this.currentState = currentState; + support.firePropertyChange("currentState", old, currentState); } + public void setPlayers(List players) { + Map old = new HashMap<>(this.players != null ? this.players : new HashMap<>()); for (Player player : players) { - this.players.put(player.getUserName(),player); + this.players.put(player.getUserName(), player); } + support.firePropertyChange("players", old, this.players); } - public void setPlayer(Player player) - { - players.put(player.getUserName(),player); + + public void setPlayer(Player player) { + Map old = new HashMap<>(this.players); + players.put(player.getUserName(), player); + support.firePropertyChange("players", old, this.players); } - public int getPositionByUsername(String username) - { - int i=0; - for (Player player : players.values()) - { - if(player.getUserName().equals(username)) - { + + // --- Metodi invariati --- + + public int getPositionByUsername(String username) { + int i = 0; + for (Player player : players.values()) { + if (player.getUserName().equals(username)) { return i; } i++; } - return -1; + return -1; } -} +} \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java b/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java index dd6863c..f90ecfd 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java @@ -20,7 +20,7 @@ public abstract class OrderLogicCard implements Serializable { /** * The queue of {@link Player Players} associated with this order logic card. */ - protected Queue players; + public Queue players; /** * The list of {@link Player Players} associated with this order logic card. 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 ac8a59c..de29419 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 @@ -45,7 +45,6 @@ public class GUI extends Application implements IView { controllerLogin.setController(controller); - loaderTotem = new FXMLLoader(getClass().getResource("/GUIScene/totem.fxml")); totemScene = new Scene(loaderTotem.load()); controllerTotem = loaderTotem.getController(); @@ -53,9 +52,13 @@ public class GUI extends Application implements IView { loaderMain = new FXMLLoader(getClass().getResource("/GUIScene/main.fxml")); + loaderMain.setControllerFactory(clazz -> { + MainFXMLController controllerMain = new MainFXMLController(); + controllerMain.setController(controller); + return controllerMain; + }); mainScene = new Scene(loaderMain.load()); controllerMain = loaderMain.getController(); - controllerMain.setController(controller); showLogin(); stage.setTitle("Mesos"); diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java index 0eb6867..1b6f676 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java @@ -4,7 +4,10 @@ import it.polimi.ingsw.gc14.Controller.ClientController; import it.polimi.ingsw.gc14.Model.*; import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCard; +import it.polimi.ingsw.gc14.Model.GamePackage.Board; +import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState; import javafx.animation.ScaleTransition; +import javafx.application.Platform; import javafx.event.Event; import javafx.fxml.FXML; import javafx.geometry.Insets; @@ -24,9 +27,8 @@ import javafx.stage.Popup; import javafx.stage.Window; import javafx.util.Duration; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; public class MainFXMLController { @@ -48,7 +50,6 @@ public class MainFXMLController { private HBox popupCards; private ClientController controller; - private final Map cardCache = new HashMap<>(); public void setController(ClientController controller) { this.controller = controller; @@ -69,6 +70,23 @@ public class MainFXMLController { // Initialize popup initPopup(); + + + controller.miniModel.addPropertyChangeListener(evt -> { + switch (evt.getPropertyName()) { + case "board" -> ciao("board"); + case "currentState" -> ciao("currentState"); + case "players" -> Platform.runLater(() -> renderSidePanel()); + case "slotPlayerMap" -> Platform.runLater(() -> renderBoard()); + case "orderLogicCard"-> Platform.runLater(() -> renderBoard()); + case "availableTotems"-> ciao("availableTotems"); + } + }); + } + + + public void ciao(String s) { + System.out.println(s); } @@ -81,86 +99,15 @@ public class MainFXMLController { renderSidePanel(); } - // ==== HELPER ==== - private StackPane createOrder(String num, boolean withZoom, boolean withShadow) { - ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Orders/order-" + num + ".png"))); - img.setFitHeight(240); - img.setPreserveRatio(true); + + // ==== EFFECTS ==== + private void addClip(Node node) { Rectangle clip = new Rectangle(); - clip.setWidth(img.getBoundsInLocal().getWidth()); - clip.setHeight(240); + clip.setWidth(node.getBoundsInLocal().getWidth()); + clip.setHeight(node.getBoundsInLocal().getHeight()); clip.setArcWidth(20); clip.setArcHeight(20); - img.setClip(clip); - StackPane wrapper = new StackPane(img); - if (withShadow) { - addShadow(wrapper); - } - if (withZoom) { - addHoverZoom(wrapper); - } - return wrapper; - } - - private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) { - ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png"))); - img.setFitHeight(240); - img.setPreserveRatio(true); - Rectangle clip = new Rectangle(); - clip.setWidth(img.getBoundsInLocal().getWidth()); - clip.setHeight(240); - clip.setArcWidth(20); - clip.setArcHeight(20); - img.setClip(clip); - StackPane wrapper = new StackPane(img); - - Player player = controller.miniModel.slotPlayerMap.get(slot); - if (player != null && controller.miniModel.getPositionByUsername(player.getUserName())!=-1) { - int index = controller.miniModel.getPositionByUsername(player.getUserName()); - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + "blue" + ".png"))); - totem.setFitHeight(70); - totem.setPreserveRatio(true); - StackPane.setAlignment(totem, Pos.TOP_LEFT); - StackPane.setMargin(totem, new Insets(8, 0, 0, 57)); - wrapper.getChildren().add(totem); - } - - if (withShadow) { - addShadow(wrapper); - } - if (withZoom) { - addHoverZoom(wrapper); - } - return wrapper; - } - private StackPane createCard(PlayableCard card, boolean withZoom, boolean withShadow) { - String id = card.getIdIMG(); - ImageView img; - if (cardCache.containsKey(id)) { - img = new ImageView(cardCache.get(id).getImage()); - } else { - img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + id + ".png"))); - cardCache.put(id, img); - } - img.setFitHeight(200); - img.setPreserveRatio(true); - - Rectangle clip = new Rectangle(); - clip.setWidth(img.getBoundsInLocal().getWidth()); - clip.setHeight(200); - clip.setArcWidth(20); - clip.setArcHeight(20); - img.setClip(clip); - - StackPane wrapper = new StackPane(img); - - if (withShadow) { - addShadow(wrapper); - } - if (withZoom) { - addHoverZoom(wrapper); - } - return wrapper; + node.setClip(clip); } private void addHoverZoom(Node node) { ScaleTransition scaleUp = new ScaleTransition(Duration.millis(150), node); @@ -172,7 +119,6 @@ public class MainFXMLController { 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.3)); @@ -195,237 +141,57 @@ public class MainFXMLController { } - - // ==== RENDER METHODS ==== - // BACKGROUND - private void renderBackground() { - BackgroundSize size = new BackgroundSize( - BackgroundSize.AUTO, BackgroundSize.AUTO, - false, false, true, true - ); - mainHBox.setBackground(new Background(new BackgroundImage( - new Image(getClass().getResourceAsStream("/GUIImages/Background.png")), - BackgroundRepeat.NO_REPEAT, - BackgroundRepeat.NO_REPEAT, - BackgroundPosition.CENTER, - size - ))); + // ==== ELEMENTS ==== + private StackPane createOrder(String num) { + ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Orders/order-" + num + ".png"))); + img.setFitHeight(240); + img.setPreserveRatio(true); + addClip(img); + StackPane wrapper = new StackPane(img); + return wrapper; } + private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) { + ImageView img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png"))); + img.setFitHeight(240); + img.setPreserveRatio(true); + addClip(img); + StackPane wrapper = new StackPane(img); - // UPPER, LOWER AND BOARD - private void renderUpper() { - upperList.setSpacing(14); - upperList.setAlignment(Pos.CENTER); - upperList.getChildren().clear(); - - int i = 0; - for (TribeCard card : controller.miniModel.board.upperListTribe) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawUpperTribeCard(controller.myUsername, index)); - upperList.getChildren().add(img); - i++; - } - i = 0; - for (BuildingCard card : controller.miniModel.board.upperListBuilding) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawUpperBuildingCard(controller.myUsername, index)); - upperList.getChildren().add(img); - i++; - } - } - private void renderOrder() { - StackPane card = createOrder(Integer.toString(controller.miniModel.players.size()), false, false); - - VBox overlay = new VBox(-20); - overlay.setPickOnBounds(false); - StackPane.setAlignment(overlay, Pos.TOP_LEFT); - StackPane.setMargin(overlay, new Insets(9, 0, 0, 57)); - - int i = 0; - for (Player player : controller.miniModel.players.values()) { - final int index = i; - - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + "blue" + ".png"))); + Player player = controller.miniModel.slotPlayerMap.get(slot); + if (player != null && controller.miniModel.getPositionByUsername(player.getUserName())!=-1) { + ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + player.totem.toString().toLowerCase(Locale.ROOT) + ".png"))); totem.setFitHeight(70); totem.setPreserveRatio(true); - if (!(controller.miniModel.orderLogicCard.getPosition(player.getUserName()) != -1 && !controller.miniModel.slotPlayerMap.containsValue(player))) { - totem.setOpacity(0.0); - } - overlay.getChildren().add(totem); - i++; + StackPane.setAlignment(totem, Pos.TOP_LEFT); + StackPane.setMargin(totem, new Insets(8, 0, 0, 57)); + wrapper.getChildren().add(totem); } - card.getChildren().add(overlay); - board.getChildren().add(card); + + if (withShadow) { + addShadow(wrapper); + } + if (withZoom) { + addHoverZoom(wrapper); + } + return wrapper; } - private void renderBoard() { - board.setSpacing(14); - board.setAlignment(Pos.CENTER); - board.getChildren().clear(); + private StackPane createCard(PlayableCard card, boolean withZoom, boolean withShadow) { + String id = card.getIdIMG(); + ImageView img; + img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + id + ".png"))); + img.setFitHeight(200); + img.setPreserveRatio(true); + addClip(img); - String path = ""; - switch (controller.miniModel.currentState.getEra()) { - case 1 -> path = "/GUIImages/Backs/back-001.png"; - case 2 -> path = "/GUIImages/Backs/back-030.png"; - case 3 -> path = "/GUIImages/Backs/back-058.png"; + StackPane wrapper = new StackPane(img); + + if (withShadow) { + addShadow(wrapper); } - ImageView back = new ImageView(new Image(getClass().getResourceAsStream(path))); - back.setFitHeight(240); - back.setPreserveRatio(true); - Rectangle clip = new Rectangle(); - clip.setWidth(back.getBoundsInLocal().getWidth()); - clip.setHeight(240); - clip.setArcWidth(20); - clip.setArcHeight(20); - back.setClip(clip); - addShadow(back); - addHoverZoom(back); - board.getChildren().add(back); - - - renderOrder(); - - int i = 0; - for (Map.Entry entry : controller.miniModel.slotPlayerMap.entrySet()) { - Slot slot = entry.getKey(); - final int index = i; - StackPane img = createSlot(slot, true, true); - img.setOnMouseClicked(e -> controller.slotChoice(controller.myUsername, index)); - board.getChildren().add(img); - i++; + if (withZoom) { + addHoverZoom(wrapper); } - } - private void renderLower() { - lowerList.setSpacing(14); - lowerList.setAlignment(Pos.CENTER); - lowerList.getChildren().clear(); - - int i = 0; - for (TribeCard card : controller.miniModel.board.lowerListTribe) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawLowerTribeCard(controller.myUsername, index)); - lowerList.getChildren().add(img); - i++; - } - i = 0; - for (BuildingCard card : controller.miniModel.board.lowerListBuilding) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawLowerBuildingCard(controller.myUsername, index)); - lowerList.getChildren().add(img); - i++; - } - } - - // MY HAND - private void renderMyHand() { - myHand.getChildren().clear(); - myHand.setSpacing(14); - myHand.setAlignment(Pos.CENTER); - - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).artists); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).gatherers); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).inventors); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).builders); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).shamans); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).hunters); - drawMyHandList(myHand, controller.miniModel.players.get(controller.myUsername).buildingCards); - } - private void drawMyHandList(HBox myHand, ArrayList cardList) { - if (!cardList.isEmpty()) { - StackPane img = createCard(cardList.getLast(), true, true); - Label label = new Label(String.valueOf(cardList.size())); - label.setTranslateY(-55); - label.setTranslateX(10); - label.getStyleClass().add("label-large"); - StackPane.setAlignment(label, Pos.TOP_RIGHT); - img.getChildren().add(label); // aggiungi il label dentro lo StackPane di createCard - img.setOnMouseClicked(e -> openPopup(cardList)); - myHand.getChildren().add(img); - } else { - Region placeholder = new Region(); - placeholder.setPrefHeight(200); - placeholder.setPrefWidth(200 * 0.675); - placeholder.setStyle("-fx-background-color: transparent;"); - myHand.getChildren().add(placeholder); - } - } - - - // SIDE PANEL - private void renderSidePanel() { - sidePanel.getChildren().clear(); - sidePanel.setSpacing(6); - - era.setText(Integer.toString(controller.miniModel.currentState.getEra())); - round.setText(Integer.toString(controller.miniModel.currentState.getRound())); - player.setText(controller.miniModel.currentState.getCurrentPlayer().getUserName()); - VBox.setMargin(info, new Insets(5, 5, 5, 5)); - sidePanel.getChildren().add(info); - - renderPlayers(sidePanel); - } - private void renderPlayers(VBox playersHand) { - for (Player player : controller.miniModel.players.values()) { - // Card container - VBox card = new VBox(3); - VBox.setMargin(card, new Insets(5)); - card.getStyleClass().add("player-card"); - card.setPadding(new Insets(8)); - addHoverZoom(card); - addShadow(card); - - // Riga 1: icona totem + nome - HBox headerRow = new HBox(8); - headerRow.setAlignment(Pos.CENTER); - int index = new ArrayList<>(controller.miniModel.players.values()).indexOf(player); - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + "blue" + ".png"))); - totem.setFitHeight(20); - totem.setPreserveRatio(true); - Label usernameLabel = new Label(player.getUserName()); - usernameLabel.getStyleClass().add("label-medium"); - if (player.getUserName().equals(controller.myUsername)) { - usernameLabel.setStyle("-fx-text-fill: #9d0208"); - } - headerRow.getChildren().addAll(totem, usernameLabel); - - // Riga 2: cibo + prestigio - HBox statsRow = new HBox(10); - statsRow.setAlignment(Pos.CENTER); - - HBox foodBox = new HBox(4); - foodBox.setAlignment(Pos.CENTER); - ImageView foodIcon = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Icons/Food.png"))); - foodIcon.setFitHeight(20); - foodIcon.setPreserveRatio(true); - Label foodLabel = new Label(String.valueOf(player.getFoodValue())); - foodLabel.getStyleClass().add("label-small"); - foodBox.getChildren().addAll(foodIcon, foodLabel); - - HBox prestigeBox = new HBox(1); - prestigeBox.setAlignment(Pos.CENTER); - ImageView PPIcon = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Icons/PrestigePoint.png"))); - PPIcon.setFitHeight(35); - PPIcon.setPreserveRatio(true); - Label prestigeLabel = new Label(String.valueOf(player.getPrestigeValue())); - prestigeLabel.getStyleClass().add("label-small"); - prestigeBox.getChildren().addAll(PPIcon, prestigeLabel); - - statsRow.getChildren().addAll(foodBox, prestigeBox); - - // Righe 3-4: icone carte (3 per riga) - HBox iconsRow1 = new HBox(6); - iconsRow1.setAlignment(Pos.CENTER); - HBox iconsRow2 = new HBox(6); - iconsRow2.setAlignment(Pos.CENTER); - renderIcons(iconsRow1, iconsRow2, player); // vedi sotto - - card.getChildren().addAll(headerRow, statsRow, iconsRow1, iconsRow2); - playersHand.getChildren().add(card); - } - + return wrapper; } private void renderIcons(HBox iconsRow1, HBox iconsRow2, Player player) { String[][] iconTypes = { @@ -450,7 +216,6 @@ public class MainFXMLController { ArrayList cards = getPlayerCards(player.getUserName(), fieldName); if (cards.isEmpty()) { ColorAdjust grayscale = new ColorAdjust(); - //grayscale.setSaturation(-1.0); icon.setEffect(grayscale); icon.setOpacity(0.3); } else { @@ -476,6 +241,236 @@ public class MainFXMLController { } + // ==== GROUPS ==== + private void renderUpper() { + upperList.setSpacing(14); + upperList.setAlignment(Pos.CENTER); + upperList.getChildren().clear(); + + int i = 0; + for (TribeCard card : controller.miniModel.board.upperListTribe) { + final int index = i; + StackPane img = createCard(card, true, true); + img.setOnMouseClicked(e -> controller.drawUpperTribeCard(controller.myUsername, index)); + upperList.getChildren().add(img); + i++; + } + i = 0; + for (BuildingCard card : controller.miniModel.board.upperListBuilding) { + final int index = i; + StackPane img = createCard(card, true, true); + img.setOnMouseClicked(e -> controller.drawUpperBuildingCard(controller.myUsername, index)); + upperList.getChildren().add(img); + i++; + } + } + private void renderLower() { + lowerList.setSpacing(14); + lowerList.setAlignment(Pos.CENTER); + lowerList.getChildren().clear(); + + int i = 0; + for (TribeCard card : controller.miniModel.board.lowerListTribe) { + final int index = i; + StackPane img = createCard(card, true, true); + img.setOnMouseClicked(e -> controller.drawLowerTribeCard(controller.myUsername, index)); + lowerList.getChildren().add(img); + i++; + } + i = 0; + for (BuildingCard card : controller.miniModel.board.lowerListBuilding) { + final int index = i; + StackPane img = createCard(card, true, true); + img.setOnMouseClicked(e -> controller.drawLowerBuildingCard(controller.myUsername, index)); + lowerList.getChildren().add(img); + i++; + } + } + private void renderDeck() { + String path = ""; + switch (controller.miniModel.currentState.getEra()) { + case 1 -> path = "/GUIImages/Backs/back-001.png"; + case 2 -> path = "/GUIImages/Backs/back-030.png"; + case 3 -> path = "/GUIImages/Backs/back-058.png"; + } + ImageView back = new ImageView(new Image(getClass().getResourceAsStream(path))); + back.setFitHeight(240); + back.setPreserveRatio(true); + addClip(back); + addShadow(back); + addHoverZoom(back); + board.getChildren().add(back); + } + private void renderOrder() { + StackPane card = createOrder(Integer.toString(controller.miniModel.players.size())); + + VBox overlay = new VBox(-20); + overlay.setPickOnBounds(false); + StackPane.setAlignment(overlay, Pos.TOP_LEFT); + StackPane.setMargin(overlay, new Insets(9, 0, 0, 57)); + + List ordered = controller.miniModel.players.values().stream() + .filter(p -> !controller.miniModel.orderLogicCard.players.contains(p)) + .collect(Collectors.toList()); + ordered.addAll(controller.miniModel.orderLogicCard.players); + for (Player player : ordered) { + ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + player.totem.toString().toLowerCase(Locale.ROOT) + ".png"))); + totem.setFitHeight(70); + totem.setPreserveRatio(true); + if (!controller.miniModel.orderLogicCard.players.contains(player)) { + totem.setOpacity(0.5); + } + overlay.getChildren().add(totem); + } + card.getChildren().add(overlay); + board.getChildren().add(card); + } + private void renderSlotMap() { + int i = 0; + for (Map.Entry entry : controller.miniModel.slotPlayerMap.entrySet()) { + Slot slot = entry.getKey(); + final int index = i; + StackPane img = createSlot(slot, true, true); + img.setOnMouseClicked(e -> controller.slotChoice(controller.myUsername, index)); + board.getChildren().add(img); + i++; + } + } + private void drawMyHandList(ArrayList cardList) { + if (!cardList.isEmpty()) { + StackPane img = createCard(cardList.getLast(), true, true); + Label label = new Label(String.valueOf(cardList.size())); + label.setTranslateY(-55); + label.setTranslateX(10); + label.getStyleClass().add("label-large"); + StackPane.setAlignment(label, Pos.TOP_RIGHT); + img.getChildren().add(label); + img.setOnMouseClicked(e -> openPopup(cardList)); + myHand.getChildren().add(img); + } else { + Region placeholder = new Region(); + placeholder.setPrefHeight(200); + placeholder.setPrefWidth(200 * 0.675); + placeholder.setStyle("-fx-background-color: transparent;"); + myHand.getChildren().add(placeholder); + } + } + private void renderPlayer(Player player) { + VBox card = new VBox(3); + VBox.setMargin(card, new Insets(5)); + card.getStyleClass().add("player-card"); + card.setPadding(new Insets(8)); + addHoverZoom(card); + addShadow(card); + + // Riga 1: icona totem + nome + HBox headerRow = new HBox(8); + headerRow.setAlignment(Pos.CENTER); + ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + player.totem.toString().toLowerCase(Locale.ROOT) + ".png"))); + totem.setFitHeight(20); + totem.setPreserveRatio(true); + Label usernameLabel = new Label(player.getUserName()); + usernameLabel.getStyleClass().add("label-medium"); + if (player.getUserName().equals(controller.myUsername)) { + usernameLabel.setStyle("-fx-text-fill: #9d0208"); + } + headerRow.getChildren().addAll(totem, usernameLabel); + + // Riga 2: cibo + prestigio + HBox statsRow = new HBox(10); + statsRow.setAlignment(Pos.CENTER); + + HBox foodBox = new HBox(4); + foodBox.setAlignment(Pos.CENTER); + ImageView foodIcon = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Icons/Food.png"))); + foodIcon.setFitHeight(20); + foodIcon.setPreserveRatio(true); + Label foodLabel = new Label(String.valueOf(player.getFoodValue())); + foodLabel.getStyleClass().add("label-small"); + foodBox.getChildren().addAll(foodIcon, foodLabel); + + HBox prestigeBox = new HBox(1); + prestigeBox.setAlignment(Pos.CENTER); + ImageView PPIcon = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Icons/PrestigePoint.png"))); + PPIcon.setFitHeight(35); + PPIcon.setPreserveRatio(true); + Label prestigeLabel = new Label(String.valueOf(player.getPrestigeValue())); + prestigeLabel.getStyleClass().add("label-small"); + prestigeBox.getChildren().addAll(PPIcon, prestigeLabel); + + statsRow.getChildren().addAll(foodBox, prestigeBox); + + // Righe 3-4: icone carte (3 per riga) + HBox iconsRow1 = new HBox(6); + iconsRow1.setAlignment(Pos.CENTER); + HBox iconsRow2 = new HBox(6); + iconsRow2.setAlignment(Pos.CENTER); + renderIcons(iconsRow1, iconsRow2, player); // vedi sotto + + card.getChildren().addAll(headerRow, statsRow, iconsRow1, iconsRow2); + sidePanel.getChildren().add(card); + } + + + // ==== ABSOLUTES ==== + private void renderBackground() { + BackgroundSize size = new BackgroundSize( + BackgroundSize.AUTO, BackgroundSize.AUTO, + false, false, true, true + ); + mainHBox.setBackground(new Background(new BackgroundImage( + new Image(getClass().getResourceAsStream("/GUIImages/Background.png")), + BackgroundRepeat.NO_REPEAT, + BackgroundRepeat.NO_REPEAT, + BackgroundPosition.CENTER, + size + ))); + } + private void renderBoard() { + board.setSpacing(14); + board.setAlignment(Pos.CENTER); + board.getChildren().clear(); + renderDeck(); + renderOrder(); + renderSlotMap(); + } + private void renderMyHand() { + myHand.getChildren().clear(); + myHand.setSpacing(14); + myHand.setAlignment(Pos.CENTER); + + drawMyHandList(controller.miniModel.players.get(controller.myUsername).artists); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).gatherers); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).inventors); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).builders); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).shamans); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).hunters); + drawMyHandList(controller.miniModel.players.get(controller.myUsername).buildingCards); + } + private void renderSidePanel() { + sidePanel.getChildren().clear(); + sidePanel.setSpacing(6); + + era.setText(Integer.toString(controller.miniModel.currentState.getEra())); + round.setText(Integer.toString(controller.miniModel.currentState.getRound())); + player.setText(controller.miniModel.currentState.getCurrentPlayer().getUserName()); + VBox.setMargin(info, new Insets(5, 5, 5, 5)); + sidePanel.getChildren().add(info); + + for (Player player : controller.miniModel.players.values()) { + renderPlayer(player); + } + } + + + + + + + + + + // POPUP private void initPopup() { popupCards = new HBox(10); @@ -489,12 +484,7 @@ public class MainFXMLController { "-fx-background-radius: 10;" ); - Rectangle clip = new Rectangle(); - clip.setArcWidth(20); - clip.setArcHeight(20); - clip.widthProperty().bind(popupCards.widthProperty()); - clip.heightProperty().bind(popupCards.heightProperty()); - popupCards.setClip(clip); + addClip(popupCards); popup = new Popup(); popup.getContent().add(popupCards); diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 3adc89b..d9c6aee 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -5,6 +5,7 @@ module it.polimi.ingsw.gc14 { requires java.rmi; requires java.smartcardio; requires com.google.gson; + requires java.desktop; opens it.polimi.ingsw.gc14 to javafx.fxml, com.google.gson; opens it.polimi.ingsw.gc14.Model to com.google.gson;