diff --git a/Meilenstein V/Diary.txt b/Meilenstein V/Diary.txt index e539ab1..1c4d0fb 100644 --- a/Meilenstein V/Diary.txt +++ b/Meilenstein V/Diary.txt @@ -366,3 +366,6 @@ Habe Highscore und Players in Lobbies auf die einfachst mögliche Art mit Textfl 16.5.2022 - Jonas Have been working on implementing all sound effects over the last couple of days + +17. & 18.5.2022 - Jonas +Working on outreach stuff and presentation. \ No newline at end of file diff --git a/Meilenstein V/Night Train To Budapest - gameplay video.mp4 b/Meilenstein V/Night Train To Budapest - gameplay video.mp4 new file mode 100644 index 0000000..c48205c Binary files /dev/null and b/Meilenstein V/Night Train To Budapest - gameplay video.mp4 differ diff --git a/Meilenstein V/Slides.pdf b/Meilenstein V/Slides.pdf new file mode 100644 index 0000000..6506c84 Binary files /dev/null and b/Meilenstein V/Slides.pdf differ diff --git a/Meilenstein V/logo.png b/Meilenstein V/logo.png new file mode 100644 index 0000000..0312268 Binary files /dev/null and b/Meilenstein V/logo.png differ diff --git a/OgGhostWinners.txt b/OgGhostWinners.txt index 53225b1..d463ca8 100644 --- a/OgGhostWinners.txt +++ b/OgGhostWinners.txt @@ -6,3 +6,8 @@ serai serai serai serai +Jonas +Jonas +Jonas +Jonas, the French delegate +Jonas diff --git a/build.gradle b/build.gradle index 1d66b45..dec25ad 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ javafx { } group 'ch.unibas.dmi.dbis' -version '0.0.2' + mainClassName = 'ch.unibas.dmi.dbis.cs108.NightTrainToBudapest' java { diff --git a/outreach/game.properties b/outreach/game.properties index 3e65681..dfc78a6 100644 --- a/outreach/game.properties +++ b/outreach/game.properties @@ -1,8 +1,8 @@ -game.name = Example Game -game.command = java -jar exampleGame.jar +game.name = Night Train to Budapest +game.command = java -jar NightTrainToBudapest.jar game.description.file = index.html game.screenshot.file = example.png -game.server.command = java -jar exampleGame.jar +game.server.command = java -jar NightTrainToBudapest.jar game.use = true -game.year = 2020 -game.developers = Tom Cat, Jerry Mouse, William Hanna, Joseph Barbera +game.year = 2022 +game.developers = Seraina Schöb, Jonas Biedermann, Sebastian Lenzlinger, Alexandr Sazonov diff --git a/outreach/index.html b/outreach/index.html index 76e9e65..a683219 100644 --- a/outreach/index.html +++ b/outreach/index.html @@ -1,14 +1,14 @@ -Example Game +Night Train to Budapest
-

Example Game

-Hier könnt ihr einen Satz über euer Spiel sagen. +

Night Train to Budapest

+Tief im österreichischen Wald rast ein Nachtzug richtung Budapest - doch unter den Passagieren scheint etas böses zu lauern...

@@ -28,26 +28,20 @@ Hier könnt ihr einen Satz über euer Spiel sagen.

Entwickler:

    -
  • Edgar Codd
  • -
  • Lynn Conway
  • -
  • Ada Lovelace
  • -
  • Alan Turing
  • +
  • Seraina Schöb
  • +
  • Jonas Biedermann
  • +
  • Sebastian Lenzlinger
  • +
  • Alexandr Sazonov

Steuerung:

-Pfeiltasten: bewegen
-Leertaste: springen
-I: Inventar
-Esc: Spiel beenden
-P: Spiel pausieren + Das Spiel wird mit der Maus gespielt.
+Enter: Chatnachricht senden
-

Inventar:

-Eisblock: Gegner können sich nicht mehr bewegen
-Schwarzes Loch: Steuerung der Gegner wird invertiert
diff --git a/outreach/screenshot.png b/outreach/screenshot.png index fc60247..8a30e6f 100644 Binary files a/outreach/screenshot.png and b/outreach/screenshot.png differ diff --git a/outreach/video.mp4 b/outreach/video.mp4 index 80274a1..8651d00 100644 Binary files a/outreach/video.mp4 and b/outreach/video.mp4 differ diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java index 0464c45..b6a3554 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java @@ -23,16 +23,16 @@ public class ClientGameInfoHandler { public static final String gameOverGhostsWin = "Game over, ghosts win!"; //relevant for gui - public static final String itsNightTime = "Please wait, ghosts are active"; - public static final String itsDayTime = "Please wait, humans are active"; + public static final String itsNightTime = "Listen closely, ghosts are active..."; + public static final String itsDayTime = "The humans are looking for you!"; //just messages public static final String youGotGhostyfied = "You are now a ghost!"; - public static final String youGotKickedOff = "Bye bye - you've been kicked off"; - public static final String humansVotedFor = "Humans voted for: "; - public static final String isAHuman = " but they're a human!"; - public static final String gotKickedOff = " is a Ghost and got kicked off"; + public static final String youGotKickedOff = "Bye bye - you've been kicked off."; + public static final String humansVotedFor = "Humans voted for "; + public static final String isAHuman = ", but they're a human!"; + public static final String gotKickedOff = " is a Ghost and got kicked off."; public static final String gotGhostyfied = " is now also a ghost!"; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index ac7156a..284a506 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -122,6 +122,10 @@ public class Game implements Runnable { LOGGER.info(gameState.toGhostString()); for (ClientHandler client : lobbyClients) {//begins filling the train with clients + + //send train horn sound to client: + client.sendMsgToClient(Protocol.playSound + "$" + "TH"); + int index = order[i]; if (passengerTrain[index].getIsGhost()) { //if there is a ghost GhostPlayer ghostPlayer = new GhostPlayer(passengerTrain[index].getPosition(), @@ -172,6 +176,14 @@ public class Game implements Runnable { if (gameOverCheck.equals(ClientGameInfoHandler.gameOverGhostsWin) && getOgGhost().getIsPlayer()) { OgGhostHighScore.addOgGhostWinner(getOgGhost().getName()); } + + //send command to play game over sound: + if (gameOverCheck.equals(ClientGameInfoHandler.gameOverGhostsWin)) { + lobby.getAdmin().sendMsgToClientsInLobby(Protocol.playSound + "$" + "GW"); + } else { + lobby.getAdmin().sendMsgToClientsInLobby(Protocol.playSound + "$" + "HW"); + } + lobby.getAdmin().broadcastAnnouncementToLobby(gameOverCheck); isOngoing = false; Timer.ghostAfterVoteTimer(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index 0d524f2..d970034 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -52,6 +52,7 @@ public class GameState { for (int i = 0; i < nrOfPlayers; i++) { if (i == train.getPositionOfGhost()) { LOGGER.info("OG position: " + train.getOrderOfTrain()[i]); + System.out.println("Og-Ghost Position: " + train.getOrderOfTrain()[i]); Ghost g = new Ghost(); g.setPosition(train.getOrderOfTrain()[i]); g.setGhost(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/NoiseHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/NoiseHandler.java index e455f3b..8c5339c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/NoiseHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/NoiseHandler.java @@ -24,11 +24,11 @@ public class NoiseHandler { public int[] noiseNotifier(Passenger predator, Passenger victim, int[] noiseAmount) { if (predator.getPosition() - victim.getPosition() > 0) { // if predator is to the right of victim - for (int i = predator.getPosition() - 1; i > victim.getPosition(); i--) { + for (int i = predator.getPosition() ; i > victim.getPosition(); i--) { //-1 noiseAmount[i]++; } } else { // if predator is to the left of victim - for (int i = predator.getPosition() + 1; i < victim.getPosition(); i++) { + for (int i = predator.getPosition(); i < victim.getPosition(); i++) { //+1 noiseAmount[i]++; } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java index dd556a9..4034172 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java @@ -121,14 +121,13 @@ public class ServerGameInfoHandler { case ClientGameInfoHandler.noiseNotification + 4 + " time(s)": case ClientGameInfoHandler.noiseNotification + 5 + " time(s)": case ClientGameInfoHandler.noiseNotification: - //todo: jonas: handle bell behaviour correctly. - String outMsg = npc.getName() + ": " + noiseRandomizer(); - //TODO: add likelyhood + if(!npc.getKickedOff()) { - game.getLobby().getAdmin().broadcastNpcChatMessageToLobby(outMsg); - game.getLobby().getAdmin().sendMsgToClientsInLobby( - Protocol.printToGUI + "$" + GuiParameters.noiseHeardAtPosition - + "$" + npc.getPosition()); + if (Math.random() < GhostNPC.probabilityToRingAlarmIfHeardNoise) { + game.getLobby().getAdmin().sendMsgToClientsInLobby( + Protocol.printToGUI + "$" + GuiParameters.noiseHeardAtPosition + + "$" + npc.getPosition()); + } } break; case ClientGameInfoHandler.ghostVoteRequest: @@ -151,13 +150,13 @@ public class ServerGameInfoHandler { case ClientGameInfoHandler.noiseNotification + 4 + " time(s)": case ClientGameInfoHandler.noiseNotification + 5 + " time(s)": case ClientGameInfoHandler.noiseNotification: //new case where times are not noted. - //todo: jonas: handle bell behaviour correctly. - String outMsg = npc.getName() + ": " + noiseRandomizer(); if(!npc.getKickedOff()) { - game.getLobby().getAdmin().broadcastNpcChatMessageToLobby(outMsg); - game.getLobby().getAdmin().sendMsgToClientsInLobby( - Protocol.printToGUI + "$" + GuiParameters.noiseHeardAtPosition - + "$" + npc.getPosition()); + if (Math.random() < HumanNPC.probabilityToRingAlarmIfHeardNoise) { + game.getLobby().getAdmin().sendMsgToClientsInLobby( + Protocol.printToGUI + "$" + GuiParameters.noiseHeardAtPosition + + "$" + npc.getPosition()); + } + } break; case ClientGameInfoHandler.humanVoteRequest: diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Timer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Timer.java index bef9f07..e31d356 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Timer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Timer.java @@ -16,23 +16,23 @@ public class Timer { /** * The maximum length of the ghost vote in the night, in seconds */ - public static final int ghostVoteTime = 30; + public static final int ghostVoteTime = 40; /** * The length of time in seconds after the ghost vote during which the ghosts visually walk to / * from their victim and the timespan within which humans will hear a noise. After this, the day starts. */ - public static final int ghostAfterVoteTime = 6; + public static final int ghostAfterVoteTime = 8; /** * The maximum length of the human vote in the day, in seconds */ - public static final int humanVoteTime = 60; + public static final int humanVoteTime = 63; /** * The length of time in seconds after the human vote, as the 'winner' of the vote is announced, * before the night begins */ - public static final int humanAfterVoteTime = 5; + public static final int humanAfterVoteTime = 8; /** * The checking interval in seconds diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index e8a6410..0a98294 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -4,6 +4,7 @@ import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; +import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -88,7 +89,7 @@ public class VoteHandler { ghostification. */ int[] noiseAmount = new int[6]; for (int i = 0; i < passengers.length; i++) { - if (passengers[i].getIsGhost() && i != newGhostPosition) { + if (passengers[i].getIsGhost() && !passengers[i].getKickedOff() && i != newGhostPosition) { NoiseHandler n = new NoiseHandler(); noiseAmount = n.noiseNotifier(passengers[i], g, noiseAmount); } @@ -169,12 +170,24 @@ public class VoteHandler { .getIsGhost()) { // if player with most votes is human, notify everyone about it for (Passenger passenger : passengers) { passenger.send( - ClientGameInfoHandler.humansVotedFor + voteIndex + ClientGameInfoHandler.isAHuman, game); + ClientGameInfoHandler.humansVotedFor + passengers[voteIndex].getName() + ClientGameInfoHandler.isAHuman, game); + } + + for (ClientHandler c: game.getLobby().getLobbyClients()) { //send human vote sound to clients + c.sendMsgToClient(Protocol.playSound + "$" + "HV"); + } + } else if (!passengers[voteIndex].getIsOG()) { + for (ClientHandler c: game.getLobby().getLobbyClients()) { //send ghost vote sound to clients + c.sendMsgToClient(Protocol.playSound + "$" + "GV"); } } - Timer.humanAfterVoteTimer(); + if (passengers[voteIndex].getIsGhost()) { // if player is a ghost if (passengers[voteIndex].getIsOG()) { // if ghost is OG --> end game, humans win + for (Passenger passenger : passengers) { + passenger.send( + ClientGameInfoHandler.humansVotedFor + passengers[voteIndex].getName() + ", the Original Ghost!", game); + } System.out.println(ClientGameInfoHandler.gameOverHumansWin); return ClientGameInfoHandler.gameOverHumansWin; } else { @@ -200,6 +213,8 @@ public class VoteHandler { } } } + Timer.humanAfterVoteTimer(); + LOGGER.info(game.getGameState().toString()); // set hasVoted to false for all passengers for future voting for (Passenger passenger : passengers) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java index f0faaab..6eea800 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java @@ -9,6 +9,7 @@ import org.apache.logging.log4j.Logger; public class GhostNPC extends Ghost { public static final Logger LOGGER = LogManager.getLogger(GhostNPC.class); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); + public static final double probabilityToRingAlarmIfHeardNoise = 0.5; /** * Creates a new GhostNPC. Should be used at game start or if a HumanNPC is turned into a ghost. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java index 271ea9d..8b1f961 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java @@ -1,6 +1,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.ClientGameInfoHandler; import ch.unibas.dmi.dbis.cs108.gamelogic.ClientVoteData; import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; @@ -14,6 +15,7 @@ public class GhostPlayer extends Ghost { public static final Logger LOGGER = LogManager.getLogger(GhostPlayer.class); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); + /** * Creates a new GhostPlayer. Should be used at game start or if a HumanPlayer is turned into a * ghost. @@ -48,6 +50,8 @@ public class GhostPlayer extends Ghost { String formattedMsg; if (msg.equals(GuiParameters.updateGameState)) { formattedMsg = Protocol.printToGUI + "$" + GuiParameters.updateGameState + game.getGameState().toGhostString(); + } else if (msg.equals(ClientGameInfoHandler.noiseNotification)) { + formattedMsg = Protocol.noiseNotificationProtocol; } else { formattedMsg = ServerGameInfoHandler.format(msg, this, game); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java index 8a8a6f7..f595628 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java @@ -10,6 +10,7 @@ public class HumanNPC extends Human { public static final Logger LOGGER = LogManager.getLogger(HumanNPC.class); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); + public static final double probabilityToRingAlarmIfHeardNoise = 0.9; /** * Creates a new HumanNPC. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Spectator.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Spectator.java index 338b8db..7baa834 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Spectator.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Spectator.java @@ -1,8 +1,10 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.ClientGameInfoHandler; import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; +import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -29,6 +31,11 @@ public class Spectator extends Passenger{ */ @Override public void send(String msg, Game game) { - clientHandler.sendMsgToClient(ServerGameInfoHandler.spectatorFormat(msg, game)); + + if (msg.equals(ClientGameInfoHandler.noiseNotification)) { + clientHandler.sendMsgToClient(Protocol.noiseNotificationProtocol); + } else { + clientHandler.sendMsgToClient(ServerGameInfoHandler.spectatorFormat(msg, game)); + } } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java index 08b1c5b..c93327b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java @@ -10,6 +10,7 @@ import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.Sprites; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatController; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.GameController; +import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.ListOfLobbiesController; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LobbyDisplayHandler; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeApp; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeSceneViewController; @@ -373,34 +374,22 @@ public class Client { LOGGER.warn("Not a position given for noise " + e.getMessage()); } break; - case GuiParameters.listOfLobbies: - updateListOfLobbies(data); - //TODO - break; case GuiParameters.VoteIsOver: chatApp.getGameController().setNoiseButtonInvisible(); chatApp.getGameController().clearAllNoiseDisplay(); dayNightChangeListener.setNoiseButtonInvisible(true); break; - case GuiParameters.getMembersInLobby: - updateLobbyMembers(data); - break; case GuiParameters.viewChangeToGame: chatApp.getLoungeSceneViewController().addGameView(); gameStateModel.setGameOver(false); dayNightChangeListener = new DayNightChangeListener(gameStateModel, chatApp, Integer.MAX_VALUE); + ListOfLobbiesController.setGameOngoing(true); new Thread(dayNightChangeListener).start(); break; case GuiParameters.viewChangeToLobby: chatApp.getLoungeSceneViewController().removeGameView(); gameStateModel.setGameOver(true); - //TODO - break; - case GuiParameters.addNewMemberToLobby: - addPlayerToLobby(data); - break; - case GuiParameters.newLobbyCreated: - makeNewLobby(data); + ListOfLobbiesController.setGameOngoing(false); break; case GuiParameters.updateHighScore: chatApp.getLoungeSceneViewController().addHighScore(data); @@ -408,16 +397,17 @@ public class Client { case GuiParameters.yourPosition: dayNightChangeListener.setPosition(Integer.parseInt(data)); break; - case GuiParameters.updatePrintLobby: - chatApp.getLoungeSceneViewController().clearLobbyPrint(); - chatApp.getLoungeSceneViewController().addLobbyPrint(data); - break; - case GuiParameters.removeLobby: - removeLobbyFromGui(data); - break; case GuiParameters.updateLobbyString: - lobbyDisplayHandler.updateLobbies(data); - ChatApp.getListController().updateList(); + if(!data.isEmpty()) { + lobbyDisplayHandler.updateLobbies(data); + if(!ListOfLobbiesController.isGameOngoing()) { + ChatApp.getListController().updateList(); + } + } else { + if(!ListOfLobbiesController.isGameOngoing()) { + ChatApp.getListController().clearVBox(); + } + } break; default: notificationTextDisplay(data); @@ -431,42 +421,6 @@ public class Client { } - private void removeLobbyFromGui(String data) { - loungeSceneViewController.removeLobbyFromView(data); - LOGGER.debug("Made it into removeLobbyFromGui()"); - } - - private void makeNewLobby(String data) { - String[] params = data.split(":"); - loungeSceneViewController.newLobby(params[0], params[1]); - LOGGER.debug("makeNewLobby() seems to have finished"); - - } - - private void addPlayerToLobby(String data) { - String[] params = data.split(":"); - loungeSceneViewController.addPlayerToLobby(params[0], params[1]); - LOGGER.debug("addPlayerToLobby() seems to have finished"); - } - - private void updateLobbyMembers(String data) { - String[] dataArr = data.split(":"); - String lobbyID = dataArr[0]; - String adminName = dataArr[1]; - } - - private void updateListOfLobbies(String data) { - String[] arr = data.split(":"); - ObservableList list = new SimpleListProperty<>(); - int n = arr.length; - for (int i = 0; i < n; i = i + 2) { - list.add(new SimpleStringProperty(arr[i])); - //ChatController.getClient().addLobbyToList(new SimpleStringProperty(arr[i])); - } - //TODO - } - - /** * Starts a new thread, thad adds a message to notificationText in the gameController, waits 3 * seconds and deletes it again. @@ -476,7 +430,11 @@ public class Client { public void notificationTextDisplay(String data) { new Thread(() -> { try { - chatApp.getGameController().addMessageToNotificationText(data); + if (data.contains("Game over")) { + chatApp.getGameController().addMessageToNotificationText(data); + } else if (!data.contains("$") && !data.contains("nickname")) { + chatApp.getChatController().addChatMsgToServerView(data); + } Thread.sleep(5000); chatApp.getGameController().clearNotificationText(); } catch (InterruptedException e) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java index ba867ee..ff071f7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java @@ -91,6 +91,27 @@ public class JClientProtocolParser { case Protocol.noiseNotificationProtocol: Sound.ghost(); break; + case Protocol.playSound: + switch (msg.substring(6)) { + case "GW": + Sound.gameoverghosts(); + break; + case "HW": + Sound.gameoverhumans(); + break; + case "GV": + Sound.voteforghost(); + break; + case "HV": + Sound.voteforhuman(); + break; + case "TH": + Sound.trainhorn(); + break; + default: + LOGGER.warn("Invalid sound request"); + } + break; default: System.out.println("Received unknown command: " + msg); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Sound.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Sound.java index 6067c6a..ca48721 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Sound.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Sound.java @@ -17,6 +17,9 @@ public class Sound { static URL bellURL = Sound.class.getResource("sounds/bell.wav"); static AudioClip bell = new AudioClip(bellURL.toString()); + static URL trainhornURL = Sound.class.getResource("sounds/trainhorn.wav"); + static AudioClip trainhorn = new AudioClip(trainhornURL.toString()); + static URL daynoisesURL = Sound.class.getResource("sounds/daynoises.wav"); static AudioClip daynoises = new AudioClip(daynoisesURL.toString()); @@ -41,6 +44,32 @@ public class Sound { static URL ghost04URL = Sound.class.getResource("sounds/ghost04.wav"); static AudioClip ghost04 = new AudioClip(ghost04URL.toString()); + static URL ghost05URL = Sound.class.getResource("sounds/ghost05.wav"); + static AudioClip ghost05 = new AudioClip(ghost05URL.toString()); + + static URL ghost06URL = Sound.class.getResource("sounds/ghost06.wav"); + static AudioClip ghost06 = new AudioClip(ghost06URL.toString()); + + static URL ghost07URL = Sound.class.getResource("sounds/ghost07.wav"); + static AudioClip ghost07 = new AudioClip(ghost07URL.toString()); + + static URL ghost08URL = Sound.class.getResource("sounds/ghost08.wav"); + static AudioClip ghost08 = new AudioClip(ghost08URL.toString()); + + static URL ghost09URL = Sound.class.getResource("sounds/ghost09.wav"); + static AudioClip ghost09 = new AudioClip(ghost09URL.toString()); + + static URL ghost10URL = Sound.class.getResource("sounds/ghost10.wav"); + static AudioClip ghost10 = new AudioClip(ghost10URL.toString()); + + static URL ghost11URL = Sound.class.getResource("sounds/ghost11.wav"); + static AudioClip ghost11 = new AudioClip(ghost11URL.toString()); + + static URL ghost12URL = Sound.class.getResource("sounds/ghost12.wav"); + static AudioClip ghost12 = new AudioClip(ghost12URL.toString()); + + + static URL musicdayURL = Sound.class.getResource("sounds/music_day.wav"); static AudioClip musicday = new AudioClip(musicdayURL.toString()); @@ -77,6 +106,8 @@ public class Sound { bell.play(defaultvolume - 0.5); } + public static void trainhorn() {trainhorn.play(defaultvolume); } + public static void startDaynoises() { daynoises.setCycleCount(AudioClip.INDEFINITE); daynoises.play(defaultvolume - 0.5); @@ -95,9 +126,28 @@ public class Sound { nightnoises.stop(); } - public static void gameoverghosts() { gameoverghosts.play(defaultvolume); } + public static void gameoverghosts() { + waitForABitThenEndDayMusic(); + voteforghost.stop(); + voteforhuman.stop(); + gameoverghosts.play(defaultvolume - 0.3); } - public static void gameoverhumans() { gameoverhumans.play(defaultvolume); } + public static void gameoverhumans() { + waitForABitThenEndDayMusic(); + voteforghost.stop(); + voteforhuman.stop(); + gameoverhumans.play(defaultvolume - 0.1); + } + + public static void voteforghost() { + waitForABitThenEndDayMusic(); + voteforghost.play(defaultvolume - 0.4); + } + + public static void voteforhuman() { + waitForABitThenEndDayMusic(); + voteforhuman.play(defaultvolume - 0.2); + } public static void musicday() { musicday.play(defaultvolume); @@ -109,8 +159,9 @@ public class Sound { } public static void ghost() { - double playbackspeed = (Math.random() / 5.0) + 0.9; - int ghostsoundnr = random.nextInt(4) + 1; + //double playbackspeed = (Math.random() / 5.0) + 0.9; causes aliasing artefacts :/ + double playbackspeed = 1; + int ghostsoundnr = random.nextInt(12) + 1; System.out.println(ghostsoundnr); AudioClip ghost; switch (ghostsoundnr) { @@ -123,13 +174,57 @@ public class Sound { case 3: ghost = ghost03; break; - default: + case 4: ghost = ghost04; break; + case 5: + ghost = ghost05; + break; + case 6: + ghost = ghost06; + break; + case 7: + ghost = ghost07; + break; + case 8: + ghost = ghost08; + break; + case 9: + ghost = ghost09; + break; + case 10: + ghost = ghost10; + break; + case 11: + ghost = ghost11; + break; + case 12: + ghost = ghost12; + break; + default: + ghost = ghost01; + break; } - ghost.play(defaultvolume - 0.3, 0.0, playbackspeed, 0.0, 5); + ghost.play(0.1, 0.0, playbackspeed, 0.0, 5); } + /** + * waits for a bit, then ends day music. :) + */ + public static void waitForABitThenEndDayMusic() { + new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(1820); + //the time it takes for the vote result sound to ramp up, so the music ends exactly on the "big reveal" + } catch (InterruptedException e) { + e.printStackTrace(); + } + stopmusicday(); + } + }).start(); + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/ChatApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/ChatApp.java index ea0d17d..3472abf 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/ChatApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/ChatApp.java @@ -6,14 +6,17 @@ import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatController; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.GameController; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.ListOfLobbiesController; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeSceneViewController; +import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; import java.net.URL; import java.util.Objects; import javafx.application.Application; +import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; +import javafx.stage.WindowEvent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -208,6 +211,9 @@ public class ChatApp extends Application { Scene scene = new Scene(lounge); scene.setRoot(lounge); primaryStage.setScene(scene); + scene.getWindow().setOnCloseRequest((WindowEvent we) -> { + clientModel.getClient().sendMsgToServer(Protocol.clientQuitRequest); + }); } catch (Exception e) { e.printStackTrace(); } @@ -217,7 +223,11 @@ public class ChatApp extends Application { primaryStage.setResizable(true); primaryStage.setMaximized(true); primaryStage.show(); - } + } + + + + public static void main(String[] args) { launch(args); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/DayNightChangeListener.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/DayNightChangeListener.java index d5b0622..21e9776 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/DayNightChangeListener.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/DayNightChangeListener.java @@ -5,7 +5,7 @@ import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.GameController; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeSceneViewController; /** - * This class adds methods to listen if there is a change in the day&night state and calls methods accordingly + * This class adds methods to listen if there is a change in the day and night state and calls methods accordingly */ public class DayNightChangeListener implements Runnable { @@ -63,7 +63,7 @@ public class DayNightChangeListener implements Runnable { chatApp.getGameController().updateRoomLabels(); gameStateModel.setRoleFromPosition(position); try { - Thread.sleep(100); + Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/ChatController.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/ChatController.java index efb013c..26d994f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/ChatController.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/ChatController.java @@ -21,12 +21,15 @@ import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.control.TextField; +import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Background; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; +import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.text.Text; +import javafx.scene.text.TextFlow; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -34,6 +37,15 @@ public class ChatController implements Initializable { public static final Logger LOGGER = LogManager.getLogger(ChatController.class); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); + @FXML + private AnchorPane whisperAnchor; + @FXML + private AnchorPane chatinputAnchor; + + @FXML + private ScrollPane serverScrollPane; + @FXML + private VBox vBoxServer; @FXML private Group vboxGroup; @@ -109,6 +121,20 @@ public class ChatController implements Initializable { ChatScrollPane.setVvalue((Double) newValue); } }); + + vBoxServer.heightProperty().addListener(new ChangeListener<>() { + /** + * TODO: implement + * Adjust the height when new messages come in. + */ + @Override + public void changed(ObservableValue observable, Number oldValue, + Number newValue) { + vBoxServer.setMaxHeight(newValue.doubleValue()); + serverScrollPane.setMaxHeight(newValue.doubleValue() * 2); + serverScrollPane.setVvalue((Double) newValue); + } + }); /** * Initialize what happens when the send button is pressed */ @@ -186,11 +212,12 @@ public class ChatController implements Initializable { l.setMaxHeight(Double.MAX_VALUE); if (msg.contains("whispers")) { l.setBackground(Background.fill(Color.TRANSPARENT)); - l.setPrefWidth(1135); + l.setTextFill(Color.rgb(15,26,150)); + l.setPrefWidth(680); l.setScaleShape(false); } else { l.setBackground(Background.fill(Color.TRANSPARENT)); - l.setPrefWidth(1135); + l.setPrefWidth(680); l.setScaleShape(false); } l.setTextFill(Color.BLACK); @@ -202,4 +229,27 @@ public class ChatController implements Initializable { }); } + + public void addChatMsgToServerView(String msg) { + TextFlow textFlow = new TextFlow(); + textFlow.setPrefWidth(420); + textFlow.setPrefHeight(Region.USE_COMPUTED_SIZE); + Text text = new Text(msg); + textFlow.getChildren().add(text); + try { + Platform.runLater(new Runnable() { + @Override + public void run() { + try { + vBoxServer.getChildren().add(textFlow); + } catch (Exception e) { + LOGGER.warn(e.getMessage()); + } + } + }); + } catch(Exception e) { + LOGGER.warn(e.getMessage()); + } + } + } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/BellAnimation.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/BellAnimation.java index 5be8662..c1d2720 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/BellAnimation.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/BellAnimation.java @@ -1,12 +1,17 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game; +import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import javafx.animation.Interpolator; import javafx.animation.Transition; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.util.Duration; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class BellAnimation extends Transition { + public static final Logger LOGGER = LogManager.getLogger(BellAnimation.class); + public static final BudaLogConfig l = new BudaLogConfig(LOGGER); ImageView imageView; Image[] bells; int index; @@ -23,9 +28,13 @@ public class BellAnimation extends Transition { @Override protected void interpolate(double frac) { - if(index < 17) { - imageView.setImage(bells[index]); + try { + if (index < 17) { + imageView.setImage(bells[index]); + } + index++; + } catch (Exception e) { + LOGGER.warn(e.getMessage()); } - index++; } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameController.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameController.java index 4dcfc21..5be6aed 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameController.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameController.java @@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game; import static javafx.scene.AccessibleRole.PARENT; +import ch.unibas.dmi.dbis.cs108.gamelogic.Timer; import ch.unibas.dmi.dbis.cs108.multiplayer.client.Sound; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.GameStateModel; @@ -24,6 +25,7 @@ import javafx.scene.Group; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.effect.DropShadow; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; @@ -39,7 +41,7 @@ public class GameController implements Initializable { public static final Logger LOGGER = LogManager.getLogger(GameController.class); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); static boolean justRangBell = false; //used to track if the bell has been rung recently - static final int minimumBellTime = 1000; //minimal time that has to pass between bells, in ms + static final int minimumBellTime = 100; //minimal time that has to pass between bells, in ms static boolean playingDayNoises = true; //true if playing day noises, false if playing night noises private static ClientModel client; @@ -380,8 +382,8 @@ public class GameController implements Initializable { public void addMessageToNotificationText(String msg) { LOGGER.trace("addMessage " + msg); Text notification = new Text(System.lineSeparator() + msg); - notification.setFill(Color.BLACK); - notification.setStyle("-fx-font: 50 arial;"); + notification.setFill(Color.WHITE); + notification.setStyle("-fx-font: 50 serif;"); try { Platform.runLater(new Runnable() { @Override @@ -428,71 +430,30 @@ public class GameController implements Initializable { String[] roles = gameStateModel.getPassengerTrainClone()[1]; boolean[] kickedOff = gameStateModel.getKickedOff(); Text name0 = new Text(names[0]); - name0.setStyle("-fx-font: 25 arial;"); - name0.setFill(Color.WHITE); + name0.setStyle("-fx-font: 15 serif;"); + name0.setFill(Color.rgb(255,250,250,0.6)); + name0.setEffect(new DropShadow(2.5, Color.BLACK)); Text name1 = new Text(names[1]); - name1.setStyle("-fx-font: 25 arial;"); - name1.setFill(Color.WHITE); + name1.setStyle("-fx-font: 15 serif;"); + name1.setFill(Color.rgb(255,250,250,0.6)); + name1.setEffect(new DropShadow(2.5, Color.BLACK)); Text name2 = new Text(names[2]); - name2.setStyle("-fx-font: 25 arial;"); - name2.setFill(Color.WHITE); + name2.setStyle("-fx-font: 15 serif;"); + name2.setFill(Color.rgb(255,250,250,0.6)); + name2.setEffect(new DropShadow(2.5, Color.BLACK)); Text name3 = new Text(names[3]); - name3.setStyle("-fx-font: 25 arial;"); - name3.setFill(Color.WHITE); + name3.setStyle("-fx-font: 15 serif;"); + name3.setFill(Color.rgb(255,250,250,0.6)); + name3.setEffect(new DropShadow(2.5, Color.BLACK)); Text name4 = new Text(names[4]); - name4.setStyle("-fx-font: 25 arial;"); - name4.setFill(Color.WHITE); + name4.setStyle("-fx-font: 15 serif;"); + name4.setFill(Color.rgb(255,250,250,0.6)); + name4.setEffect(new DropShadow(2.5, Color.BLACK)); Text name5 = new Text(names[5]); - name5.setStyle("-fx-font: 25 arial;"); - name5.setFill(Color.WHITE); - Text role0; - if (kickedOff[0]) { - role0 = new Text("\nkicked off"); - } else { - role0 = new Text("\n" + roles[0]); - } - role0.setStyle("-fx-font: 25 arial;"); - role0.setFill(Color.WHITE); - Text role1; - if (kickedOff[1]) { - role1 = new Text("\nkicked off"); - } else { - role1 = new Text("\n" + roles[1]); - } - role1.setStyle("-fx-font: 25 arial;"); - role1.setFill(Color.WHITE); - Text role2; - if (kickedOff[2]) { - role2 = new Text("\nkicked off"); - } else { - role2 = new Text("\n" + roles[2]); - } - role2.setStyle("-fx-font: 25 arial;"); - role2.setFill(Color.WHITE); - Text role3; - if (kickedOff[3]) { - role3 = new Text("\nkicked off"); - } else { - role3 = new Text("\n" + roles[3]); - } - role3.setStyle("-fx-font: 25 arial;"); - role3.setFill(Color.WHITE); - Text role4; - if (kickedOff[4]) { - role4 = new Text("\nkicked off"); - } else { - role4 = new Text("\n" + roles[4]); - } - role4.setStyle("-fx-font: 25 arial;"); - role4.setFill(Color.WHITE); - Text role5; - if (kickedOff[5]) { - role5 = new Text("\nkicked off"); - } else { - role5 = new Text("\n" + roles[5]); - } - role5.setStyle("-fx-font: 25 arial;"); - role5.setFill(Color.WHITE); + name5.setStyle("-fx-font: 15 serif;"); + name5.setFill(Color.rgb(255,250,250,0.6)); + name5.setEffect(new DropShadow(2.5, Color.BLACK)); + Platform.runLater(new Runnable() { @Override @@ -500,22 +461,16 @@ public class GameController implements Initializable { try { lableRoom0.getChildren().clear(); lableRoom0.getChildren().add(name0); - lableRoom0.getChildren().add(role0); lableRoom1.getChildren().clear(); lableRoom1.getChildren().add(name1); - lableRoom1.getChildren().add(role1); lableRoom2.getChildren().clear(); lableRoom2.getChildren().add(name2); - lableRoom2.getChildren().add(role2); lableRoom3.getChildren().clear(); lableRoom3.getChildren().add(name3); - lableRoom3.getChildren().add(role3); lableRoom4.getChildren().clear(); lableRoom4.getChildren().add(name4); - lableRoom4.getChildren().add(role4); lableRoom5.getChildren().clear(); lableRoom5.getChildren().add(name5); - lableRoom5.getChildren().add(role5); } catch (Exception e) { LOGGER.trace("Not yet initialized"); } @@ -534,17 +489,7 @@ public class GameController implements Initializable { try { if(!gameStateModel.getKickedOff()[0]) { Animation bell = new BellAnimation(noiseImage5, bells); - //wait until it's day: - while (!getGameStateModel().getDayClone()) { - Thread.sleep(100); - } - Thread.sleep(500); - //just so the alarm isn't rung exactly when the day starts, add random delay - Random random = new Random(); - Thread.sleep(random.nextInt(1000)); - - bell.play(); - ringBellSound(); + waitForDayThenRingBell(bell); } } catch (Exception e) { e.printStackTrace(); @@ -565,16 +510,7 @@ public class GameController implements Initializable { try { if(!gameStateModel.getKickedOff()[1]) { Animation bell = new BellAnimation(noiseImage4, bells); - //wait until it's day: - while (!getGameStateModel().getDayClone()) { - Thread.sleep(100); - } - Thread.sleep(500); - //just so the alarm isn't rung exactly when the day starts, add random delay - Random random = new Random(); - Thread.sleep(random.nextInt(1000)); - bell.play(); - ringBellSound(); + waitForDayThenRingBell(bell); } } catch (Exception e) { e.printStackTrace(); @@ -594,17 +530,7 @@ public class GameController implements Initializable { try { if(!gameStateModel.getKickedOff()[2]) { Animation bell = new BellAnimation(noiseImage3, bells); - //wait until it's day: - while (!getGameStateModel().getDayClone()) { - Thread.sleep(100); - } - Thread.sleep(500); - //just so the alarm isn't rung exactly when the day starts, add random delay - Random random = new Random(); - Thread.sleep(random.nextInt(1000)); - - bell.play(); - ringBellSound(); + waitForDayThenRingBell(bell); } } catch (Exception e) { e.printStackTrace(); @@ -624,17 +550,7 @@ public class GameController implements Initializable { try { if(!gameStateModel.getKickedOff()[3]) { Animation bell = new BellAnimation(noiseImage2, bells); - //wait until it's day: - while (!getGameStateModel().getDayClone()) { - Thread.sleep(100); - } - Thread.sleep(500); - //just so the alarm isn't rung exactly when the day starts, add random delay - Random random = new Random(); - Thread.sleep(random.nextInt(1000)); - - bell.play(); - ringBellSound(); + waitForDayThenRingBell(bell); } } catch (Exception e) { e.printStackTrace(); @@ -654,17 +570,7 @@ public class GameController implements Initializable { try { if(!gameStateModel.getKickedOff()[4]) { Animation bell = new BellAnimation(noiseImage1, bells); - //wait until it's day: - while (!getGameStateModel().getDayClone()) { - Thread.sleep(100); - } - Thread.sleep(500); - //just so the alarm isn't rung exactly when the day starts, add random delay - Random random = new Random(); - Thread.sleep(random.nextInt(1000)); - - bell.play(); - ringBellSound(); + waitForDayThenRingBell(bell); } } catch (Exception e) { e.printStackTrace(); @@ -684,16 +590,7 @@ public class GameController implements Initializable { try { if(!gameStateModel.getKickedOff()[5]) { Animation bell = new BellAnimation(noiseImage0, bells); - //wait until it's day: - while (!getGameStateModel().getDayClone()) { - Thread.sleep(100); - } - Thread.sleep(500); - //just so the alarm isn't rung exactly when the day starts, add random delay - Random random = new Random(); - Thread.sleep(random.nextInt(1000)); - bell.play(); - ringBellSound(); + waitForDayThenRingBell(bell); } } catch (Exception e) { e.printStackTrace(); @@ -734,6 +631,34 @@ public class GameController implements Initializable { ChatApp.setGameController(this); } + public static void waitForDayThenRingBell(Animation bell) { + new Thread(new Runnable() { + @Override + public void run() { + try { + //wait until it's day: + int timeoutCounter = 0; //otherwise this thread can get stuck in a loop if player leaves server + if (!getGameStateModel().getDayClone()) { //used to ring bell immediately if it's already day + while (!getGameStateModel().getDayClone() + && timeoutCounter < Timer.ghostAfterVoteTime * 15) { + Thread.sleep(100); + timeoutCounter++; + } + //just so the alarm isn't rung exactly when the day starts, also add random delay + Thread.sleep(1000); + Random random = new Random(); + Thread.sleep(random.nextInt(1000)); + } + + } catch (Exception e) { + e.printStackTrace(); + } + bell.play(); + ringBellSound(); + } + }).start(); + } + /** * plays bell sound, but only if it hasn't been played recently, to avoid artefacts due to * overlapping sounds diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/ListOfLobbiesController.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/ListOfLobbiesController.java index f40a3c5..4fa663a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/ListOfLobbiesController.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/ListOfLobbiesController.java @@ -2,10 +2,12 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge; import static javafx.scene.control.PopupControl.USE_COMPUTED_SIZE; +import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import ch.unibas.dmi.dbis.cs108.multiplayer.client.Client; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ClientModel; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; +import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import ch.unibas.dmi.dbis.cs108.multiplayer.server.Lobby; import ch.unibas.dmi.dbis.cs108.multiplayer.server.LobbyUpdater; import java.net.URL; @@ -25,8 +27,13 @@ import javafx.scene.layout.Background; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class ListOfLobbiesController implements Initializable { + public static final Logger LOGGER = LogManager.getLogger(ListOfLobbiesController.class); + public static final BudaLogConfig l = new BudaLogConfig(LOGGER); + @FXML private ScrollPane backDropScrolePane; @@ -37,17 +44,30 @@ public class ListOfLobbiesController implements Initializable { private ChatApp chatApp; //TODO: VeryImportant to set this one right! private HashSet treeViews = new HashSet(); + private static boolean gameOngoing = false; public void setChatApp(ChatApp chatApp) { this.chatApp = chatApp; } + public static void setGameOngoing(boolean gameOngoing) { + ListOfLobbiesController.gameOngoing = gameOngoing; + } + + public static boolean isGameOngoing() { + return gameOngoing; + } public void updateList() { - clearVBox(); - for (LobbyModel lobby : LobbyDisplayHandler.getLobbies()) { - newTreeView(lobby.getId(), lobby.getAdmin(), chatApp.getcModel().getUsername(), lobby.getMembers()); - } + new Thread(new Runnable() { + @Override + public void run() { + clearVBox(); + for (LobbyModel lobby : LobbyDisplayHandler.getLobbies()) { + newTreeView(lobby.getId(), lobby.getAdmin(), lobby.isLobbyIsOpen(), chatApp.getcModel().getUsername(), lobby.getMembers()); + } + } + }).start(); } /** @@ -55,38 +75,57 @@ public class ListOfLobbiesController implements Initializable { * @param lobbyId the id of the lobby * @param admin the admin of the lobby * @param userName the username of the client + * @param isOpen the status if lobby is open or closed */ - public void newTreeView(int lobbyId, String admin, String userName, HashSet members) { + public void newTreeView(int lobbyId, String admin, boolean isOpen, String userName, HashSet members) { try { Button button = new Button(); if (admin.equals(userName)) { // the client of this user is the admin of this lobby button.setOnAction(event -> startGame()); button.setText("Start"); - } else { + } else if (isOpen){ button.setOnAction(event -> joinALobby(lobbyId)); button.setText("Join"); + } else { + button.setVisible(false); } HBox rootHBox = new HBox(); - rootHBox.setPrefWidth(195); - rootHBox.setMaxHeight(20); - Label adminLabel = new Label(lobbyId + " " + admin); + rootHBox.setPrefWidth(300); + rootHBox.setMaxHeight(45); + String statusLobby; + if (isOpen) { + statusLobby = " (open)"; + } else { + statusLobby = " (closed)"; + } + Label adminLabel = new Label(" Lobby " + lobbyId + ": " + admin + statusLobby); adminLabel.setTextFill(Color.WHITE); + try { + rootHBox.getChildren().add(button); + } catch (Exception e) { + LOGGER.warn(e.getMessage()); + } rootHBox.getChildren().add(adminLabel); - rootHBox.getChildren().add(button); TreeItem root = new TreeItem(rootHBox); + root.setExpanded(true); + int i = 1; for (String member : members) { HBox memberBox = new HBox(); - memberBox.setPrefWidth(195); - memberBox.setMaxHeight(20); - Label memberLabel = new Label(member); + memberBox.setPrefWidth(300); + memberBox.setMaxHeight(45); + memberBox.setPrefHeight(USE_COMPUTED_SIZE); + Label memberLabel = new Label("- " + member); memberLabel.setTextFill(Color.WHITE); memberBox.getChildren().add(memberLabel); root.getChildren().add(new TreeItem(memberBox)); + i++; } TreeView treeView = new TreeView<>(root); treeView.setVisible(true); - treeView.setPrefWidth(195); - treeView.setMaxHeight(USE_COMPUTED_SIZE); + treeView.setPrefWidth(300); + treeView.setMinHeight(i*45 + 10); + treeView.setPrefHeight(i*45 + 10); + treeView.setMaxHeight(i*45 + 10); Platform.runLater(new Runnable() { @Override public void run() { @@ -96,7 +135,7 @@ public class ListOfLobbiesController implements Initializable { } }); } catch (Exception e) { - e.printStackTrace(); + LOGGER.warn(e.getMessage()); } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LobbyDisplayHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LobbyDisplayHandler.java index f09e2e3..b4bc033 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LobbyDisplayHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LobbyDisplayHandler.java @@ -11,11 +11,20 @@ public class LobbyDisplayHandler { private static HashSet lobbies = new HashSet<>(); + private static boolean threadRunning = false; public static HashSet getLobbies() { return lobbies; } + public static void setThreadRunning(boolean threadRunning) { + LobbyDisplayHandler.threadRunning = threadRunning; + } + + public static boolean isThreadRunning() { + return threadRunning; + } + /** * searches lobbies for a lobby with a certain id * @param id the int representing a Lobby id to be lookes for @@ -31,6 +40,17 @@ public class LobbyDisplayHandler { } public void updateLobbies(String data) { + new Thread(new Runnable() { + @Override + public void run() { + while(isThreadRunning()) { + try { + Thread.sleep(20); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + setThreadRunning(true); try { for (LobbyModel model : lobbies) { model.setHasBeenVisited(false); @@ -46,7 +66,7 @@ public class LobbyDisplayHandler { if (searchForLobbyId(id) == null) { //the lobby is new and has not been saved yet addLobbyFromString(id, admin, isOpen, oneLobby); } else { // the lobby exists but might need to be updated - updateExistingLobby(id, isOpen, oneLobby); + updateExistingLobby(id, admin, isOpen, oneLobby); } } //System.out.println("lobby size before removal: " + lobbies.size()); @@ -55,7 +75,12 @@ public class LobbyDisplayHandler { } catch (Exception e) { e.printStackTrace(); LOGGER.info("empty list"); + } finally { + setThreadRunning(false); } + } + + }).start(); } private void addLobbyFromString(int id, String admin, boolean isOpen, String[] oneLobby) { @@ -72,9 +97,12 @@ public class LobbyDisplayHandler { //System.out.println("lobby size: " + lobbies.size()); } - private void updateExistingLobby(int id, boolean isOpen, String[] oneLobby) { + private void updateExistingLobby(int id, String admin,boolean isOpen, String[] oneLobby) { //System.out.println("update"); LobbyModel oldLobby = searchForLobbyId(id); + if (!oldLobby.getAdmin().equals(admin)) { + oldLobby.setAdmin(admin); + } oldLobby.setHasBeenVisited(true); oldLobby.setLobbyIsOpen(isOpen); oldLobby.removeAllMembers(); @@ -87,7 +115,7 @@ public class LobbyDisplayHandler { LobbyDisplayHandler handler = new LobbyDisplayHandler(); String lobby = "1:Seraina:true:Alex:Jonas$2:Sebi:false:Maria:Claudia:Hansli$3:Vanessa:true:Lara:Flu"; handler.updateLobbies(lobby); - System.out.println("lobby size in main:" + lobbies.size()); + //System.out.println("lobby size in main:" + lobbies.size()); for (LobbyModel model : lobbies) { //System.out.println(model); System.out.println("Lobby " + model.getId() + " " + model.isLobbyIsOpen() + " (" + model.getAdmin() + "):"); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LobbyModel.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LobbyModel.java index 7567a29..667be99 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LobbyModel.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LobbyModel.java @@ -8,7 +8,7 @@ import java.util.HashSet; */ public class LobbyModel { private final int id; - private final String admin; + private String admin; private HashSet members = new HashSet(5); private boolean lobbyIsOpen = true; private boolean hasBeenVisited = false; @@ -42,6 +42,10 @@ public class LobbyModel { return admin; } + public void setAdmin(String admin) { + this.admin = admin; + } + public void setHasBeenVisited(boolean hasBeenVisited) { this.hasBeenVisited = hasBeenVisited; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LoungeSceneViewController.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LoungeSceneViewController.java index ea29f14..e5c6c0d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LoungeSceneViewController.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LoungeSceneViewController.java @@ -35,8 +35,10 @@ import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; +import javafx.scene.layout.TilePane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; +import javafx.scene.text.Font; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; import javafx.util.Duration; @@ -47,69 +49,48 @@ public class LoungeSceneViewController implements Initializable { public static final Logger LOGGER = LogManager.getLogger(LoungeSceneViewController.class); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); - @FXML - private AnchorPane listLobbyAnchorPane; + private AnchorPane highScorePane; @FXML - private AnchorPane buttonPane; - @FXML - private AnchorPane buttonLobbyPane; - @FXML - private AnchorPane backGroundAnimationPane; - - @FXML - private AnchorPane backGroundAnchorPane; + private TilePane listTilePane; @FXML private AnchorPane gameDisplayAnchorPane; @FXML + private AnchorPane listLobbyAnchorPane; + @FXML private TextFlow highScore; @FXML - public TextFlow lobbyPrint; - @FXML - private SplitPane chatSplitPane; - @FXML - public Button highScoreButton; - @FXML - private Button leaveLobbyButton; - @FXML - private Button lobbyPrintButton; - @FXML - private Button startGame; - @FXML private Button newGameButton; @FXML - private AnchorPane gameAnchorPane; + private ToolBar LobbyControlsToolBar; @FXML - public ListView LobbyListView; + private BorderPane allLobbyElementsBorderPane; + @FXML + private AnchorPane ChatArea; @FXML private Button ChangeNameButton; @FXML + private Button leaveLobbyButton; + @FXML private Button LeaveServerButton; @FXML - private AnchorPane ChatArea; + private AnchorPane backGroundAnchorPane; + @FXML + private AnchorPane backGroundAnimationPane; @FXML private BorderPane LoungeSceneBorderPane; @FXML private ToolBar NTtBToolBar; - public static ListView lListView; - public static ClientModel client; private static ChatApp chatApp; + private ChatApp cApp; private static TrainAnimationDayController trainAnimationDayController; - ObservableList clients = FXCollections.observableArrayList(); - ObservableList lobbies = FXCollections.observableArrayList(); - - private ObservableMap> lobbyToMemberssMap; - private HashMap clientToLobbyMap; - private HashMap lobbyIDtoLobbyMop; public LoungeSceneViewController() { super(); - lobbyToMemberssMap = FXCollections.observableHashMap(); - lobbyIDtoLobbyMop = new HashMap<>(); } public void setChatApp(ChatApp chatApp) { @@ -143,122 +124,20 @@ public class LoungeSceneViewController implements Initializable { ChangeNameButton.setOnAction(event -> changeName()); LeaveServerButton.setOnAction(event -> leaveServer()); newGameButton.setOnAction(event -> newGame()); - LobbyListView.setVisible(true); - lListView = LobbyListView; - LOGGER.debug("Lobby in initialize" + LobbyListView); addChatView(); addBackgroundDay(); addListOfLobbiesView(); LOGGER.debug("cApp = " + cApp); LOGGER.debug("chatApp = " + chatApp); TrainAnimationDayController.setcApp(cApp); - ImageView bgAnimationView = new ImageView(); - bgAnimationView.setFitHeight(1950); - bgAnimationView.setFitWidth(6667.968); - - - LobbyListView.setItems(lobbies); - LOGGER.debug("In Initialize 2 LobbyListView" + LobbyListView); - LobbyListView.setCellFactory(param -> { - ListCell cell = new ListCell<>() { - Label lobbyID = new Label(); - Label adminName = new Label(); - Label lobbyIsOpen = new Label(); - Label noOfPlayersInLobby = new Label(); - Button startOrJoin = new Button(); - HBox head = new HBox(lobbyID, adminName, noOfPlayersInLobby, lobbyIsOpen, startOrJoin); - VBox playerList = new VBox(); - TitledPane headParent = new TitledPane(head.toString(), playerList); - - { - head.setAlignment(Pos.CENTER_LEFT); - head.setSpacing(5); - playerList.setAlignment(Pos.CENTER_LEFT); - headParent.setCollapsible(true); - } - - /** - * The updateItem method should not be called by developers, but it is the - * best method for developers to override to allow for them to customise the - * visuals of the cell. To clarify, developers should never call this method - * in their code (they should leave it up to the UI control, such as the - * {@link ListView} control) to call this method. However, the purpose of - * having the updateItem method is so that developers, when specifying - * custom cell factories (again, like the ListView {@link - * ListView#cellFactoryProperty() cell factory}), the updateItem method can - * be overridden to allow for complete customisation of the cell. - * - *

It is very important that subclasses - * of Cell override the updateItem method properly, as failure to do so will - * lead to issues such as blank cells or cells with unexpected content - * appearing within them. Here is an example of how to properly override the - * updateItem method: - * - *

-         * protected void updateItem(T item, boolean empty) {
-         *     super.updateItem(item, empty);
-         *
-         *     if (empty || item == null) {
-         *         setText(null);
-         *         setGraphic(null);
-         *     } else {
-         *         setText(item.toString());
-         *     }
-         * }
-         * 
- * - *

Note in this code sample two important points: - *

    - *
  1. We call the super.updateItem(T, boolean) method. If this is not - * done, the item and empty properties are not correctly set, and you are - * likely to end up with graphical issues.
  2. - *
  3. We test for the empty condition, and if true, we - * set the text and graphic properties to null. If we do not do this, - * it is almost guaranteed that end users will see graphical artifacts - * in cells unexpectedly.
  4. - *
- * @param item The new item for the cell. - * - * @param empty whether or not this cell represents data from the list. If - * it is empty, then it does not represent any domain data, but - * is a cell - */ - @Override - protected void updateItem(LobbyListItem item, boolean empty) { - super.updateItem(item, empty); - if (empty) { - setText(null); - setGraphic((null)); - } else { - LOGGER.debug("In ELSE part of LobbyView Update item()"); - lobbyID.setText(item.getLobbyID()); - adminName.setText(item.getAdminName()); - startOrJoin.setOnAction(event -> { - if (item.isOwnedByClient()) { - startGame(); - } else { - joinGame(item.lobbyIDProperty().getValue()); - } - }); - startOrJoin.setText(item.isOwnedByClient() ? "Start" : "Join"); - lobbyID.setTextFill(Color.BLACK); - adminName.setTextFill(Color.BLACK); - startOrJoin.setTextFill(Color.BLACK); - setGraphic(head); - } - } - }; - return cell; - }); Platform.runLater(new Runnable() { @Override public void run() { - //TODO(SERAINA): bgAnimation? + ImageView bgAnimationView = new ImageView(); + bgAnimationView.setFitHeight(1950); + bgAnimationView.setFitWidth(6667.968); } }); - LOGGER.debug("In Initialize 3 LobbyListView" + LobbyListView); - LobbyListView.setPlaceholder(new Text("No open lobbies!")); - LobbyListView.setVisible(true); } /** @@ -287,8 +166,10 @@ public class LoungeSceneViewController implements Initializable { public void run() { try { LOGGER.debug(" in GameView()" + chatApp); - buttonLobbyPane.setVisible(false); + allLobbyElementsBorderPane.setVisible(false); gameDisplayAnchorPane.getChildren().add(chatApp.game); + chatApp.getGameController().clearAllNoiseDisplay(); + chatApp.getGameController().clearNotificationText(); } catch (Exception e) { LOGGER.debug("Not yet initialized"); } @@ -305,7 +186,9 @@ public class LoungeSceneViewController implements Initializable { public void run() { try { trainAnimationDayController.showFullWagon(); - buttonLobbyPane.setVisible(true); + allLobbyElementsBorderPane.setVisible(true); + chatApp.getGameController().clearAllNoiseDisplay(); + chatApp.getGameController().clearNotificationText(); gameDisplayAnchorPane.getChildren().clear(); } catch (Exception e) { LOGGER.debug("Not yet initialized"); @@ -344,70 +227,6 @@ public class LoungeSceneViewController implements Initializable { }); } - /** - * Adds players to a lobby "NMEMB" {@link ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters} - * - * @param lobbyID the Id the Player belongs to - * @param player the player to be added - */ - public void addPlayerToLobby(String lobbyID, String player) { - LOGGER.debug("Lobby ID: " + lobbyID + " player: " + player); - Platform.runLater(new Runnable() { - @Override - public void run() { - Iterator itr = clients.iterator(); - while (itr.hasNext()) { - ClientListItem cl = itr.next(); - if (cl.getName().equals(player)) { - LobbyListItem li = lobbyIDtoLobbyMop.get(lobbyID); - li.getClientsInLobby().add(cl); - } - } - - } - }); - } - - /** - * Used when a new lobby shall be added to the view. "NLOBBY" {@link - * ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters} - * - * @param lobbyID the ID of the new lobby - * @param adminName the name of the Lobby admin - */ - public void newLobby(String lobbyID, String adminName) { - LobbyListView = lListView; - LOGGER.debug("In newLobby()0 LobbyListView" + lListView); - LOGGER.debug("New lobby with ID " + lobbyID + " and admin " + adminName); - SimpleStringProperty id = new SimpleStringProperty(lobbyID); - SimpleStringProperty admin = new SimpleStringProperty((adminName)); - LOGGER.debug("In newLobby()1 LobbyListView" + LobbyListView); - boolean ownedByClient = false; - if (adminName.equals(client.getUsername())) { - LOGGER.debug("Client is admin. Name: " + adminName); - ownedByClient = true; - } else { - LOGGER.debug("Different admin case. ADMIN Name: " + adminName); - } - LobbyListItem item = new LobbyListItem(id, admin, new SimpleBooleanProperty(ownedByClient), - new SimpleBooleanProperty(true), new SimpleIntegerProperty(0)); - lobbyIDtoLobbyMop.put(lobbyID, item); - LOGGER.debug("In newLobby()2 LobbyListView" + LobbyListView); - Platform.runLater(new Runnable() { - @Override - public void run() { - lobbies.add(item); - LobbyListView.getItems().add(item); - LOGGER.debug("within newLobby() run() thread"); - LOGGER.debug(item.toString()); - LOGGER.debug("In newLobby() run() " + LobbyListView); - } - }); - LOGGER.debug("newLobby() in LoungeSceneViewController seems to have reached end."); - LOGGER.debug(lobbies.toString()); - LOGGER.debug("In newLobby()3 LobbyListView" + LobbyListView); - } - /** * Send the joinLobby Protocol message * @@ -500,68 +319,13 @@ public class LoungeSceneViewController implements Initializable { for (String argument : arguments) { LOGGER.debug("HighScore " + argument); Text text = new Text(argument + System.lineSeparator()); - text.setFill(Color.BLACK); + text.setFill(Color.WHITE); + text.setFont(new Font("serif",15)); highScore.getChildren().add(text); } } }); } - /** - * Adds a String to the lobbyPrint TextFlow - * - * @param data the String to be added - */ - public void addLobbyPrint(String data) { - String[] arguments = data.split("/n"); - LOGGER.debug(arguments.length); - Platform.runLater(new Runnable() { - @Override - public void run() { - for (String argument : arguments) { - LOGGER.debug("HighScore " + argument); - Text text = new Text(argument + System.lineSeparator()); - text.setFill(Color.BLACK); - lobbyPrint.getChildren().add(text); - } - } - }); - } - - /** - * Clears the lobbyPrint TextFlow - */ - public void clearLobbyPrint() { - Platform.runLater(new Runnable() { - @Override - public void run() { - lobbyPrint.getChildren().clear(); - } - }); - } - - /** - * Should remove the lobby from the lobby list view - * - * @param data to be removed - */ - public void removeLobbyFromView(String data) { - Iterator itr = lobbies.iterator(); - while (itr.hasNext()) { - LobbyListItem item = itr.next(); - if (item.getLobbyID().equals(data)) { - Platform.runLater(new Runnable() { - @Override - public void run() { - itr.remove(); - LOGGER.debug( - "Made it into removeLobbyFromView if clause for lobby w/ ID: " + item.getLobbyID() - + " for data passed: " + data); - } - }); - - } - } - } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/utils/ChatLabelConfigurator.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/utils/ChatLabelConfigurator.java index f2fa9fe..445d061 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/utils/ChatLabelConfigurator.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/utils/ChatLabelConfigurator.java @@ -28,7 +28,7 @@ public class ChatLabelConfigurator { l.setAlignment(Pos.CENTER_RIGHT); l.setWrapText(true); l.setMaxHeight(Double.MAX_VALUE); - l.setPrefWidth(1135); + l.setPrefWidth(680); l.setScaleShape(false); } else { //t = new Text(client.getUsername() + " (you): " + msg); @@ -37,7 +37,7 @@ public class ChatLabelConfigurator { l.setAlignment(Pos.CENTER_RIGHT); l.setWrapText(true); l.setMaxHeight(Double.MAX_VALUE); - l.setPrefWidth(1135); + l.setPrefWidth(680); l.setScaleShape(false); } return l; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java index 44c3061..e7e4d21 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java @@ -212,6 +212,13 @@ public class Protocol { */ public static final String noiseNotificationProtocol = "NOISE"; + /** + * Used to tell the client to play a sound, namely the sounds for when humans have voted for a human (PLSND$HV), + * when humans have voted for a ghost (PLSND$GV), when humans have won (i.e. have voted for the OG - PLSND$HW) + * or when ghosts have won (PLSND$GW), or the train horn at the start of the game (PLSND$TH). Not used for ghost sounds. + */ + public static final String playSound = "PLSND"; + /** * Sends an information to client at which position in the train from the game (0 to 5) they sit, as soon as the game starts * {@code POSOF$position} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java index 860f2fe..ac0ab0a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java @@ -129,10 +129,7 @@ public class ClientHandler implements Runnable { String helper = this.getClientUserName(); String oldName = getClientUserName(); this.clientUserName = nameDuplicateChecker.checkName(newName); - guiUpdateAll(Protocol.printToGUI + "$" + GuiParameters.nameChanged + "$" + oldName + ":" - + getClientUserName()); sendMsgToClient(Protocol.changedUserName + "$" + newName); - broadcastAnnouncementToAll(helper + " has changed their nickname to " + clientUserName); try { getLobby().getGame().getGameState().changeUsername(helper, newName); @@ -250,12 +247,6 @@ public class ClientHandler implements Runnable { } } - public static void guiUpdateAll(String msg) { - System.out.println(msg); - for (ClientHandler client : connectedClients) { - client.sendMsgToClient(msg); - } - } /** * Broadcasts a non-chat Message to all clients in the same lobby. This can be used for server @@ -415,6 +406,7 @@ public class ClientHandler implements Runnable { Thread t = new Thread(game); t.start(); l.addGameToRunningGames(game); + sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.viewChangeToGame + "$"); } else { sendAnnouncementToClient("Only the admin can start the game"); } @@ -475,9 +467,6 @@ public class ClientHandler implements Runnable { public void createNewLobby() { if (Lobby.clientIsInLobby(this) == -1) { Lobby newGame = new Lobby(this); - guiUpdateAll( - Protocol.printToGUI + "$" + GuiParameters.newLobbyCreated + "$" + getLobby().getLobbyID() - + ":" + getClientUserName()); LOGGER.debug("Lobby: " + getLobby().getLobbyID() + ". In method createNewLobby()"); } else { sendAnnouncementToClient("You are already in lobby nr. " + Lobby.clientIsInLobby(this)); @@ -495,8 +484,6 @@ public class ClientHandler implements Runnable { if (l != null) { if (l.getLobbyIsOpen()) { l.addPlayer(this); - guiUpdateAll(Protocol.printToGUI + "$" + GuiParameters.addNewMemberToLobby + "$" + i + ":" - + getClientUserName()); } else { sendAnnouncementToClient("The game in Lobby " + l.getLobbyID() + " has already started, or the lobby is already full."); @@ -517,8 +504,6 @@ public class ClientHandler implements Runnable { l.removePlayer(this); Game game = l.getGame(); if(l.getAdmin().equals(getClientUserName())){ - //Lobby closed because admin left. Lobby must be removed from gui view - guiUpdateAll(Protocol.printToGUI+"$"+GuiParameters.removeLobby+"$"+l.getLobbyID()); }else{ //client just leaves lobby } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java index e5c8416..09991b2 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java @@ -65,8 +65,6 @@ public class JServerProtocolParser { } catch (Exception e) { h.setUsernameOnLogin("U.N. Owen"); } - h.guiUpdateAll(Protocol.printToGUI + "$" + GuiParameters.newPlayerOnServer + "$" - + h.getClientUserName()); break; case Protocol.nameChange: h.changeUsername(msg.substring(6)); @@ -92,9 +90,6 @@ public class JServerProtocolParser { break; case Protocol.createNewLobby: h.createNewLobby(); - h.guiUpdateAll( - Protocol.printToGUI + "$" + GuiParameters.newLobbyCreated + "$" + h.getLobby() - .getLobbyID() + ":" + h.getClientUserName()); LOGGER.info("Here"); break; case Protocol.listLobbies: @@ -115,7 +110,6 @@ public class JServerProtocolParser { break; case Protocol.startANewGame: h.startNewGame(); - h.sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.viewChangeToGame + "$"); break; case Protocol.listGames: h.listGames(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/LobbyUpdater.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/LobbyUpdater.java index d6d4fd6..32c198c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/LobbyUpdater.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/LobbyUpdater.java @@ -1,6 +1,7 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.server; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.highscore.OgGhostHighScore; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ServerPinger; @@ -18,15 +19,25 @@ public class LobbyUpdater implements Runnable{ public void run() { while (true) { try { - Thread.sleep(3000); + Thread.sleep(1000); } catch (InterruptedException e) { LOGGER.warn(e.getMessage()); } String lobbiesAsString = Lobby.lobbiesToString(); for (ClientHandler client : ClientHandler.getConnectedClients()) { + String list = OgGhostHighScore.formatGhostHighscoreList(); + String[] listarray = list.split("\\R"); + StringBuilder forGui = new StringBuilder(); + for (String s : listarray) { + forGui.append(s).append("/n"); + } + client.sendMsgToClient(Protocol.printToGUI + "$" + GuiParameters.updateHighScore + "$" + forGui.toString()); if (!Lobby.lobbies.isEmpty()) { client.sendMsgToClient( Protocol.printToGUI + "$" + GuiParameters.updateLobbyString + "$" + lobbiesAsString); + } else{ + client.sendMsgToClient( + Protocol.printToGUI + "$" + GuiParameters.updateLobbyString + "$"); } } } diff --git a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/Chat.css b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/Chat.css index 996b07e..5cefda2 100644 --- a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/Chat.css +++ b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/Chat.css @@ -3,6 +3,17 @@ -fx-background-color: transparent; } +.text-flow{ + -fx-text-alignment: center; +} + +.separator *.line { + -fx-border-style: solid; + -fx-border-color: rgb(90,69,51); + -fx-background-color: rgb(90,69,51); + -fx-effect: none; +} + #vBoxChatMessages{ -fx-background-color: transparent; } diff --git a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/ChatView.fxml b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/ChatView.fxml index d0dc006..4525edf 100644 --- a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/ChatView.fxml +++ b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/chat/ChatView.fxml @@ -4,6 +4,7 @@ + @@ -14,16 +15,16 @@ - + - + - + @@ -32,18 +33,18 @@ - + - + - + - + - - - + + + @@ -61,7 +62,7 @@ - + @@ -108,5 +109,11 @@ + + + + + + diff --git a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameDay.css b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameDay.css index 65a90d2..18ecce3 100644 --- a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameDay.css +++ b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameDay.css @@ -9,16 +9,23 @@ .button:pressed{ -fx-background-color: transparent; - -fx-border-color: transparent; + -fx-boarder-color: lightgrey; } #noiseButton{ - -fx-background-color: midnightblue; + -fx-background-color: rgb(15,26,59); + -fx-background-image: url(bell.jpg); + -fx-background-size: 100%; -fx-text-fill: lightgrey; } +#noiseButton:hover{ + -fx-effect: innershadow(gaussian, lightsteelblue, 10, 0.5 , 2, 2); +} + #noiseButton:pressed{ - -fx-background-color: midnightblue; + -fx-background-image: url(bellPressed.jpg); + -fx-background-size: 100%; -fx-text-fill: lightgrey; } @@ -27,6 +34,7 @@ } + .textField{ -fx-text-fill: white; -fx-background-color: transparent; diff --git a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameDayAll.fxml b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameDayAll.fxml index af1e173..11e64e9 100644 --- a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameDayAll.fxml +++ b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/GameDayAll.fxml @@ -49,7 +49,7 @@ - + @@ -91,11 +91,12 @@ - - + + + diff --git a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/bell.jpg b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/bell.jpg new file mode 100644 index 0000000..05d26e5 Binary files /dev/null and b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/bell.jpg differ diff --git a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/bellPressed.jpg b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/bellPressed.jpg new file mode 100644 index 0000000..0f9ca7d Binary files /dev/null and b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/bellPressed.jpg differ diff --git a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/images/bell.png b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/images/bell.png new file mode 100644 index 0000000..05d26e5 Binary files /dev/null and b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/images/bell.png differ diff --git a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/images/buttonpressed2.png b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/images/buttonpressed2.png new file mode 100644 index 0000000..ed00974 Binary files /dev/null and b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/images/buttonpressed2.png differ diff --git a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/ListOfLobbiesScrollPane.fxml b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/ListOfLobbiesScrollPane.fxml index f34c759..fb591cf 100644 --- a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/ListOfLobbiesScrollPane.fxml +++ b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/ListOfLobbiesScrollPane.fxml @@ -4,11 +4,11 @@ - + - + - + diff --git a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LobbiesBorderPane.css b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LobbiesBorderPane.css new file mode 100644 index 0000000..4cf3957 --- /dev/null +++ b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LobbiesBorderPane.css @@ -0,0 +1,41 @@ +*{ + -fx-background-color: transparent; + -fx-text-fill: white; + -fx-font-family: serif; +} + + +.border-pane{ + -fx-background-color: rgb(15,26,59,0.8); + -fx-border-color: rgb(204,186,138); + -fx-border-width: 10; +} + +.tool-bar{ + -fx-background-color: rgb(15,26,59,0.8); +} + +#highScorePane{ + -fx-background-color: rgb(15,26,59,0.8); + -fx-text-fill: white; + -fx-font-family: serif; +} + +#listTilePane{ + -fx-background-color: rgb(15,26,59,0.8) +} + +.button{ + -fx-background-color: rgb(204,186,138); + -fx-effect: innershadow(gaussian, rgb(142,121,89), 10, 0.5 , 2, 2); + -fx-text-fill: black; +} + +.button:pressed{ + -fx-background-color: rgb(90,69,51); + -fx-text-fill: rgb(197,177,131); +} + +.button:hover{ + -fx-effect: innershadow(gaussian, rgb(90,69,51), 10, 0.5 , 2, 2); +} \ No newline at end of file diff --git a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LoungeSceneView.fxml b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LoungeSceneView.fxml index d7edc81..3855bc6 100644 --- a/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LoungeSceneView.fxml +++ b/src/main/resources/ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/lounge/LoungeSceneView.fxml @@ -2,7 +2,6 @@ - @@ -16,8 +15,6 @@ -