diff --git a/.gitignore b/.gitignore index dccc202ed..694b3d454 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,9 @@ target/ .idea *.iml *.db -.idea -.xml \ No newline at end of file +!.idea +.idea/inspectionProfiles/Project_Default.xml + +*.xml + +.idea/ diff --git a/Client/src/main/java/de/uol/swp/client/ClientApp.java b/Client/src/main/java/de/uol/swp/client/ClientApp.java index 824501320..0f3617cf1 100644 --- a/Client/src/main/java/de/uol/swp/client/ClientApp.java +++ b/Client/src/main/java/de/uol/swp/client/ClientApp.java @@ -6,6 +6,7 @@ import com.google.inject.Guice; import com.google.inject.Injector; import de.uol.swp.client.di.ClientModule; +import de.uol.swp.client.game.GameService; import de.uol.swp.client.lobby.LobbyService; import de.uol.swp.client.sound.SoundMediaPlayer; import de.uol.swp.common.lobby.message.*; @@ -22,7 +23,6 @@ import io.netty.channel.Channel; import javafx.application.Application; import javafx.application.Platform; -import javafx.scene.control.Alert; import javafx.stage.Stage; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -37,6 +37,7 @@ public class ClientApp extends Application implements ConnectionListener { private int port; private UserService userService; private LobbyService lobbyService; + private GameService gameService; private User user; private ClientConnection clientConnection; private EventBus eventBus; @@ -98,6 +99,7 @@ public void start(Stage primaryStage) { // get user service from guice, is needed for logout this.userService = injector.getInstance(UserService.class); this.lobbyService = injector.getInstance(LobbyService.class); + this.gameService = injector.getInstance(GameService.class); // get event bus from guice eventBus = injector.getInstance(EventBus.class); @@ -229,11 +231,7 @@ public void onCreateLobbyMessage(CreateLobbyMessage message) { @Subscribe public void onUserJoinedLobbyMessage(UserJoinedLobbyMessage message) { if (message.getUser().getUsername().equals(user.getUsername())) { - if (sceneManager.getGameManagement(message.getLobbyID()) != null) { - sceneManager.getGameManagement(message.getLobbyID()).showLobbyView(); - } else { - sceneManager.showLobbyScreen(message.getUser(), message.getLobby().getName(), message.getLobbyID(), message.getGameOwner()); - } + sceneManager.showLobbyScreen(message.getUser(), message.getLobby().getName(), message.getLobbyID(), message.getGameOwner()); LOG.info("User " + message.getUser().getUsername() + " joined lobby successfully"); } } @@ -251,7 +249,6 @@ public void onUserLeftLobbyMessage(UserLeftLobbyMessage message) { if (message.getUser().getUsername().equals(user.getUsername())) { sceneManager.showMainScreen(user); LOG.info("User " + message.getUser().getUsername() + " left lobby successfully"); - sceneManager.getGameManagement(message.getLobbyID()).close(); } } @@ -299,13 +296,12 @@ public void onUpdateUserFailedMessage(UpdateUserFailedMessage message) { } } - /** * Empfängt vom Server die Message, dass ein User gekickt wurde. Bei diesem User wird das Lobbyfenster * geschlossen und das MainMenu wird angezeigt * * @param message KickUserMessage - * @author Darian. Marvin + * @author Darian, Marvin * @since Sprint 4 */ @Subscribe @@ -313,8 +309,6 @@ public void onKickUserMessage(KickUserMessage message) { if (message.getUser().getUsername().equals(user.getUsername())) { sceneManager.showMainScreen(user); LOG.info("User " + message.getUser().getUsername() + " is kicked from the lobby successfully"); - sceneManager.getGameManagement(message.getLobbyID()).close(); - SceneManager.showAlert(Alert.AlertType.WARNING, "Sie wurden aus der Lobby entfernt", "Lobby verlassen"); } } @@ -333,6 +327,7 @@ public void onKickUserMessage(KickUserMessage message) { @Subscribe public void onUserLoggedOutMessage(UserLoggedOutMessage message) { LOG.info("Logout and leaving of all lobbies successful."); + if (message.getUsername().equals(user.getUsername())) { sceneManager.closeAllStages(); sceneManager.showLoginScreen(); diff --git a/Client/src/main/java/de/uol/swp/client/SceneManager.java b/Client/src/main/java/de/uol/swp/client/SceneManager.java index b4dd84e0e..854548ed3 100644 --- a/Client/src/main/java/de/uol/swp/client/SceneManager.java +++ b/Client/src/main/java/de/uol/swp/client/SceneManager.java @@ -8,11 +8,10 @@ import de.uol.swp.client.auth.LoginPresenter; import de.uol.swp.client.auth.events.ShowLoginViewEvent; import de.uol.swp.client.chat.ChatService; -import de.uol.swp.client.game.GameManagement; import de.uol.swp.client.game.GameService; import de.uol.swp.client.game.event.GameQuitEvent; import de.uol.swp.client.lobby.LobbyService; -import de.uol.swp.client.main.MainMenuPresenter; +import de.uol.swp.client.main.PrimaryPresenter; import de.uol.swp.client.register.RegistrationPresenter; import de.uol.swp.client.register.event.RegistrationCanceledEvent; import de.uol.swp.client.register.event.RegistrationErrorEvent; @@ -23,9 +22,9 @@ import de.uol.swp.client.settings.event.CloseSettingsEvent; import de.uol.swp.client.settings.event.DeleteAccountEvent; import de.uol.swp.client.sound.SoundMediaPlayer; +import de.uol.swp.client.user.UserService; import de.uol.swp.common.user.User; import de.uol.swp.common.user.UserDTO; -import de.uol.swp.common.user.UserService; import javafx.application.Platform; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; @@ -37,8 +36,6 @@ import org.apache.logging.log4j.Logger; import java.net.URL; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; /** @@ -68,13 +65,11 @@ public class SceneManager { private Scene mainScene; private Scene settingsScene; private Scene deleteAccountScene; - private Scene gameScene; private Scene lastScene = null; private Scene currentScene = null; private User currentUser; - private Map lobbyScenes = new HashMap<>(); - private Map games = new HashMap<>(); - private Map lobbyStages = new HashMap<>(); + private PrimaryPresenter primaryPresenter; + private Scene primaryScene; @Inject @@ -209,7 +204,7 @@ public void showLoginErrorScreen() { } public void showMainScreen(User currentUser) { - showScene(mainScene, "Welcome " + currentUser.getUsername()); + showScene(primaryScene, "Welcome " + currentUser.getUsername()); } @@ -233,13 +228,7 @@ public void showRegistrationScreen() { public void showLobbyScreen(User currentUser, String title, UUID lobbyID, UserDTO gameOwner) { Platform.runLater(() -> { //neue Instanz des LobbyPresenter mit (name, id) wird erstellt - GameManagement gameManagement = new GameManagement(eventBus, lobbyID, title, currentUser, chatService, lobbyService, userService, injector, gameOwner, gameService); - - eventBus.register(gameManagement); - - //LobbyPresenter und lobbyStage in der jeweilige Map speichern. Die lobbyID dient als Schlüssel. - games.put(lobbyID, gameManagement); - gameManagement.showLobbyView(); + primaryPresenter.createLobby(currentUser, title, lobbyID, gameOwner); }); } @@ -267,18 +256,6 @@ public void showSettingsScreen(User loggedInUser) { }); } - /** - * Gibt die übergebenen lobbyID zurück, die zum jeweiligen GameManagement gehört. - * - * @param lobbyID die übergebene LobbyID - * @return GameManagement - * @author Julia, Paula - * @since Sprint3 - */ - public GameManagement getGameManagement(UUID lobbyID) { - return games.get(lobbyID); - } - /** * Schließt alle Stages * @@ -287,7 +264,6 @@ public GameManagement getGameManagement(UUID lobbyID) { */ public void closeAllStages() { Platform.runLater(() -> { - games.values().forEach(GameManagement::close); if (settingsStage != null) { settingsStage.close(); } @@ -307,8 +283,8 @@ public void closeSettings() { private void initViews() { initLoginView(); - initMainView(); initRegistrationView(); + initPrimaryView(); } private Parent initPresenter(String fxmlFile) { @@ -325,6 +301,36 @@ private Parent initPresenter(String fxmlFile) { return rootPane; } + private Parent initPresenter(String fxmlFile, PrimaryPresenter presenter) { + Parent rootPane; + FXMLLoader loader = injector.getInstance(FXMLLoader.class); + try { + URL url = getClass().getResource(fxmlFile); + LOG.debug("Loading " + url); + loader.setLocation(url); + loader.setController(presenter); + rootPane = loader.load(); + } catch (Exception e) { + throw new RuntimeException("Could not load View!" + e.getMessage(), e); + } + return rootPane; + } + + private void initPrimaryView() { + if (primaryScene == null) { + primaryPresenter = new PrimaryPresenter(); + primaryPresenter.initialise(eventBus, currentUser, chatService, lobbyService, userService, injector, gameService); + Parent rootPane = initPresenter(PrimaryPresenter.fxml, primaryPresenter); + primaryScene = new Scene(rootPane, 1400, 790); + primaryScene.getStylesheets().add(styleSheet); + primaryScene.getStylesheets().add(PrimaryPresenter.css); + primaryStage.setOnCloseRequest(event -> { + userService.logout(currentUser); + }); + eventBus.register(primaryPresenter); + } + } + private Parent initSettingsPresenter(SettingsPresenter settingsPresenter) { Parent rootPane; FXMLLoader loader = injector.getInstance(FXMLLoader.class); @@ -355,15 +361,6 @@ private Parent initDeleteAccountPresenter(DeleteAccountPresenter deleteAccountPr return rootPane; } - private void initMainView() { - if (mainScene == null) { - Parent rootPane = initPresenter(MainMenuPresenter.fxml); - mainScene = new Scene(rootPane, 1280, 750); - mainScene.getStylesheets().add(styleSheet); - mainScene.getStylesheets().add(MainMenuPresenter.css); - } - } - private void initLoginView() { if (loginScene == null) { Parent rootPane = initPresenter(LoginPresenter.fxml); @@ -393,9 +390,9 @@ private void initSettingsView(SettingsPresenter settingsPresenter) { private void initDeleteAccountView() { if (deleteAccountScene == null) { Parent rootPane = initDeleteAccountPresenter(new DeleteAccountPresenter(currentUser, lobbyService, userService, eventBus)); - deleteAccountScene = new Scene(rootPane, 200, 100); + deleteAccountScene = new Scene(rootPane, 250, 100); deleteAccountScene.getStylesheets().add(SettingsPresenter.css); } } -} +} \ No newline at end of file diff --git a/Client/src/main/java/de/uol/swp/client/di/ClientModule.java b/Client/src/main/java/de/uol/swp/client/di/ClientModule.java index c1cb6d320..48bf212ab 100644 --- a/Client/src/main/java/de/uol/swp/client/di/ClientModule.java +++ b/Client/src/main/java/de/uol/swp/client/di/ClientModule.java @@ -8,6 +8,7 @@ import de.uol.swp.client.SceneManager; import de.uol.swp.client.SceneManagerFactory; import de.uol.swp.client.chat.ChatService; +import de.uol.swp.client.game.GameService; import de.uol.swp.client.user.UserService; import javafx.fxml.FXMLLoader; diff --git a/Client/src/main/java/de/uol/swp/client/game/AnimationManagement.java b/Client/src/main/java/de/uol/swp/client/game/AnimationManagement.java index 181255ded..dfd13e7b3 100644 --- a/Client/src/main/java/de/uol/swp/client/game/AnimationManagement.java +++ b/Client/src/main/java/de/uol/swp/client/game/AnimationManagement.java @@ -1,6 +1,7 @@ package de.uol.swp.client.game; import javafx.animation.PathTransition; +import javafx.scene.Parent; import javafx.scene.image.ImageView; import javafx.scene.shape.ArcTo; import javafx.scene.shape.LineTo; @@ -8,28 +9,26 @@ import javafx.scene.shape.Path; import javafx.util.Duration; -import java.util.List; public class AnimationManagement { - private static final double HAND_X = 294; - private static final double HAND_Y = 598; + private static final double HAND_X = 460; - private static final double ABLAGE_X = 733 + 30; - private static final double ABLAGE_Y = 538 + 92; + private static final double ABLAGE_X = 1156; + private static final double ABLAGE_Y = 590; - private static final double ACTION_ZONE_X = 370; - private static final double ACTION_ZONE_Y = 421; + private static final double ACTION_ZONE_X = 510; + private static final double ACTION_ZONE_Y = 600; private static final double ACTION_ZONE_OPPONENT_X = ACTION_ZONE_X; - private static final double ACTION_ZONE_OPPONENT_Y = 31; + private static final double ACTION_ZONE_OPPONENT_Y = 205; - private static final double TRASH_X = 100; - private static final double TRASH_Y = 233; + private static final double TRASH_X = 150; + private static final double TRASH_Y = 455; /** - * Erstellt ein neues MoveTo Objekt für den Pfad, wobei die aktuellen Kooridnaten der Karte übernommen werden. + * Erstellt ein neues MoveTo Objekt für den Pfad, wobei die aktuellen Koordinaten der Karte übernommen werden. * * @param card die Kare * @return MoveTo @@ -39,7 +38,7 @@ public class AnimationManagement { public static MoveTo keepPosition(ImageView card) { double w = card.getFitWidth() / 2; double h = card.getFitHeight() / 2; - return new MoveTo(w, h); + return new MoveTo(w + card.getParent().getLayoutX(), h + card.getParent().getLayoutY()); } /** @@ -48,20 +47,21 @@ public static MoveTo keepPosition(ImageView card) { * Die neuen Koordinaten werden am Ende übernommen. * * @param card die zu bewegende Karte + * @param moveTo der Startpunkt * @param EndPointX die X-Koordinate des Endpunktes * @param EndPointY die Y-Koordinate des Endpunktes * @return boolean ob die Bewegung durchgeführt wurde * @author Anna * @since Sprint5 */ - public static Boolean createLineToPath(ImageView card, double EndPointX, double EndPointY) { + public static PathTransition createLineToPath(ImageView card, MoveTo moveTo, double EndPointX, double EndPointY) { double x = card.getLayoutX(); double y = card.getLayoutY(); double w = card.getFitWidth() / 2; double h = card.getFitHeight() / 2; if (x != EndPointX || y != EndPointY) { Path path = new Path(); - path.getElements().add(new MoveTo(w, h)); + path.getElements().add(moveTo); path.getElements().add(new LineTo(EndPointX - x + w, EndPointY - y + h)); PathTransition pathTransition = new PathTransition(); pathTransition.setDuration(Duration.millis(1000)); @@ -70,10 +70,9 @@ public static Boolean createLineToPath(ImageView card, double EndPointX, double pathTransition.setCycleCount(1); card.toFront(); pathTransition.play(); - setNewCoordinates(card, pathTransition); - return true; + return pathTransition; } - return false; + return null; } /** @@ -92,8 +91,8 @@ public static Boolean createLineToPath(ImageView card, double EndPointX, double * @since Sprint5 */ public static Boolean createArcToPath(ImageView card, MoveTo moveTo, double EndPointX, double EndPointY, int count, boolean largeArc) { - double x = card.getLayoutX(); - double y = card.getLayoutY(); + double x = card.getBoundsInParent().getMinX(); + double y = card.getBoundsInParent().getMinY(); double w = card.getFitWidth() / 2; double h = card.getFitHeight() / 2; EndPointX = EndPointX + w + count * w; @@ -150,8 +149,8 @@ public static Boolean opponentPlaysCard(ImageView card, int count) { * @author Anna * @since Sprint5 */ - public static Boolean buyCard(ImageView card) { - return createLineToPath(card, ABLAGE_X, ABLAGE_Y); + public static PathTransition buyCard(ImageView card) { + return createLineToPath(card, keepPosition(card), ABLAGE_X, ABLAGE_Y); } /** @@ -162,8 +161,8 @@ public static Boolean buyCard(ImageView card) { * @author Anna * @since Sprint5 */ - public static Boolean opponentBuysCard(ImageView card) { - return createLineToPath(card, 334, -300); + public static PathTransition opponentBuysCard(ImageView card) { + return createLineToPath(card, keepPosition(card), 334, -300); } /** @@ -180,35 +179,31 @@ public static Boolean deleteCard(ImageView card) { /** * Die übergebene Karte wird zur Hand des Spieler hinzugefügt. - * Wenn mehr als 5 Karten auf der Hand liegen, werden die Abstände verringert. * Die bewegte Karte wird dabei in den Vordergrund gerückt. * Die neuen Koordinaten werden übernommen. * - * @param card die Karte - * @param count gibt an, die wievielte Karte hinzugefügt wird - * @param smallSpace gibt an, ob ein kleinerer Abstand genommen werden soll + * @param card die Karte + * @param count gibt an, die wievielte Karte hinzugefügt wird * @author Anna * @since Sprint5 */ - public static Boolean addToHand(ImageView card, int count, boolean smallSpace) { - double xValue = card.getLayoutX(); - double yValue = card.getLayoutY(); + public static Boolean addToHand(ImageView card, int count) { + Parent parent = card.getParent(); double w = card.getFitWidth() / 2; double h = card.getFitHeight() / 2; - if ((smallSpace && HAND_X + count * w != xValue) || (!smallSpace && HAND_X + count * w * 2 + 5 * count != xValue)) { + double endPointX = parent.getLayoutX() + parent.getBoundsInLocal().getWidth() / 2 - w - HAND_X - w * 2 * count; + endPointX += 350; + parent.toBack(); + if (HAND_X + count * w != endPointX) { Path path = new Path(); - path.getElements().add(new MoveTo(w, h)); - if (smallSpace) { - path.getElements().add(new LineTo(HAND_X - xValue + w + count * w, HAND_Y - yValue + h)); - } else { - path.getElements().add(new LineTo(HAND_X - xValue + w + count * w * 2 + 5 * count, HAND_Y - yValue + h)); - } + path.getElements().add(new MoveTo(endPointX, h)); + card.toFront(); + path.getElements().add(new LineTo(w, h)); PathTransition pathTransition = new PathTransition(); - pathTransition.setDuration(Duration.millis(600)); + pathTransition.setDuration(Duration.millis(700)); pathTransition.setNode(card); pathTransition.setPath(path); pathTransition.setCycleCount(1); - card.toFront(); pathTransition.play(); setNewCoordinates(card, pathTransition); return true; @@ -216,20 +211,6 @@ public static Boolean addToHand(ImageView card, int count, boolean smallSpace) { return false; } - /** - * Die Karten werden neu angeordnet. - * - * @param cards die Karten auf der Hand - * @param smallSpace gibt an, ob verkleinerte Abstäne benutzt werden sollen - * @author Anna - * @since Sprint5 - */ - public static void refactorHand(List cards, boolean smallSpace) { - for (int i = 0; i < cards.size(); i++) { - addToHand(cards.get(i), i, smallSpace); - } - } - /** * Die Methode setzt die neuen Koordinaten der Karte, nachdem die Bewegung beendet wurde. * diff --git a/Client/src/main/java/de/uol/swp/client/game/GameManagement.java b/Client/src/main/java/de/uol/swp/client/game/GameManagement.java index a70cb259a..f0a9e7317 100644 --- a/Client/src/main/java/de/uol/swp/client/game/GameManagement.java +++ b/Client/src/main/java/de/uol/swp/client/game/GameManagement.java @@ -8,20 +8,24 @@ import de.uol.swp.client.chat.ChatViewPresenter; import de.uol.swp.client.lobby.LobbyPresenter; import de.uol.swp.client.lobby.LobbyService; +import de.uol.swp.client.main.PrimaryPresenter; import de.uol.swp.client.sound.SoundMediaPlayer; import de.uol.swp.common.game.messages.GameOverMessage; import de.uol.swp.common.game.messages.UserGaveUpMessage; -import de.uol.swp.common.lobby.message.KickUserMessage; +import de.uol.swp.common.lobby.message.CreateLobbyMessage; +import de.uol.swp.common.lobby.message.UserLeftAllLobbiesMessage; import de.uol.swp.common.lobby.message.UserLeftLobbyMessage; import de.uol.swp.common.user.User; import de.uol.swp.common.user.UserDTO; import de.uol.swp.common.user.UserService; import de.uol.swp.common.user.message.UpdatedUserMessage; -import de.uol.swp.common.user.message.UserLoggedOutMessage; +import de.uol.swp.common.user.message.UserDroppedMessage; import javafx.application.Platform; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.control.Tab; +import javafx.scene.layout.Pane; import javafx.stage.Stage; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -37,10 +41,11 @@ * @author Keno O. * @since Sprint3 */ +@SuppressWarnings("UnstableApiUsage") public class GameManagement { static final Logger LOG = LogManager.getLogger(GameManagement.class); - static final String styleSheet = "css/swp.css"; + static final String styleSheet = "css/global.css"; private LobbyPresenter lobbyPresenter; private GameViewPresenter gameViewPresenter; @@ -50,14 +55,16 @@ public class GameManagement { private UserDTO gameOwner; private String lobbyName; - private Scene gameScene; - private Scene lobbyScene; + private Pane gamePane; + private Pane lobbyPane; private Scene gameOverScene; + private Tab primaryTab; + private PrimaryPresenter primaryPresenter; + private Injector injector; private EventBus eventBus; - private Stage primaryStage; private Stage gameOverStage; private GameService gameService; @@ -77,40 +84,29 @@ public class GameManagement { * @author Keno O., Darian * @since Sprint3 */ - public GameManagement(EventBus eventBus, UUID id, String lobbyName, User loggedInUser, ChatService chatService, LobbyService lobbyService, UserService userService, Injector injector, UserDTO gameOwner, GameService gameService) { + public GameManagement(EventBus eventBus, UUID id, String lobbyName, User loggedInUser, ChatService chatService, LobbyService lobbyService, UserService userService, Injector injector, UserDTO gameOwner, GameService gameService, PrimaryPresenter primaryPresenter) { this.id = id; this.loggedInUser = loggedInUser; this.injector = injector; - this.primaryStage = new Stage(); + this.primaryTab = new Tab(); this.gameOverStage = new Stage(); this.lobbyName = lobbyName; this.eventBus = eventBus; this.gameOwner = gameOwner; this.gameService = gameService; + this.primaryPresenter = primaryPresenter; this.chatViewPresenter = new ChatViewPresenter(lobbyName, id, loggedInUser, ChatViewPresenter.THEME.Light, chatService, injector, this); - this.gameViewPresenter = new GameViewPresenter(loggedInUser, id, chatService, chatViewPresenter, lobbyService, userService, injector, this); + this.gameViewPresenter = new GameViewPresenter(loggedInUser, id, chatService, chatViewPresenter, lobbyService, userService, injector, this, gameService); this.lobbyPresenter = new LobbyPresenter(loggedInUser, lobbyName, id, chatService, chatViewPresenter, lobbyService, userService, injector, gameOwner, this, eventBus); + this.primaryTab.setId(id.toString()); + eventBus.register(chatViewPresenter); eventBus.register(lobbyPresenter); eventBus.register(gameViewPresenter); } - /** - * Schließt das Fenster, wenn der aktuelle Benutzer diese Lobby verlassen hat - * - * @param msg die UserLeftLobbyMessage - * @author Keno O. - * @since Sprint3 - */ - @Subscribe - private void userLeft(UserLeftLobbyMessage msg) { - if (msg.getLobbyID().equals(id) && msg.getUser().getUsername().equals(loggedInUser.getUsername())) { - close(); - } - } - /** * Methode fängt Servernachricht ab und sofern, die Anfrage des Users erfolgreich war, wird das Gamefenster geschlossen. * @@ -121,39 +117,38 @@ private void userLeft(UserLeftLobbyMessage msg) { @Subscribe private void userGivedUp(UserGaveUpMessage msg) { if (msg.getLobbyID().equals(id) && msg.getUserGivedUp() && msg.getTheUser().equals(loggedInUser)) { - close(); + primaryPresenter.closeTab(msg.getLobbyID(), true); LOG.debug("Game mit folgender ID geschlossen: " + id); } else { // TODO: Fehlerbehandlung später implementieren. + } + } + @Subscribe + private void userLeftLobby(UserLeftLobbyMessage msg) { + if (msg.getUser().getUsername().equals(loggedInUser.getUsername()) && msg.getLobbyID().equals(id)) { + primaryPresenter.closeTab(id, true); } } - /** - * Wenn die Nachricht abgefangen wird und man der gekickte Benutzer ist und in der Lobby ist wird das Lobbyfenster - * geschlossen - * - * @author Darian, Marvin - * @since sprint4 - */ @Subscribe - private void onKickUserMessage(KickUserMessage msg) { - if (msg.getLobbyID().equals(id) && msg.getUser().getUsername().equals(loggedInUser.getUsername())) { - close(); + private void userLeftAllLobbys(UserLeftAllLobbiesMessage msg) { + if (msg.getUser().getUsername().equals(loggedInUser.getUsername())) { + primaryPresenter.closeAllTabs(); + } + } + + @Subscribe + private void userDrppedAccount(UserDroppedMessage msg) { + if (msg.getUser().getUsername().equals(loggedInUser.getUsername())) { + primaryPresenter.closeAllTabs(); } } - /** - * Schließt das Fenster, wenn sich der aktuelle Benutzer ausgeloggt hat - * - * @param msg die UserLoggedOutMessage - * @author Keno O. - * @since Sprint3 - */ @Subscribe - private void userLoggedOut(UserLoggedOutMessage msg) { - if (msg.getUsername().equals(loggedInUser.getUsername())) { - close(); + private void lobbyCreated(CreateLobbyMessage msg) { + if (msg.getUser().getUsername().equals(loggedInUser.getUsername())) { + primaryPresenter.showTab(msg.getChatID()); } } @@ -193,7 +188,7 @@ public void onGameOverMessage(GameOverMessage message) { * @since Sprint3 */ public boolean hasFocus() { - return primaryStage.isFocused(); + return primaryPresenter.getFocusedTab().equals(id.toString()); } /** @@ -204,7 +199,7 @@ public boolean hasFocus() { */ public void showLobbyView() { initLobbyView(); - showScene(lobbyScene, lobbyName); + showView(lobbyPane, lobbyName); } /** @@ -215,7 +210,7 @@ public void showLobbyView() { */ public void showGameView() { initGameView(); - showScene(gameScene, lobbyName); + showView(gamePane, lobbyName); } /** @@ -240,21 +235,10 @@ public void showGameOverView(User loggedInUser, List winners, Map closeGameOverViewAndLeaveLobby()); - primaryStage.close(); }); } } - /** - * Methode zum Schließen der aktuellen Stage - * - * @author Keno O. - * @since Sprint3 - */ - public void close() { - Platform.runLater(() -> primaryStage.close()); - } - /** * Methode zum Schließen der GameOverStage. * @@ -273,20 +257,20 @@ public void closeGameOverView() { */ public void closeGameOverViewAndLeaveLobby() { Platform.runLater(() -> gameOverStage.close()); + primaryPresenter.closeTab(id, true); lobbyPresenter.getLobbyService().leaveLobby(id, new UserDTO(loggedInUser.getUsername(), loggedInUser.getPassword(), loggedInUser.getEMail())); } /** * Initialisieren der GameView * - * @author Keno O. - * @since Sprint3 + * @author Keno O., Fenja + * @since Sprint7 */ private void initGameView() { - if (gameScene == null) { - Parent rootPane = initPresenter(gameViewPresenter, GameViewPresenter.fxml); - gameScene = new Scene(rootPane, 1280, 750); - gameScene.getStylesheets().add(styleSheet); + if (gamePane == null) { + gamePane = initPresenter(gameViewPresenter, GameViewPresenter.fxml); + gamePane.getStylesheets().add(styleSheet); } } @@ -294,14 +278,13 @@ private void initGameView() { * LobbyView wird initalisiert und deklariert. * Neue Szene für die neue Lobby wird erstellt und gespeichert * - * @author Keno O. - * @since Sprint3 + * @author Keno O., Fenja + * @since Sprint7 */ private void initLobbyView() { - if (lobbyScene == null) { - Parent rootPane = initPresenter(lobbyPresenter, LobbyPresenter.fxml); - lobbyScene = new Scene(rootPane, 900, 750); - lobbyScene.getStylesheets().add(styleSheet); + if (lobbyPane == null) { + lobbyPane = initPresenter(lobbyPresenter, LobbyPresenter.fxml); + lobbyPane.getStylesheets().add(styleSheet); } } @@ -317,7 +300,7 @@ private void initLobbyView() { private void initGameOverView(User user, List winners, Map res) { Parent rootPane = initPresenter(new GameOverViewPresenter(this, user, winners, res), GameOverViewPresenter.fxml); gameOverScene = new Scene(rootPane, 420, 280); - lobbyScene.getStylesheets().add(styleSheet); + gameOverScene.getStylesheets().add(styleSheet); } /** @@ -326,11 +309,11 @@ private void initGameOverView(User user, List winners, Map { - primaryStage.setTitle(title); - primaryStage.setScene(scene); - primaryStage.setResizable(false); - //User wird aus der Lobby ausgeloggt, wenn er das Lobbyfenster schließt - primaryStage.setOnCloseRequest(windowEvent -> { - if (primaryStage.getScene().equals(lobbyScene)) { - lobbyPresenter.getLobbyService().leaveLobby(id, new UserDTO(loggedInUser.getUsername(), loggedInUser.getPassword(), loggedInUser.getEMail())); - } - }); - primaryStage.show(); + primaryTab.setText(title); + primaryTab.setContent(pane); new SoundMediaPlayer(SoundMediaPlayer.Sound.Window_Opened, SoundMediaPlayer.Type.Sound).play(); }); } @@ -390,9 +365,28 @@ public UUID getID() { * * @return der LobbyService * @author Anna - * @aince Sprint6 + * @Since Sprint6 */ public LobbyService getLobbyService() { return this.lobbyPresenter.getLobbyService(); } + + + public Tab getPrimaryTab() { + return primaryTab; + } + + /** + * Gets the Lobby Name. + * + * @return the Name + * @author Keno Oelrichs Garcia + * @Version 1.0 + * @since Sprint 4 + */ + + public String getLobbyName() { + return lobbyName; + } + } diff --git a/Client/src/main/java/de/uol/swp/client/game/GameOverViewPresenter.java b/Client/src/main/java/de/uol/swp/client/game/GameOverViewPresenter.java index 1f98be035..51b5a3dfb 100644 --- a/Client/src/main/java/de/uol/swp/client/game/GameOverViewPresenter.java +++ b/Client/src/main/java/de/uol/swp/client/game/GameOverViewPresenter.java @@ -180,7 +180,6 @@ public void onAgainButtonPressed(ActionEvent actionEvent) { @FXML public void onReturnButtonPressed(ActionEvent actionEvent) { LOG.debug("Player " + loggedInUser.getUsername() + " wants to return to the MainMenu."); - gameManagement.close(); gameManagement.closeGameOverViewAndLeaveLobby(); } } diff --git a/Client/src/main/java/de/uol/swp/client/game/GameService.java b/Client/src/main/java/de/uol/swp/client/game/GameService.java index be9456b7d..ace88f110 100644 --- a/Client/src/main/java/de/uol/swp/client/game/GameService.java +++ b/Client/src/main/java/de/uol/swp/client/game/GameService.java @@ -2,7 +2,11 @@ import com.google.common.eventbus.EventBus; import com.google.inject.Inject; +import de.uol.swp.common.game.request.BuyCardRequest; import de.uol.swp.common.game.request.GameGiveUpRequest; +import de.uol.swp.common.game.request.PlayCardRequest; +import de.uol.swp.common.game.request.SkipPhaseRequest; +import de.uol.swp.common.user.User; import de.uol.swp.common.user.UserDTO; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -38,4 +42,28 @@ public void giveUp(UUID lobbyID, UserDTO theUserWhoGivedUp) { GameGiveUpRequest request = new GameGiveUpRequest(theUserWhoGivedUp, lobbyID); bus.post(request); } + + /** + * Erstellt skipPhaseRequest und postet diese auf den EventBus. + * + * @param gameID die LobbyID zum Lobbynamen + * @param user der User der seine Phase skippen möchte + * @author Devin + * @since Sprint5 + */ + public void skipPhase(User user, UUID gameID) { + SkipPhaseRequest req = new SkipPhaseRequest(user, gameID); + bus.post(req); + } + + + public void playCard(UUID gameID, User loggedInUser, Short id) { + PlayCardRequest req = new PlayCardRequest(gameID, loggedInUser, id); + bus.post(req); + } + + public void buyCard(BuyCardRequest req) { + bus.post(req); + } + } diff --git a/Client/src/main/java/de/uol/swp/client/game/GameViewPresenter.java b/Client/src/main/java/de/uol/swp/client/game/GameViewPresenter.java index 39affd636..781f144da 100644 --- a/Client/src/main/java/de/uol/swp/client/game/GameViewPresenter.java +++ b/Client/src/main/java/de/uol/swp/client/game/GameViewPresenter.java @@ -7,41 +7,45 @@ import de.uol.swp.client.chat.ChatViewPresenter; import de.uol.swp.client.lobby.LobbyService; import de.uol.swp.client.main.MainMenuPresenter; -import de.uol.swp.common.game.messages.BuyCardMessage; -import de.uol.swp.common.game.messages.DrawHandMessage; -import de.uol.swp.common.game.messages.PlayCardMessage; +import de.uol.swp.common.game.card.Card; +import de.uol.swp.common.game.card.parser.JsonCardParser; +import de.uol.swp.common.game.card.parser.components.CardPack; +import de.uol.swp.common.game.messages.*; import de.uol.swp.common.game.request.BuyCardRequest; -import de.uol.swp.common.game.request.PlayCardRequest; import de.uol.swp.common.lobby.message.UserJoinedLobbyMessage; import de.uol.swp.common.lobby.response.AllOnlineUsersInLobbyResponse; import de.uol.swp.common.user.User; import de.uol.swp.common.user.UserDTO; import de.uol.swp.common.user.UserService; import de.uol.swp.common.user.message.UpdatedUserMessage; +import javafx.animation.PathTransition; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; +import javafx.event.Event; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; -import javafx.scene.control.Alert; -import javafx.scene.control.Button; -import javafx.scene.control.ButtonType; -import javafx.scene.control.ListView; +import javafx.geometry.Insets; +import javafx.scene.Group; +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.effect.ColorAdjust; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; import javafx.scene.layout.Pane; +import javafx.scene.layout.StackPane; import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.StageStyle; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; +import java.util.*; /** * Der Presenter für die Spielansicht. @@ -54,24 +58,64 @@ public class GameViewPresenter extends AbstractPresenter { /** * Die Konstante fxml. */ - public static final String fxml = "/fxml/GameView.fxml"; + public static final String fxml = "/fxml/GameViewWIP.fxml"; private static final Logger LOG = LogManager.getLogger(MainMenuPresenter.class); - private UUID lobbyID; + private final UUID lobbyID; private User loggedInUser; + // @FXML + // private Pane gameView; + @FXML - private Pane gameView; + private Pane gameViewWIP; @FXML private Pane chatView; @FXML - private ImageView shopTeppich; + private Pane shopTeppich; @FXML private ListView usersView; + @FXML + private StackPane deckPane; + @FXML + private StackPane discardPilePane; + @FXML + private ImageView cardPlaceholder1; + @FXML + private ImageView cardPlaceholder2; + @FXML + private ImageView cardPlaceholder3; + @FXML + private ImageView cardPlaceholder4; + @FXML + private ImageView cardPlaceholder5; + @FXML + private ImageView cardPlaceholder6; + @FXML + private ImageView cardPlaceholder7; + @FXML + private ImageView cardPlaceholder8; + @FXML + private ImageView cardPlaceholder9; + @FXML + private ImageView cardPlaceholder10; + + private final HandcardsLayoutContainer handcards; + private final PlayedCardLayoutContainer playedCardLayoutContainer; private ObservableList users; - private ChatViewPresenter chatViewPresenter; - private Injector injector; - private GameManagement gameManagement; + private final GameService gameService; + private MouseEvent mouseEvent; + private final ChatViewPresenter chatViewPresenter; + private final Injector injector; + private final GameManagement gameManagement; + + private final EventHandler handCardEventHandler = new EventHandler() { + @Override + public void handle(Event event) { + ImageView card = (ImageView) event.getSource(); + playChoosenCard(lobbyID, loggedInUser, card.getImage().getUrl(), Short.valueOf(card.getId()), card, (MouseEvent) event); + } + }; /** * Instantiiert einen neuen GameView Presenter. @@ -85,7 +129,7 @@ public class GameViewPresenter extends AbstractPresenter { * @param injector der Injector * @param gameManagement das Game Management */ - public GameViewPresenter(User loggedInUser, UUID lobbyID, ChatService chatService, ChatViewPresenter chatViewPresenter, LobbyService lobbyService, UserService userService, Injector injector, GameManagement gameManagement) { + public GameViewPresenter(User loggedInUser, UUID lobbyID, ChatService chatService, ChatViewPresenter chatViewPresenter, LobbyService lobbyService, UserService userService, Injector injector, GameManagement gameManagement, GameService gameService) { this.loggedInUser = loggedInUser; this.lobbyID = lobbyID; this.chatService = chatService; @@ -94,9 +138,17 @@ public GameViewPresenter(User loggedInUser, UUID lobbyID, ChatService chatServic this.chatViewPresenter = chatViewPresenter; this.injector = injector; this.gameManagement = gameManagement; + handcards = new HandcardsLayoutContainer(460, 618, 160, 650); + playedCardLayoutContainer = new PlayedCardLayoutContainer(500, 500, 160, 100); + this.gameService = gameService; initializeUserList(); } + /* + showAlert Methode, um Alert Box zu erstellen + */ + + /** * Show Alert für den Aufgeben Button * @@ -137,20 +189,30 @@ public void initialize() throws IOException { chatView.getChildren().add(loader.load()); ((Pane) chatView.getChildren().get(0)).setPrefHeight(chatView.getPrefHeight()); ((Pane) chatView.getChildren().get(0)).setPrefWidth(chatView.getPrefWidth()); - + gameViewWIP.getChildren().add(playedCardLayoutContainer); + gameViewWIP.getChildren().add(handcards); + initalizeCardFieldImages(); } - /** - * Logout Button gedrückt Ereignis. - * - * @param actionEvent das Ereignis der Aktion. - * @author Fenja - * @since Sprint 3 - */ - @FXML - public void onLogoutButtonPressed(ActionEvent actionEvent) { - lobbyService.leaveAllLobbiesOnLogout(new UserDTO(loggedInUser.getUsername(), loggedInUser.getPassword(), loggedInUser.getEMail())); - userService.logout(loggedInUser); + private void initalizeCardFieldImages() { + ArrayList theList = new ArrayList<>(); + CardPack cardsPackField = new JsonCardParser().loadPack("Basispack"); + for (int i = 0; i < 10; i++) { + Card card = cardsPackField.getCards().getActionCards().get(i); + theList.add(card.getId()); + } + ArrayList allImageViews = new ArrayList<>(Arrays.asList(cardPlaceholder1, cardPlaceholder2, cardPlaceholder3, cardPlaceholder4, cardPlaceholder5, cardPlaceholder6, cardPlaceholder7, cardPlaceholder8, cardPlaceholder9, cardPlaceholder10)); + int index = 0; + for (ImageView imageView : allImageViews) { + String theIdInString = String.valueOf(theList.get(index)); + String imageUrl = "/cards/images/" + theIdInString + "_sm.png"; + Image theImage = new Image(imageUrl); + imageView.setImage(theImage); + index++; + } + cardsPackField = null; + theList = null; + allImageViews = null; } @@ -216,7 +278,7 @@ public void updatedUser(UpdatedUserMessage message) { if (loggedInUser.getUsername().equals(message.getOldUser().getUsername())) { loggedInUser = message.getUser(); } - if (users.contains(message.getOldUser().getUsername())) { + if (users != null && users.contains(message.getOldUser().getUsername())) { users.remove(message.getOldUser().getUsername()); users.add(message.getUser().getUsername()); } @@ -244,24 +306,44 @@ public void userList(AllOnlineUsersInLobbyResponse allOnlineUsersInLobbyResponse * Überprüft ob die Spieler noch Karten der gekauften Art kaufen können und fügt ggf. das ImageView (kleines Bild) wieder hinzu * * @param msg die Nachricht - * @author Rike + * @author Rike, Devin, Anna * @since Sprint 5 */ + // TODO: Karte wenn sie gekauft wird, von der richtigen Postition einfliegen lassen. ( Weiter nach rechts) @Subscribe public void onBuyCardMessage(BuyCardMessage msg) { + System.out.println(msg.getCounterCard()); if (msg.getLobbyID().equals(lobbyID) && msg.getCurrentUser().equals(loggedInUser)) { if (msg.isBuyCard()) { - AnimationManagement.buyCard(msg.getCardImage()); + ImageView selectedCard = (ImageView) mouseEvent.getSource(); + String pfad = "file:Client/src/main/resources/cards/images/" + msg.getCardID().toString() + ".png"; + Image picture = new Image(pfad); + ImageView newCardImage = new ImageView(picture); LOG.debug("Der Spieler " + msg.getCurrentUser() + " hat die Karte " + msg.getCardID() + " gekauft."); - if (msg.getCounterCard() > 0) { - // fügt ein "neues" Bild an der Stelle des alten Bildes im Shop hinzu - ImageView newCardImage = msg.getCardImage(); - newCardImage.setFitWidth(msg.getCardImage().getFitWidth()); - newCardImage.setLayoutY(msg.getCardImage().getLayoutY()); - newCardImage.setLayoutX(msg.getCardImage().getLayoutX()); - newCardImage.setId(msg.getCardID()); - newCardImage.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseEvent -> chosenBuyableCard(mouseEvent)); + // fügt ein "neues" Bild an der Stelle des alten Bildes im Shop hinzu + newCardImage.setPreserveRatio(true); + newCardImage.setFitHeight(107); + newCardImage.setFitWidth(Math.round(newCardImage.getBoundsInLocal().getWidth())); + newCardImage.setLayoutX(selectedCard.getLayoutX()); + newCardImage.setLayoutY(selectedCard.getLayoutY()); + newCardImage.setId(String.valueOf(msg.getCardID())); + Platform.runLater(() -> { + gameViewWIP.getChildren().add(newCardImage); + PathTransition pathTransition = AnimationManagement.buyCard(newCardImage); + pathTransition.setOnFinished(actionEvent -> { + gameViewWIP.getChildren().remove(newCardImage); + ImageView iv = new ImageView(picture); + iv.setPreserveRatio(true); + iv.setFitHeight(107); + discardPilePane.getChildren().add(iv); + }); + }); + if (msg.getCounterCard() < 1) { + ColorAdjust makeImageDarker = new ColorAdjust(); + makeImageDarker.setBrightness(-0.7); + selectedCard.setEffect(makeImageDarker); } + playAllMoneyCardsOnHand(); } else { showAlert(Alert.AlertType.WARNING, "Du kannst die Karte nicht kaufen!", "Fehler"); LOG.debug("Der Kauf der Karte " + msg.getCardID() + " von " + msg.getCurrentUser() + " ist fehlgeschlagen"); @@ -273,22 +355,24 @@ public void onBuyCardMessage(BuyCardMessage msg) { * Die Nachricht die angibt ob die Karte gespielt werden konnte * * @param msg die Nachricht - * @author Rike - * @since Sprint 5 + * @author Devin + * @since Sprint 6 */ + @FXML @Subscribe public void onPlayCardMessage(PlayCardMessage msg) { - if (msg.getLobbyID().equals(lobbyID) && msg.getCurrentUser().equals(loggedInUser)) { - if (msg.isPlayCard()) { - if (msg.isSmallSpace()) { - AnimationManagement.refactorHand(msg.getHandCards(), false); - } else { - AnimationManagement.playCard(msg.getCardImage(), msg.getCount()); - if (msg.getHandCards().contains(msg.getCardImage())) { - msg.getHandCards().remove(msg.getCardImage()); - AnimationManagement.refactorHand(msg.getHandCards(), msg.isSmallSpace()); + + ImageView card = (ImageView) mouseEvent.getTarget(); + if (msg.getGameID().equals(lobbyID) && msg.getCurrentUser().equals(loggedInUser)) { + if (msg.getIsPlayed()) { + Platform.runLater(() -> { + if (handcards.getChildren().contains(card)) { + AnimationManagement.playCard(card, playedCardLayoutContainer.getChildren().size()); + handcards.getChildren().remove(card); + playedCardLayoutContainer.getChildren().add(card); + card.removeEventHandler(MouseEvent.MOUSE_CLICKED, handCardEventHandler); } - } + }); } else { showAlert(Alert.AlertType.WARNING, "Du kannst die Karte nicht spielen!", "Fehler"); LOG.debug("Das Spielen der Karte " + msg.getHandCardID() + " von " + msg.getCurrentUser() + " ist fehlgeschlagen"); @@ -297,32 +381,31 @@ public void onPlayCardMessage(PlayCardMessage msg) { } /** - * Die usersView Liste wird geupdatet. - * Äquivalent zu MainMenuPresenter.updateUsersList. + * Fügt die Karte aus der DiscardPileLastCardMessage dem Ablagestapel hinzu. * - * @param userList - * @author Marvin - * @since Sprint3 + * @param msg Die Nachricht + * @author Timo + * @Sprint 6 */ - private void updateUsersList(Set userList) { - // Attention: This must be done on the FX Thread! + @Subscribe + public void onDiscardPileLastCardMessage(DiscardPileLastCardMessage msg) { Platform.runLater(() -> { - if (usersView != null) { - if (users == null) { - users = FXCollections.observableArrayList(); - usersView.setItems(users); - } - users.clear(); - userList.forEach(u -> users.add(u.getUsername())); + if (msg.getGameID().equals(this.gameManagement.getID()) && msg.getUser().equals(this.loggedInUser)) { + String pfad = "file:Client/src/main/resources/cards/images/" + msg.getCardID() + ".png"; + Image picture = new Image(pfad); + ImageView card = new ImageView(picture); + card.setFitHeight(107); + card.setPreserveRatio(true); + card.setFitWidth(Math.round(card.getBoundsInLocal().getWidth())); + discardPilePane.getChildren().add(card); } }); } - /** * Zeigt die Karten auf der Hand in der GameView an * - * @author Devin S. + * @author Devin S., Anna * @since Sprint5 */ @@ -332,28 +415,155 @@ public void ShowNewHand(DrawHandMessage message) { Platform.runLater(() -> { if (lobbyID.equals(message.getTheLobbyID())) { ArrayList HandCardID = message.getCardsOnHand(); - ArrayList HandCards = new ArrayList<>(); HandCardID.forEach((n) -> { String pfad = "file:Client/src/main/resources/cards/images/" + n + ".png"; Image picture = new Image(pfad); ImageView card = new ImageView(picture); card.setFitHeight(107); - card.setLayoutY(603); - card.setLayoutX(171); card.setPreserveRatio(true); + card.setId(n.toString()); card.setFitWidth(Math.round(card.getBoundsInLocal().getWidth())); - gameView.getChildren().add(card); - HandCards.add(card); - AnimationManagement.addToHand(card, HandCards.size() - 1, false); - card.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> { - PlayCardRequest request = new PlayCardRequest(lobbyID, loggedInUser, HandCardID.get(n), card, HandCards, false); - eventBus.post(request); - }); + deckPane.getChildren().add(card); + AnimationManagement.addToHand(card, handcards.getChildren().size()); + deckPane.getChildren().remove(card); + handcards.getChildren().add(card); + card.addEventHandler(MouseEvent.MOUSE_CLICKED, handCardEventHandler); }); } }); } + /** + * Hier wird die GameExceptionMessage abgefangen und die Nachricht in einem neuem Fenster angezeigt + * + * @param msg die Nachricht + * @author Anna + * @since Sprint 7 + */ + @Subscribe + public void onGameExceptionMessage(GameExceptionMessage msg) { + if (msg.getGameID().equals(lobbyID)) { + Platform.runLater(() -> { + Alert alert = new Alert(Alert.AlertType.ERROR, msg.getMessage()); + DialogPane root = alert.getDialogPane(); + Stage dialogStage = new Stage(StageStyle.UTILITY); + for (ButtonType buttonType : root.getButtonTypes()) { + ButtonBase button = (ButtonBase) root.lookupButton(buttonType); + button.setOnAction(evt -> { + dialogStage.close(); + }); + } + root.getScene().setRoot(new Group()); + root.setPadding(new Insets(10, 0, 10, 0)); + Scene scene = new Scene(root); + dialogStage.setScene(scene); + dialogStage.initModality(Modality.APPLICATION_MODAL); + dialogStage.setResizable(false); + dialogStage.showAndWait(); + }); + } + } + + /** + * Die usersView Liste wird geupdatet. + * Äquivalent zu MainMenuPresenter.updateUsersList. + * + * @param userList + * @author Marvin + * @since Sprint3 + */ + private void updateUsersList(Set userList) { + // Attention: This must be done on the FX Thread! + Platform.runLater(() -> { + if (usersView != null) { + if (users == null) { + users = FXCollections.observableArrayList(); + usersView.setItems(users); + } + users.clear(); + userList.forEach(u -> users.add(u.getUsername())); + } + }); + } + + /** + * Skips die aktuelle Phase des Spielers zur nächsten. + * + * @author Devin S. + * @since Sprint6 + */ + @FXML + public void onSkipPhaseButtonPressed(ActionEvent actionEvent) { + gameManagement.getGameService().skipPhase(loggedInUser, lobbyID); + } + + /** + * Methode, die beim anklicken einer Handkarte ausgeführt wird. + * + * @param gameID Die ID des Spiels + * @param loggedInUser der User der gerade eingelogt im Spiel ist und die Karte ausgewählt hat. + * @param pfad Der Pfad zum entsprechendem Vollbild + * @param id Die ID der Karte + * @param card Die ImageView der ausgewählten Karte + * @param e Das MouseEvent, das zum anlicken der Karte zuständig ist. + * @author Devin + * @since Sprint 6 + */ + + private void playChoosenCard(UUID gameID, User loggedInUser, String pfad, Short id, ImageView card, MouseEvent e) { + ImageView bigCardImage = new ImageView(new Image(pfad)); + bigCardImage.setFitHeight(225.0); + bigCardImage.setFitWidth(150.0); + bigCardImage.toFront(); + bigCardImage.setLayoutX(425.0); + bigCardImage.setLayoutY(155.0); + gameViewWIP.getChildren().add(bigCardImage); + if (id > 6) { + Button play = new Button("auspielen"); + Button back = new Button("zurück"); + play.setLayoutX(432.0); + play.setLayoutY(385.0); + back.setLayoutX(516.0); + back.setLayoutY(385.0); + back.setMinWidth(52.0); + gameViewWIP.getChildren().add(play); + gameViewWIP.getChildren().add(back); + + play.setOnAction(event -> { + gameViewWIP.getChildren().remove(play); + gameViewWIP.getChildren().remove(back); + gameViewWIP.getChildren().remove(bigCardImage); + for (Node a : handcards.getChildren()) { + ImageView b = (ImageView) a; + if (b.equals(card)) { + mouseEvent = e; + gameManagement.getGameService().playCard(gameID, loggedInUser, id); + } + } + }); + // Aktion hinter dem Zurück Button -> Buttons und das große Bild werden entfernt + back.setOnAction(event -> { + gameViewWIP.getChildren().remove(play); + gameViewWIP.getChildren().remove(back); + gameViewWIP.getChildren().remove(bigCardImage); + }); + } else { + Button back = new Button("zurück"); + + back.setLayoutX(516.0); + back.setLayoutY(385.0); + back.setMinWidth(52.0); + gameViewWIP.getChildren().add(back); + + // Aktion hinter dem Zurück Button -> Buttons und das große Bild werden entfernt + back.setOnAction(event -> { + gameViewWIP.getChildren().remove(back); + gameViewWIP.getChildren().remove(bigCardImage); + }); + } + + } + /** * Hilfsmethode für onBuyableCardClicked() und onBuyCardMessage() * Großes Bild der Karte wird angezeigt. @@ -368,49 +578,71 @@ public void ShowNewHand(DrawHandMessage message) { private void chosenBuyableCard(MouseEvent mouseEvent) { double mouseX = mouseEvent.getSceneX(); double mouseY = mouseEvent.getSceneY(); + ImageView cardImage = (ImageView) mouseEvent.getSource(); // Überprüdung ob sich die angeklickte Karte innerhalb des Shops befindet und nicht bereits auf dem Ablagestapel - if (mouseX > shopTeppich.getLayoutX() && mouseX < (shopTeppich.getLayoutX() + shopTeppich.getFitWidth()) && - mouseY > shopTeppich.getLayoutY() && mouseY < (shopTeppich.getLayoutY() + shopTeppich.getFitHeight())) { - // Karte befindet sich im Shop - ImageView cardImage = (ImageView) mouseEvent.getSource(); - String cardID = cardImage.getId(); - String PathCardLargeView = "/cards/images/" + cardID + ".png"; - // ein großes Bild der Karte wird hinzugefügt - ImageView bigCardImage = new ImageView(new Image(new File(getClass().getResource(PathCardLargeView).toExternalForm().replace("file:", "")).toURI().toString())); - // setzt die Größe und die Position des Bildes. Das Bild ist im Vordergrund. Bild wird hinzugefügt - bigCardImage.setFitHeight(225.0); - bigCardImage.setFitWidth(150.0); - bigCardImage.toFront(); - bigCardImage.setLayoutX(425.0); - bigCardImage.setLayoutY(155.0); - gameView.getChildren().add(bigCardImage); - // es werden zwei Buttons hinzugefügt (zurück und kaufen) - Button buy = new Button("kaufen"); - Button back = new Button("zurück"); - gameView.getChildren().add(buy); - gameView.getChildren().add(back); - // Position der Buttons wird gesetzt - buy.setLayoutX(432.0); - buy.setLayoutY(385.0); - back.setLayoutX(516.0); - back.setLayoutY(385.0); - back.setMinWidth(52.0); - // Aktion hinter dem Kauf-Button - buy.setOnAction(event -> { - buy.setVisible(false); - back.setVisible(false); - bigCardImage.setVisible(false); - BuyCardRequest request = new BuyCardRequest(lobbyID, loggedInUser, cardID, cardImage); - eventBus.post(request); - }); - // Aktion hinter dem Zurück Button -> Buttons und das große Bild werden entfernt - back.setOnAction(event -> { - buy.setVisible(false); - back.setVisible(false); - bigCardImage.setVisible(false); - }); - } - + // if (mouseX > shopTeppich.getLayoutX() && mouseX < (shopTeppich.getLayoutX() + shopTeppich.getWidth()) && + // mouseY > shopTeppich.getLayoutY() && mouseY < (shopTeppich.getLayoutY() + shopTeppich.getHeight()) && cardImage.getEffect() == null) { + // Karte befindet sich im Shop + String cardID3 = cardImage.getImage().getUrl(); + String cardID2 = cardID3.replace("_sm.png", ""); + String cardID = cardID2.substring(cardID2.length() - 1); + String PathCardLargeView = "file:Client/src/main/resources/cards/images/" + cardID + ".png"; + // ein großes Bild der Karte wird hinzugefügt + ImageView bigCardImage = new ImageView(new Image(PathCardLargeView)); + // setzt die Größe und die Position des Bildes. Das Bild ist im Vordergrund. Bild wird hinzugefügt + bigCardImage.setFitHeight(240.0); + bigCardImage.setFitWidth(150.0); + bigCardImage.toFront(); + bigCardImage.setLayoutX(325.0); + bigCardImage.setLayoutY(20.0); + gameViewWIP.getChildren().add(bigCardImage); + // es werden zwei Buttons hinzugefügt (zurück und kaufen) + Button buy = new Button("kaufen"); + Button back = new Button("zurück"); + gameViewWIP.getChildren().add(buy); + gameViewWIP.getChildren().add(back); + // Position der Buttons wird gesetzt + buy.setLayoutX(325.0); + buy.setLayoutY(255.0); + buy.setMinWidth(70.0); + back.setLayoutX(405.0); + back.setLayoutY(255.0); + back.setMinWidth(70.0); + // Aktion hinter dem Kauf-Button + buy.setOnAction(event -> { + buy.setVisible(false); + back.setVisible(false); + bigCardImage.setVisible(false); + BuyCardRequest req = new BuyCardRequest(lobbyID, loggedInUser, Short.valueOf(cardID)); + gameService.buyCard(req); + this.mouseEvent = mouseEvent; + }); + // Aktion hinter dem Zurück Button -> Buttons und das große Bild werden entfernt + back.setOnAction(event -> { + buy.setVisible(false); + back.setVisible(false); + bigCardImage.setVisible(false); + }); } -} +//} + + /** + * Hier werden alle Geldkarten, die sich auf der Hand befinden, ausgespielt + * + * @author Anna + * @since Sprint 7 + */ + public void playAllMoneyCardsOnHand() { + for (Node c : handcards.getChildren()) { + ImageView card = (ImageView) c; + if (card.getId().equals("1") || card.getId().equals("2") || card.getId().equals("3")) { + Platform.runLater(() -> { + AnimationManagement.playCard(card, playedCardLayoutContainer.getChildren().size()); + handcards.getChildren().remove(c); + playedCardLayoutContainer.getChildren().add(card); + }); + } + } + } +} \ No newline at end of file diff --git a/Client/src/main/java/de/uol/swp/client/game/HandcardsLayoutContainer.java b/Client/src/main/java/de/uol/swp/client/game/HandcardsLayoutContainer.java new file mode 100644 index 000000000..ff41ebfce --- /dev/null +++ b/Client/src/main/java/de/uol/swp/client/game/HandcardsLayoutContainer.java @@ -0,0 +1,88 @@ +package de.uol.swp.client.game; + + +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.layout.Region; + +/** + * Layoutcontainer für die Karten auf der Hand. + * + * @author Anna + * @since Sprint6 + */ +public class HandcardsLayoutContainer extends Region { + + /** + * Instantiiert einen neuen HandcardsLayoutContainer. + * + * @author Anna + * @since Sprint6 + */ + public HandcardsLayoutContainer() { + } + + /** + * Instantiiert einen neuen HandcardsLayoutContainer. + * + * @param layoutX x-Koordinate + * @param layoutY y-Koordinate + * @param height Höhe + * @param width Breite + * @author Anna + * @since Sprint6 + */ + public HandcardsLayoutContainer(double layoutX, double layoutY, double height, double width) { + this.setLayoutX(layoutX); + this.setLayoutY(layoutY); + this.setPrefHeight(height); + this.setPrefWidth(width); + } + + /** + * Hier wird festgelegt, wie sich die Kinder anordnen sollen. + * Wenn die Pane breit genug ordnen sie sich, von der Mitte ausgehend, direkt nebeneinander an. + * Ansonsten überlappen sie sich, aber immer nur so viel wie nötig. + * + * @author Anna + * @since Sprint6 + */ + @Override + protected void layoutChildren() { + ObservableList children = getChildren(); + double sum = 0; + double size = children.size(); + for (Node child : children) { + sum += Math.round(child.getBoundsInLocal().getWidth()); + } + double diff = this.getWidth() - sum; + if (diff > 0) { + double counter = size; + double width = sum / size; + for (Node child : children) { + child.relocate(this.getWidth() / 2 + width * (size / 2) - width * counter, 0); + counter--; + } + } else { + double change = (-diff) / (size - 1); + int i = 0; + for (Node child : children) { + child.relocate(i, 0); + i += Math.round(child.getBoundsInLocal().getWidth() - change); + } + } + } + + /** + * Getter für fie Liste der Kinderknoten + * + * @return Kinder + * @author Anna + * @since Sprint6 + */ + @Override + public ObservableList getChildren() { + return super.getChildren(); + } +} + diff --git a/Client/src/main/java/de/uol/swp/client/game/PlayedCardLayoutContainer.java b/Client/src/main/java/de/uol/swp/client/game/PlayedCardLayoutContainer.java new file mode 100644 index 000000000..284936f70 --- /dev/null +++ b/Client/src/main/java/de/uol/swp/client/game/PlayedCardLayoutContainer.java @@ -0,0 +1,89 @@ +package de.uol.swp.client.game; + +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.layout.Region; + +/** + * Layoutcontainer für die Karten, die von der Hand ausgespielt worden sind. + * + * @author Devin + * @since Sprint6 + */ + +public class PlayedCardLayoutContainer extends Region { + + /** + * Instantiiert einen neuen PlayedCardLayoutContainer. + * + * @author Anna + * @since Sprint6 + */ + public PlayedCardLayoutContainer() { + } + + /** + * Instantiiert einen neuen PlayedCardLayoutContainer. + * + * @param layoutX x-Koordinate + * @param layoutY y-Koordinate + * @param height Höhe + * @param width Breite + * @author Devin + * @since Sprint6 + */ + public PlayedCardLayoutContainer(double layoutX, double layoutY, double height, double width) { + this.setLayoutX(layoutX); + this.setLayoutY(layoutY); + this.setPrefHeight(height); + this.setPrefWidth(width); + } + + /** + * Hier wird festgelegt, wie sich die Kinder anordnen sollen. + * Wenn die Pane breit genug ordnen sie sich, von der Mitte ausgehend, direkt nebeneinander an. + * Ansonsten überlappen sie sich, aber immer nur so viel wie nötig. + * + * @author Devin + * @since Sprint6 + */ + @Override + protected void layoutChildren() { + ObservableList children = getChildren(); + double sum = 0; + double size = children.size(); + for (Node child : children) { + sum += Math.round(child.getBoundsInLocal().getWidth()); + } + double diff = this.getWidth() - sum; + if (diff > 0) { + double counter = size; + double width = sum / size; + for (Node child : children) { + child.relocate(this.getWidth() / 2 + width * (size / 2) - width * counter, 0); + counter--; + } + } else { + double change = (-diff) / (size - 1); + int i = 0; + for (Node child : children) { + child.relocate(i, 0); + i += Math.round(child.getBoundsInLocal().getWidth() - change); + } + } + } + + /** + * Getter für fie Liste der Kinderknoten + * + * @return Kinder + * @author Devin + * @since Sprint6 + */ + @Override + public ObservableList getChildren() { + return super.getChildren(); + } + +} + diff --git a/Client/src/main/java/de/uol/swp/client/lobby/LobbyPresenter.java b/Client/src/main/java/de/uol/swp/client/lobby/LobbyPresenter.java index 2392a6cbd..29fcf37cf 100644 --- a/Client/src/main/java/de/uol/swp/client/lobby/LobbyPresenter.java +++ b/Client/src/main/java/de/uol/swp/client/lobby/LobbyPresenter.java @@ -15,7 +15,6 @@ import de.uol.swp.common.user.message.UpdatedUserMessage; import de.uol.swp.common.user.message.UserDroppedMessage; import de.uol.swp.common.user.message.UserLoggedOutMessage; -import de.uol.swp.common.user.request.OpenSettingsRequest; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -45,7 +44,7 @@ public class LobbyPresenter extends AbstractPresenter { - public static final String fxml = "/fxml/LobbyView.fxml"; + public static final String fxml = "/fxml/LobbyViewWIP.fxml"; private static final Logger LOG = LogManager.getLogger(ChatViewPresenter.class); @FXML ChoiceBox chooseMaxPlayer; @@ -65,6 +64,7 @@ public class LobbyPresenter extends AbstractPresenter { private Pane chatView; @FXML private Button readyButton; + private ObservableList userHBoxes; private GameManagement gameManagement; @@ -115,19 +115,6 @@ public void onLeaveLobbyButtonPressed(ActionEvent event) { lobbyService.leaveLobby(lobbyID, loggedInUserDTO); } - /** - * Die Methode postet ein Request auf den Bus, wenn der Einstellungen-Button gedrückt wird. - * - * @param actionEvent - * @author Anna - * @since Sprint4 - */ - @FXML - public void onSettingsButtonPressed(ActionEvent actionEvent) { - OpenSettingsRequest request = new OpenSettingsRequest(loggedInUser); - eventBus.post(request); - } - /** * Intitialisieren des Chats - FXML laden, Controller setzen (muss immer eine eigene Instanz sein) * und chatView ind die chatView-Pane dieses Controllers laden. @@ -154,35 +141,19 @@ public void initialize() throws IOException { chooseMaxPlayer.setValue(4); } - +/* /** * Wird aufgerufen wenn der Logout-Button gedrückt wird. * * @param actionEvent * @author Keno S, Keno O. * @since Sprint3 - */ + @FXML public void onLogoutButtonPressed(ActionEvent actionEvent) { lobbyService.leaveAllLobbiesOnLogout(loggedInUserDTO); userService.logout(loggedInUser); - } - - /** - * Wird aufgerufen wenn der Spielanleitung-Button gedrückt wird. - * - * @param actionEvent - * @author Keno S, Keno O., Timo - * @since Sprint3 - */ - @FXML - public void onInstructionsButtonPressed(ActionEvent actionEvent) { - try { - this.lobbyService.startWebView(); - } catch (Exception e1) { - e1.printStackTrace(); - } - } + } */ /** * Wird aufgerufen wenn der Bereit-Button gedrückt wird. diff --git a/Client/src/main/java/de/uol/swp/client/lobby/LobbyService.java b/Client/src/main/java/de/uol/swp/client/lobby/LobbyService.java index ac36d82e3..45351b4b2 100644 --- a/Client/src/main/java/de/uol/swp/client/lobby/LobbyService.java +++ b/Client/src/main/java/de/uol/swp/client/lobby/LobbyService.java @@ -73,19 +73,6 @@ public void leaveLobby(UUID lobbyID, UserDTO user) { bus.post(request); } - /** - * Erstellt eine LeaveAllLobbiesOnLogoutRequest und postet diese auf den EventBus. - * - * @param user der User der alle Lobbys verlassen will - * @author Julia, Paula - * @since Sprint3 - */ - - public void leaveAllLobbiesOnLogout(UserDTO user) { - LeaveAllLobbiesOnLogoutRequest request = new LeaveAllLobbiesOnLogoutRequest(user); - bus.post(request); - } - /** * Erstellt ein RetrieveAllOnlineLobbiesRequest und postet diese auf den Eventbus. * diff --git a/Client/src/main/java/de/uol/swp/client/main/MainMenuPresenter.java b/Client/src/main/java/de/uol/swp/client/main/MainMenuPresenter.java index 83fd90211..ccbf5befe 100644 --- a/Client/src/main/java/de/uol/swp/client/main/MainMenuPresenter.java +++ b/Client/src/main/java/de/uol/swp/client/main/MainMenuPresenter.java @@ -16,7 +16,6 @@ import de.uol.swp.common.user.message.UserDroppedMessage; import de.uol.swp.common.user.message.UserLoggedInMessage; import de.uol.swp.common.user.message.UserLoggedOutMessage; -import de.uol.swp.common.user.request.OpenSettingsRequest; import de.uol.swp.common.user.response.AllOnlineUsersResponse; import de.uol.swp.common.user.response.LoginSuccessfulResponse; import javafx.application.Platform; @@ -28,8 +27,6 @@ import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.control.*; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; import javafx.scene.layout.Pane; import javafx.scene.paint.Paint; import javafx.scene.shape.Circle; @@ -39,7 +36,6 @@ import javax.swing.*; import java.awt.event.ActionListener; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -76,9 +72,7 @@ public class MainMenuPresenter extends AbstractPresenter { @FXML private Pane chatView; @FXML - private Button createLobbyButton, logoutButton; - @FXML - private ImageView soundIcon; + private Button createLobbyButton; //-------------------------------------- @@ -133,12 +127,6 @@ public void initialize() throws IOException { joinLobby.setPrefWidth(85); createLobbyButton.setOnMouseEntered(event -> new SoundMediaPlayer(SoundMediaPlayer.Sound.Button_Hover, SoundMediaPlayer.Type.Sound).play()); - logoutButton.setOnMouseEntered(event -> new SoundMediaPlayer(SoundMediaPlayer.Sound.Button_Hover, SoundMediaPlayer.Type.Sound).play()); - - soundIcon.setOnMouseClicked(event -> { - SoundMediaPlayer.setSound(!SoundMediaPlayer.isSoundEnabled()); - soundIcon.setImage(new Image(new File(getClass().getResource(SoundMediaPlayer.isSoundEnabled() ? "/images/sound_on_icon.png" : "/images/sound_off_icon.png").toExternalForm().replace("file:", "")).toURI().toString())); - }); } /** @@ -235,36 +223,6 @@ else if (Pattern.matches("([a-zA-Z]|[0-9])+(([a-zA-Z]|[0-9])+([a-zA-Z]|[0-9]| )* createLobbyDialoge.setVisible(true); } - - /** - * Die Methode postet ein Request auf den Bus, wenn der Einstellungen-Button gedrückt wird - * - * @param actionEvent das ActionEvent - * @author Anna - * @since Sprint4 - */ - @FXML - public void onSettingsButtonPressed(ActionEvent actionEvent) { - OpenSettingsRequest request = new OpenSettingsRequest(loggedInUser); - eventBus.post(request); - } - - /** - * Drückt man auf den LogoutButton, wird der User aus allen Lobbys, in denen er angemeldet ist, entfernt - * Zudem wird der User ausgeloggt. - * - * @param actionEvent das ActionEvent - * @author Julia, Paula - * @since Sprint3 - */ - @FXML - public void onLogoutButtonPressed(ActionEvent actionEvent) { - new SoundMediaPlayer(SoundMediaPlayer.Sound.Button_Pressed, SoundMediaPlayer.Type.Sound).play(); - lobbyService.leaveAllLobbiesOnLogout(new UserDTO(loggedInUser.getUsername(), loggedInUser.getPassword(), loggedInUser.getEMail())); - userService.logout(loggedInUser); - } - - //-------------------------------------- // EVENTBUS //-------------------------------------- diff --git a/Client/src/main/java/de/uol/swp/client/main/PrimaryPresenter.java b/Client/src/main/java/de/uol/swp/client/main/PrimaryPresenter.java new file mode 100644 index 000000000..ecc93af5f --- /dev/null +++ b/Client/src/main/java/de/uol/swp/client/main/PrimaryPresenter.java @@ -0,0 +1,306 @@ +package de.uol.swp.client.main; + +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; +import com.google.inject.Injector; +import de.uol.swp.client.AbstractPresenter; +import de.uol.swp.client.chat.ChatService; +import de.uol.swp.client.game.GameManagement; +import de.uol.swp.client.game.GameService; +import de.uol.swp.client.lobby.LobbyService; +import de.uol.swp.client.user.UserService; +import de.uol.swp.common.lobby.message.KickUserMessage; +import de.uol.swp.common.lobby.message.UserLeftLobbyMessage; +import de.uol.swp.common.user.User; +import de.uol.swp.common.user.UserDTO; +import de.uol.swp.common.user.message.UserDroppedMessage; +import de.uol.swp.common.user.message.UserLoggedOutMessage; +import de.uol.swp.common.user.request.OpenSettingsRequest; +import de.uol.swp.common.user.response.LoginSuccessfulResponse; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.Scene; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +@SuppressWarnings("UnstableApiUsage") +public class PrimaryPresenter extends AbstractPresenter { + + /** + * The constant fxml. + */ + public static final String fxml = "/fxml/PrimaryView.fxml"; + /** + * The constant css. + */ + public static final String css = "css/PrimaryPresenter.css"; + + private final Logger LOG = LogManager.getLogger(PrimaryPresenter.class); + + + private Scene mainScene; + private Map games = new HashMap<>(); + private Injector injector = null; + private ChatService chatService; + private LobbyService lobbyService; + private GameService gameService; + + @FXML + private TabPane TabView; + + + /** + * Setting the Injector + * + * @param eventBus the event bus + * @param loggedInUser the logged in user + * @param chatService the chat service + * @param lobbyService the lobby service + * @param userService the user service + * @param injector the injector + * @author Fenja Oelrichs Garcia + * @Version 1.0 + * @since Sprint 4 + */ + public void initialise(EventBus eventBus, User loggedInUser, ChatService chatService, LobbyService lobbyService, UserService userService, Injector injector, GameService gameService) { + this.loggedInUser = loggedInUser; + this.injector = injector; + this.eventBus = eventBus; + this.chatService = chatService; + this.lobbyService = lobbyService; + this.userService = userService; + this.gameService = gameService; + + } + + /** + * Login war erfolgreich. Der User tritt dem globalen Chat bei. Lobbys werden aktualisiert + * + * @param message Die Nachricht + * @author Marco + * @since Start + */ + @Subscribe + public void loginSuccessful(LoginSuccessfulResponse message) { + loggedInUser = message.getUser(); + } + + private void userDroppedAccount(UserDroppedMessage msg) { + if (loggedInUser.equals(msg.getUser().getUsername())) { + closeAllTabs(); + } + } + + public void addTab(Tab tab) { + TabView.getTabs().add(tab); + } + + public void showTab(UUID id) { + TabView.getTabs().forEach(t -> { + if (t.getId().equals(id.toString())) { + TabView.getSelectionModel().select(t); + } + }); + } + + /** + * Methode fängt ButtonKlick ab, User verlässt alle Lobbies, in denen er angemeldet ist und wird ausgeloggt + * + * @param actionEvent the action event + * @author Julia, Paula + * @Version 1.0 + * @since sprint3 + */ + @FXML + public void onLogoutButtonPressed(ActionEvent actionEvent) { + userService.logout(loggedInUser); + } + + public String getFocusedTab() { + return TabView.getSelectionModel().getSelectedItem().getId(); + } + + private void removeTab(UUID id) { + TabView.getTabs().forEach(t -> { + if (t.getId().equals(id.toString())) { + Platform.runLater(() -> TabView.getTabs().remove(t)); + + } + }); + } + + /** + * On instructions button pressed. + * + * @param actionEvent the action event + * @author Keno Oelrichs Garcia + * @Version 1.0 + * @since + */ + @FXML + public void onInstructionsButtonPressed(ActionEvent actionEvent) { + try { + this.lobbyService.startWebView(); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + + /** + * Schließt das Fenster, wenn der aktuelle Benutzer diese Lobby verlassen hat + * + * @param msg die UserLeftLobbyMessage + * @author Keno O. + * @since Sprint3 + */ + @Subscribe + private void userLeft(UserLeftLobbyMessage msg) { + if (games.containsKey(msg.getLobbyID()) && msg.getUser().getUsername().equals(loggedInUser.getUsername())) { + closeTab(msg.getLobbyID(), true); + } + } + + + /** + * Die Methode postet ein Request auf den Bus, wenn der Einstellungen-Button gedrückt wird + * + * @param actionEvent das ActionEvent + * @author Anna + * @since Sprint4 + */ + @FXML + public void onSettingsButtonPressed(ActionEvent actionEvent) { + OpenSettingsRequest request = new OpenSettingsRequest(loggedInUser); + eventBus.post(request); + } + + /** + * Es wird eine neue Stage mit der lobbyScene angezeigt und mit dem Attribut geöffnet. + * + * @param currentUser the current user + * @param title der Übergebene Titel aus dem MainMenuPresenter + * @param lobbyID die übergebene LobbyID aus der empfangenen Message in der ClientApp + * @author Paula, Haschem, Ferit, Anna + * @Version 1.0 + * @version 0.2 + * @since Sprint3 + */ + public void createLobby(User currentUser, String title, UUID lobbyID, UserDTO gameOwner) { + Platform.runLater(() -> { + //LobbyPresenter neue Instanz mit (name, id) wird erstellt + GameManagement gameManagement = new GameManagement(eventBus, lobbyID, title, currentUser, chatService, lobbyService, userService, injector, gameOwner, gameService, this); + + eventBus.register(gameManagement); + + //LobbyPresenter und lobbyStage in die jeweilige Map packen, mit lobbyID als Schlüssel + games.put(lobbyID, gameManagement); + gameManagement.showLobbyView(); + + //Neuen Tab initialisieren, Pane vom GameManagement übernehmen und der TabView hinzufügen + + //Auf schließung des Tabs reagieren + gameManagement.getPrimaryTab().setOnCloseRequest(event -> { + games.remove(gameManagement); + lobbyService.leaveLobby(gameManagement.getID(), (UserDTO) loggedInUser); + TabView.getTabs().remove(gameManagement.getPrimaryTab()); + lobbyService.retrieveAllLobbies(); + }); + TabView.getTabs().add(gameManagement.getPrimaryTab()); + }); + + } + + @Subscribe + private void onUserLeftLobby(UserLeftLobbyMessage msg) { + if (games.containsKey(msg.getLobbyID()) && loggedInUser.getUsername().equals(msg.getUser().getUsername())) { + closeTab(msg.getLobbyID(), false); + LOG.info("User " + msg.getUser().getUsername() + " left lobby successfully"); + } + } + + /** + * Sort dafür, das die Lobby CLientseitig geschlossen wird und diese ggf. verlassen wird + * + * @param uuid Die UUID der Lobby + * @param leave Ob die Lobby Serverseitig noch verlassen werden muss + */ + public void closeTab(UUID uuid, boolean leave) { + if (games.containsKey(uuid)) { + removeTab(uuid); + if (leave) + lobbyService.leaveLobby(games.get(uuid).getID(), (UserDTO) loggedInUser); + games.remove(uuid); + } + } + + /** + * Gibt das zur übergebenen lobbyID gehörige GameManagement zurück + * + * @param lobbyID the lobby id + * @return GameManagement game management + * @author Julia, Paula + * @since Sprint3 + */ + public GameManagement getGameManagement(UUID lobbyID) { + GameManagement gameManagement; + try { + gameManagement = games.get(lobbyID); + } catch (NullPointerException e) { + gameManagement = null; + } + return gameManagement; + } + + /** + * Wenn die Nachricht abgefangen wird und man der gekickte Benutzer ist und in der Lobby ist wird das Lobbyfenster + * geschlossen + * + * @author Darian, Marvin + * @since sprint4 + */ + @Subscribe + private void onKickUserMessage(KickUserMessage msg) { + if (games.containsKey(msg.getLobbyID()) && msg.getUser().getUsername().equals(loggedInUser.getUsername())) { + closeTab(msg.getLobbyID(), true); + } + } + + /** + * Schließt das Fenster, wenn sich der aktuelle Benutzer ausgeloggt hat + * + * @param msg die UserLoggedOutMessage + * @author Keno O. + * @since Sprint3 + */ + @Subscribe + private void userLoggedOut(UserLoggedOutMessage msg) { + if (msg.getUsername().equals(loggedInUser.getUsername())) { + closeAllTabs(); + } + } + + /** + * Schließt alle GameManagement Stages + * + * @author Julia, Paula + * @Version 1.0 + * @since Sprint3 + */ + public void closeAllTabs() { + Platform.runLater(() -> games.values().forEach(e -> { + try { + closeTab(e.getID(), true); + } catch (ConcurrentModificationException ignored) { + } + })); + } + +} diff --git a/Client/src/main/java/de/uol/swp/client/settings/DeleteAccountPresenter.java b/Client/src/main/java/de/uol/swp/client/settings/DeleteAccountPresenter.java index bb22328be..b4b68a216 100644 --- a/Client/src/main/java/de/uol/swp/client/settings/DeleteAccountPresenter.java +++ b/Client/src/main/java/de/uol/swp/client/settings/DeleteAccountPresenter.java @@ -4,7 +4,6 @@ import de.uol.swp.client.lobby.LobbyService; import de.uol.swp.client.settings.event.CloseDeleteAccountEvent; import de.uol.swp.common.user.User; -import de.uol.swp.common.user.UserDTO; import de.uol.swp.common.user.UserService; import javafx.event.ActionEvent; import javafx.fxml.FXML; @@ -63,7 +62,6 @@ public DeleteAccountPresenter(User loggedInUser, LobbyService lobbyService, User @FXML public void onYesButtonPressed(ActionEvent actionEvent) { LOG.debug("Der Benutzer " + loggedInUser.getUsername() + " löscht seinen Account!"); - lobbyService.leaveAllLobbiesOnLogout((UserDTO) loggedInUser); userService.dropUser(loggedInUser); } diff --git a/Client/src/main/resources/cards/circle_profil.png b/Client/src/main/resources/cards/circle_profil.png new file mode 100644 index 000000000..2c7d85836 Binary files /dev/null and b/Client/src/main/resources/cards/circle_profil.png differ diff --git a/Client/src/main/resources/cards/images/card_back.png b/Client/src/main/resources/cards/images/card_back.png new file mode 100644 index 000000000..c026a7e89 Binary files /dev/null and b/Client/src/main/resources/cards/images/card_back.png differ diff --git a/Client/src/main/resources/css/PrimaryPresenter.css b/Client/src/main/resources/css/PrimaryPresenter.css new file mode 100644 index 000000000..e69de29bb diff --git a/Client/src/main/resources/fxml/ChatView.fxml b/Client/src/main/resources/fxml/ChatView.fxml index 79fccff82..e352ecbc7 100644 --- a/Client/src/main/resources/fxml/ChatView.fxml +++ b/Client/src/main/resources/fxml/ChatView.fxml @@ -1,43 +1,32 @@ - - - - - + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Client/src/main/resources/fxml/MainMenuView.fxml b/Client/src/main/resources/fxml/MainMenuView.fxml index c4386a05c..e0282783e 100644 --- a/Client/src/main/resources/fxml/MainMenuView.fxml +++ b/Client/src/main/resources/fxml/MainMenuView.fxml @@ -3,36 +3,14 @@ - - - - - - - - + - - - - - - - - - - + + GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"> - + - - - + + +