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 6121fcd..3d3b26b 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/GamePackage/Board.java b/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/Board.java index ac2c9e5..6e3023c 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/Board.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/Board.java @@ -176,8 +176,8 @@ public class Board implements Serializable { tribeDeck_temp.addAll(era1); tribeDeck_temp.addAll(era2); tribeDeck_temp.addAll(era3); - tribeDeck_temp.add(new Sustenance("95",3,3)); - tribeDeck_temp.add(new ShamanicRitual("96",3,15,7)); + tribeDeck_temp.add(new Sustenance("095",3,3)); + tribeDeck_temp.add(new ShamanicRitual("096",3,15,7)); return tribeDeck_temp; } 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..78c9d10 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,82 @@ 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.io.Serializable; -import java.rmi.RemoteException; import java.util.*; -//TODO + public class MiniModel implements Serializable { + 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 --- + + 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); } + + + // --- Setter --- + public void setBoard(Board board) { this.board = board; } - public void setAvailableTotems(ListavailableTotems) { + + public void setAvailableTotems(List availableTotems) { this.availableTotems = availableTotems; } - public void setSlotPlayerMap(Map slotPlayerMap) { + + public void setSlotPlayerMap(Map slotPlayerMap) { this.slotPlayerMap = slotPlayerMap; } + public void setOrderLogicCard(OrderLogicCard orderLogicCard) { this.orderLogicCard = orderLogicCard; } + public void setCurrentState(CurrentState currentState) { this.currentState = currentState; } + public void setPlayers(List players) { for (Player player : players) { - this.players.put(player.getUserName(),player); + this.players.put(player.getUserName(), player); } } - public void setPlayer(Player player) - { - players.put(player.getUserName(),player); + + public void setPlayer(Player player) { + players.put(player.getUserName(), player); } - public int getPositionByUsername(String username) - { - int i=0; - for (Player player : players.values()) - { - if(player.getUserName().equals(username)) - { + + + 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 d49b955..143ee83 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java @@ -20,12 +20,12 @@ 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. */ - protected List playerList; + public List playerList; /** diff --git a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java index 60a848e..2321955 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java +++ b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java @@ -256,7 +256,10 @@ public class ServerLauncher { while (true) { try{ this.doFirstEvent(); - this.view.fullRender(); + if(view!=null) + { + view.fullRender(); + } } catch(InterruptedException e){ Thread.currentThread().interrupt(); 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 1d2fa3d..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 @@ -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"); @@ -81,10 +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/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java index 608e885..5274d97 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,12 @@ 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 it.polimi.ingsw.gc14.Model.GamePackage.GameStages; +import it.polimi.ingsw.gc14.Model.Orders.OrderPlayer; import javafx.animation.ScaleTransition; +import javafx.application.Platform; import javafx.event.Event; import javafx.fxml.FXML; import javafx.geometry.Insets; @@ -24,9 +29,11 @@ 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; + +import static it.polimi.ingsw.gc14.Model.GamePackage.GameStages.RES_ACTIONS; +import static it.polimi.ingsw.gc14.Model.GamePackage.GameStages.SLOT_CHOICE; public class MainFXMLController { @@ -47,20 +54,24 @@ public class MainFXMLController { private Popup popup; private HBox popupCards; - private MiniModel model; private ClientController controller; - private String username; - private final Map cardCache = new HashMap<>(); + private GameStages old_state_stage; + private String old_state_username; - public void setModel(MiniModel model) {this.model = model;} - public void setController(ClientController controller) {this.controller = controller;} - public void setUsername(String username) {this.username = username;} + + public void setController(ClientController controller) { + this.controller = controller; + } @FXML public void initialize() { + old_state_stage=null; + old_state_username=""; + + // Import font and apply CSS Font.loadFont(getClass().getResourceAsStream("/Fonts/InknutAntiqua-Regular.ttf"), 14); mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> { @@ -74,95 +85,51 @@ public class MainFXMLController { } + public void render() { - renderBackground(); - renderUpper(); - renderBoard(); - renderLower(); - renderMyHand(); - 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); - 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); - if (withShadow) { - addShadow(wrapper); - } - if (withZoom) { - addHoverZoom(wrapper); - } - return wrapper; - } + if (old_state_stage==null) { + renderBackground(); + renderUpper(); + renderBoard(); + renderLower(); + renderMyHand(); + renderSidePanel(); + } else if (old_state_stage==SLOT_CHOICE ) { + System.out.println("OLD: "+old_state_stage+", NEW: "+controller.miniModel.currentState.getGameStage()); + System.out.println("RIDISEGNO BOARD\n"); + renderBoard(); + } else if (old_state_stage==RES_ACTIONS) { + System.out.println("OLD: "+old_state_stage+", NEW: "+controller.miniModel.currentState.getGameStage()); + System.out.println("RIDISEGNO TUTTO. USERNAME: "+old_state_username); + renderUpper(); + renderBoard(); + renderLower(); + renderSidePanel(); + if (Objects.equals(old_state_username, controller.myUsername)) { + renderMyHand(); + } - 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 = model.slotPlayerMap.get(slot); - if (player != null && model.getPositionByUsername(player.getUserName())!=-1) { - int index = model.getPositionByUsername(player.getUserName()); - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + index + ".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()); + // TODO: se sono io a pescare renderizzo myHand, altrimenti no (non è scontato) } else { - img = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Fronts/card-" + id + ".png"))); - cardCache.put(id, img); + System.out.println("NON GESTITO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } - img.setFitHeight(200); - img.setPreserveRatio(true); + old_state_stage=controller.miniModel.currentState.getGameStage(); + old_state_username=controller.miniModel.currentState.getCurrentPlayer().getUserName(); + // TODO: le info in sidepanel non vengono aggiornate sempre aggiornate, bisogna prima capire dove metterle + + } + + + // ==== EFFECTS ==== + private void addClip(Node node) { Rectangle clip = new Rectangle(); - clip.setWidth(img.getBoundsInLocal().getWidth()); - clip.setHeight(200); + 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; + node.setClip(clip); } private void addHoverZoom(Node node) { ScaleTransition scaleUp = new ScaleTransition(Duration.millis(150), node); @@ -174,7 +141,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)); @@ -197,237 +163,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 : model.board.upperListTribe) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawUpperTribeCard(username, index)); - upperList.getChildren().add(img); - i++; - } - i = 0; - for (BuildingCard card : model.board.upperListBuilding) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawUpperBuildingCard(username, index)); - upperList.getChildren().add(img); - i++; - } - } - private void renderOrder() { - StackPane card = createOrder(Integer.toString(model.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 : model.players.values()) { - final int index = i; - - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + index + ".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 (!(model.orderLogicCard.getPosition(player.getUserName()) != -1 && !model.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 (model.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 : model.slotPlayerMap.entrySet()) { - Slot slot = entry.getKey(); - final int index = i; - StackPane img = createSlot(slot, true, true); - img.setOnMouseClicked(e -> controller.slotChoice(username, 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 : model.board.lowerListTribe) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawLowerTribeCard(username, index)); - lowerList.getChildren().add(img); - i++; - } - i = 0; - for (BuildingCard card : model.board.lowerListBuilding) { - final int index = i; - StackPane img = createCard(card, true, true); - img.setOnMouseClicked(e -> controller.drawLowerBuildingCard(username, index)); - lowerList.getChildren().add(img); - i++; - } - } - - // MY HAND - private void renderMyHand() { - myHand.getChildren().clear(); - myHand.setSpacing(14); - myHand.setAlignment(Pos.CENTER); - - drawMyHandList(myHand, model.players.get(username).artists); - drawMyHandList(myHand, model.players.get(username).gatherers); - drawMyHandList(myHand, model.players.get(username).inventors); - drawMyHandList(myHand, model.players.get(username).builders); - drawMyHandList(myHand, model.players.get(username).shamans); - drawMyHandList(myHand, model.players.get(username).hunters); - drawMyHandList(myHand, model.players.get(username).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(model.currentState.getEra())); - round.setText(Integer.toString(model.currentState.getRound())); - player.setText(model.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 : model.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<>(model.players.values()).indexOf(player); - ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + index + ".png"))); - totem.setFitHeight(20); - totem.setPreserveRatio(true); - Label usernameLabel = new Label(player.getUserName()); - usernameLabel.getStyleClass().add("label-medium"); - if (player.getUserName().equals(username)) { - 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 = { @@ -452,7 +238,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 { @@ -465,7 +250,7 @@ public class MainFXMLController { } } private ArrayList getPlayerCards(String username, String type) { - Player p = model.players.get(username); + Player p = controller.miniModel.players.get(username); return switch (type) { case "artists" -> new ArrayList<>(p.artists); case "gatherers" -> new ArrayList<>(p.gatherers); @@ -478,6 +263,232 @@ 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)); + + for (OrderPlayer player : controller.miniModel.orderLogicCard.playerList) { + ImageView totem = new ImageView(new Image(getClass().getResourceAsStream("/GUIImages/Totems/totem_" + player.player.totem.toString().toLowerCase(Locale.ROOT) + ".png"))); + totem.setFitHeight(70); + totem.setPreserveRatio(true); + if(controller.miniModel.slotPlayerMap.containsValue(player.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); @@ -491,12 +502,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/it/polimi/ingsw/gc14/View/GUI/MainView.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainView.java deleted file mode 100644 index bc5bb86..0000000 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainView.java +++ /dev/null @@ -1,49 +0,0 @@ -package it.polimi.ingsw.gc14.View.GUI; - -import it.polimi.ingsw.gc14.Controller.ClientController; -import it.polimi.ingsw.gc14.Model.Game; -import it.polimi.ingsw.gc14.Model.MiniModel; -import javafx.fxml.FXMLLoader; -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.Scene; -import javafx.scene.control.Label; -import javafx.scene.layout.VBox; - -import java.io.IOException; - -public class MainView { - - private final Scene scene; - private final MainFXMLController fxmlController; - private MiniModel model; - private ClientController controller; - private String username; - - public MainView() { - try { - FXMLLoader loader = new FXMLLoader( - getClass().getResource("/GUIScene/main.fxml") - ); - scene = new Scene(loader.load(), 1920, 1080); - fxmlController = loader.getController(); - } catch (IOException e) { - throw new RuntimeException("Impossibile caricare login.fxml", e); - } - } - - public Scene getScene() { return scene; } - public void setModel(MiniModel model, ClientController controller, String username) { - this.model = model; - fxmlController.setModel(model); - this.controller = controller; - fxmlController.setController(controller); - this.username = username; - fxmlController.setUsername(username); - - } - public void render() { - fxmlController.render(); - } - -} \ No newline at end of file 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 1b2f6f8..6e128b4 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,39 +1,204 @@ 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 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() { - 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)); - mainHBox.getChildren().add(img); + mainHBox.getChildren().clear(); + selectedIndex = -1; + selectedFrame = null; + + 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 choose ✦"); + turnBanner.setStyle( + "-fx-font-family: 'Cinzel'; -fx-font-size: 13; -fx-letter-spacing: 3;" + + "-fx-text-fill: #000000;" + + "-fx-background-color: linear-gradient(to right, #f4c05a, #c8791a, #f4c05a);" + + "-fx-border-color: #000000; -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 for" + chooser + " to choose his totem…"); + turnBanner.setStyle( + "-fx-font-family: 'Cinzel'; -fx-font-size: 11; -fx-letter-spacing: 2;" + + "-fx-text-fill: #000000;" + + "-fx-background-color: linear-gradient(to right, #f4c05a, #c8791a, #f4c05a);" + + "-fx-border-color: #000000; -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(); + + 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 ? "#75FF79" : "rgba(200,120,20,0.28)") + ";" + + "-fx-border-width: " + (selected ? "0" : "0") + ";" + + "-fx-border-radius: 4 4 0 0; -fx-background-radius: 4 4 0 0;" + + (selected ? "-fx-effect: dropshadow(gaussian, #ffffff, 20, 0.33, 0, 0);" : ""); + } + + private String nameStyle(boolean selected) { + return "-fx-font-family: 'Cinzel'; -fx-font-size: 10; -fx-letter-spacing: 2;" + + "-fx-text-fill: " + (selected ? "#ffffff" : "ffffff") + ";"; + } + + private String capitalize(Totems t) { + String s = t.name().toLowerCase(Locale.ROOT); + return Character.toUpperCase(s.charAt(0)) + s.substring(1); + } -} + @FXML + private void onConfirm() { + if (selectedIndex >= 0) { + controller.totemChoice(controller.myUsername, selectedIndex); + } + } +} \ No newline at end of file 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; diff --git a/src/main/resources/GUIScene/main.fxml b/src/main/resources/GUIScene/main.fxml index 62d9eb4..b72f4cf 100644 --- a/src/main/resources/GUIScene/main.fxml +++ b/src/main/resources/GUIScene/main.fxml @@ -1,15 +1,23 @@ - - - + - - + + @@ -37,8 +45,13 @@ - - + + @@ -67,5 +80,6 @@ + - + \ No newline at end of file diff --git a/src/main/resources/GUIScene/totem.fxml b/src/main/resources/GUIScene/totem.fxml index 9e41caa..40ca776 100644 --- a/src/main/resources/GUIScene/totem.fxml +++ b/src/main/resources/GUIScene/totem.fxml @@ -1,6 +1,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + +