Merge remote-tracking branch 'origin/master'

This commit is contained in:
Sebastian Lenzlinger 2022-05-18 13:40:41 +02:00
commit 2429844ec6
62 changed files with 646 additions and 647 deletions

View File

@ -366,3 +366,6 @@ Habe Highscore und Players in Lobbies auf die einfachst mögliche Art mit Textfl
16.5.2022 - Jonas 16.5.2022 - Jonas
Have been working on implementing all sound effects over the last couple of days 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.

BIN
Meilenstein V/Slides.pdf Normal file

Binary file not shown.

BIN
Meilenstein V/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

View File

@ -6,3 +6,8 @@ serai
serai serai
serai serai
serai serai
Jonas
Jonas
Jonas
Jonas, the French delegate
Jonas

View File

@ -12,7 +12,7 @@ javafx {
} }
group 'ch.unibas.dmi.dbis' group 'ch.unibas.dmi.dbis'
version '0.0.2'
mainClassName = 'ch.unibas.dmi.dbis.cs108.NightTrainToBudapest' mainClassName = 'ch.unibas.dmi.dbis.cs108.NightTrainToBudapest'
java { java {

View File

@ -1,8 +1,8 @@
game.name = Example Game game.name = Night Train to Budapest
game.command = java -jar exampleGame.jar game.command = java -jar NightTrainToBudapest.jar
game.description.file = index.html game.description.file = index.html
game.screenshot.file = example.png game.screenshot.file = example.png
game.server.command = java -jar exampleGame.jar game.server.command = java -jar NightTrainToBudapest.jar
game.use = true game.use = true
game.year = 2020 game.year = 2022
game.developers = Tom Cat, Jerry Mouse, William Hanna, Joseph Barbera game.developers = Seraina Schöb, Jonas Biedermann, Sebastian Lenzlinger, Alexandr Sazonov

View File

@ -1,14 +1,14 @@
<html> <html>
<!-- Dies ist ein html Kommentar --> <!-- Dies ist ein html Kommentar -->
<!-- Ändert in diesem File sämtliche Platzhalter, wie z.B. den Spielnamen in der nächsten Linie --> <!-- Ändert in diesem File sämtliche Platzhalter, wie z.B. den Spielnamen in der nächsten Linie -->
<head><title>Example Game</title><link rel="stylesheet" href="main.css"></head> <head><title>Night Train to Budapest</title><link rel="stylesheet" href="main.css"></head>
<body> <body>
<!-- Header nicht verändern --> <!-- Header nicht verändern -->
<header class="site-header"><div class="wrapper"><a class="site-title" href="/cs108/">Programmierprojekt - Computerspiele</a></div></header><div class="page-content"><div class="wrapper"><div class="home"> <header class="site-header"><div class="wrapper"><a class="site-title" href="/cs108/">Programmierprojekt - Computerspiele</a></div></header><div class="page-content"><div class="wrapper"><div class="home">
<h1>Example Game</h1> <h1>Night Train to Budapest</h1>
Hier k&ouml;nnt ihr einen Satz &uuml;ber euer Spiel sagen. Tief im &ouml;sterreichischen Wald rast ein Nachtzug richtung Budapest - doch unter den Passagieren scheint etas b&ouml;ses zu lauern... <br/>
<!-- Dieser Block ist dafür verantwortlich, den Trailer / das Gameplay Video und euren Screenshot einzubauen. Verändert ihn nicht, sondern überschreibt einfach die Dateien --> <!-- Dieser Block ist dafür verantwortlich, den Trailer / das Gameplay Video und euren Screenshot einzubauen. Verändert ihn nicht, sondern überschreibt einfach die Dateien -->
<br> <br>
@ -28,26 +28,20 @@ Hier k&ouml;nnt ihr einen Satz &uuml;ber euer Spiel sagen.
<h3>Entwickler:</h3> <h3>Entwickler:</h3>
<ul> <ul>
<li> Edgar Codd </li> <li> Seraina Sch&ouml;b </li>
<li> Lynn Conway </li> <li> Jonas Biedermann </li>
<li> Ada Lovelace </li> <li> Sebastian Lenzlinger </li>
<li> Alan Turing </li> <li> Alexandr Sazonov </li>
</ul> </ul>
<!-- Nachfolgend sollt ihr die Tasten angeben, welche man braucht um euer Spiel zu Spielen. Um weitere Tasten hinzuzufügen könnt Ihr einfach eine Zeile kopieren und den Buchstaben oder das Wort zwischen <i>Beispiel:</i> ändern. --> <!-- Nachfolgend sollt ihr die Tasten angeben, welche man braucht um euer Spiel zu Spielen. Um weitere Tasten hinzuzufügen könnt Ihr einfach eine Zeile kopieren und den Buchstaben oder das Wort zwischen <i>Beispiel:</i> ändern. -->
<h2>Steuerung:</h2> <h2>Steuerung:</h2>
<i>Pfeiltasten:</i> bewegen<br/> Das Spiel wird mit der Maus gespielt. <br/>
<i>Leertaste:</i> springen<br/> <i>Enter:</i> Chatnachricht senden<br/>
<i>I:</i> Inventar<br/>
<i>Esc:</i> Spiel beenden<br/>
<i>P:</i> Spiel pausieren
<!-- Falls ihr noch zusätzliche Informationen wie Items oder andere Erklärungen angeben wollt, könnt Ihr das wie nachfolgend machen. --> <!-- Falls ihr noch zusätzliche Informationen wie Items oder andere Erklärungen angeben wollt, könnt Ihr das wie nachfolgend machen. -->
<h2>Inventar:</h2>
<i>Eisblock:</i> Gegner k&ouml;nnen sich nicht mehr bewegen<br/>
<i>Schwarzes Loch:</i> Steuerung der Gegner wird invertiert
</div></div></div></div></body> </div></div></div></div></body>
</html> </html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

View File

@ -23,16 +23,16 @@ public class ClientGameInfoHandler {
public static final String gameOverGhostsWin = "Game over, ghosts win!"; public static final String gameOverGhostsWin = "Game over, ghosts win!";
//relevant for gui //relevant for gui
public static final String itsNightTime = "Please wait, ghosts are active"; public static final String itsNightTime = "Listen closely, ghosts are active...";
public static final String itsDayTime = "Please wait, humans are active"; public static final String itsDayTime = "The humans are looking for you!";
//just messages //just messages
public static final String youGotGhostyfied = "You are now a ghost!"; 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 youGotKickedOff = "Bye bye - you've been kicked off.";
public static final String humansVotedFor = "Humans voted for: "; public static final String humansVotedFor = "Humans voted for ";
public static final String isAHuman = " but they're a human!"; 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 gotKickedOff = " is a Ghost and got kicked off.";
public static final String gotGhostyfied = " is now also a ghost!"; public static final String gotGhostyfied = " is now also a ghost!";

View File

@ -122,6 +122,10 @@ public class Game implements Runnable {
LOGGER.info(gameState.toGhostString()); LOGGER.info(gameState.toGhostString());
for (ClientHandler client : lobbyClients) {//begins filling the train with clients 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]; int index = order[i];
if (passengerTrain[index].getIsGhost()) { //if there is a ghost if (passengerTrain[index].getIsGhost()) { //if there is a ghost
GhostPlayer ghostPlayer = new GhostPlayer(passengerTrain[index].getPosition(), GhostPlayer ghostPlayer = new GhostPlayer(passengerTrain[index].getPosition(),
@ -172,6 +176,14 @@ public class Game implements Runnable {
if (gameOverCheck.equals(ClientGameInfoHandler.gameOverGhostsWin) && getOgGhost().getIsPlayer()) { if (gameOverCheck.equals(ClientGameInfoHandler.gameOverGhostsWin) && getOgGhost().getIsPlayer()) {
OgGhostHighScore.addOgGhostWinner(getOgGhost().getName()); 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); lobby.getAdmin().broadcastAnnouncementToLobby(gameOverCheck);
isOngoing = false; isOngoing = false;
Timer.ghostAfterVoteTimer(); Timer.ghostAfterVoteTimer();

View File

@ -52,6 +52,7 @@ public class GameState {
for (int i = 0; i < nrOfPlayers; i++) { for (int i = 0; i < nrOfPlayers; i++) {
if (i == train.getPositionOfGhost()) { if (i == train.getPositionOfGhost()) {
LOGGER.info("OG position: " + train.getOrderOfTrain()[i]); LOGGER.info("OG position: " + train.getOrderOfTrain()[i]);
System.out.println("Og-Ghost Position: " + train.getOrderOfTrain()[i]);
Ghost g = new Ghost(); Ghost g = new Ghost();
g.setPosition(train.getOrderOfTrain()[i]); g.setPosition(train.getOrderOfTrain()[i]);
g.setGhost(); g.setGhost();

View File

@ -24,11 +24,11 @@ public class NoiseHandler {
public int[] noiseNotifier(Passenger predator, Passenger victim, int[] noiseAmount) { public int[] noiseNotifier(Passenger predator, Passenger victim, int[] noiseAmount) {
if (predator.getPosition() - victim.getPosition() if (predator.getPosition() - victim.getPosition()
> 0) { // if predator is to the right of victim > 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]++; noiseAmount[i]++;
} }
} else { // if predator is to the left of victim } 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]++; noiseAmount[i]++;
} }
} }

View File

@ -121,14 +121,13 @@ public class ServerGameInfoHandler {
case ClientGameInfoHandler.noiseNotification + 4 + " time(s)": case ClientGameInfoHandler.noiseNotification + 4 + " time(s)":
case ClientGameInfoHandler.noiseNotification + 5 + " time(s)": case ClientGameInfoHandler.noiseNotification + 5 + " time(s)":
case ClientGameInfoHandler.noiseNotification: case ClientGameInfoHandler.noiseNotification:
//todo: jonas: handle bell behaviour correctly.
String outMsg = npc.getName() + ": " + noiseRandomizer();
//TODO: add likelyhood
if(!npc.getKickedOff()) { if(!npc.getKickedOff()) {
game.getLobby().getAdmin().broadcastNpcChatMessageToLobby(outMsg); if (Math.random() < GhostNPC.probabilityToRingAlarmIfHeardNoise) {
game.getLobby().getAdmin().sendMsgToClientsInLobby( game.getLobby().getAdmin().sendMsgToClientsInLobby(
Protocol.printToGUI + "$" + GuiParameters.noiseHeardAtPosition Protocol.printToGUI + "$" + GuiParameters.noiseHeardAtPosition
+ "$" + npc.getPosition()); + "$" + npc.getPosition());
}
} }
break; break;
case ClientGameInfoHandler.ghostVoteRequest: case ClientGameInfoHandler.ghostVoteRequest:
@ -151,13 +150,13 @@ public class ServerGameInfoHandler {
case ClientGameInfoHandler.noiseNotification + 4 + " time(s)": case ClientGameInfoHandler.noiseNotification + 4 + " time(s)":
case ClientGameInfoHandler.noiseNotification + 5 + " time(s)": case ClientGameInfoHandler.noiseNotification + 5 + " time(s)":
case ClientGameInfoHandler.noiseNotification: //new case where times are not noted. case ClientGameInfoHandler.noiseNotification: //new case where times are not noted.
//todo: jonas: handle bell behaviour correctly.
String outMsg = npc.getName() + ": " + noiseRandomizer();
if(!npc.getKickedOff()) { if(!npc.getKickedOff()) {
game.getLobby().getAdmin().broadcastNpcChatMessageToLobby(outMsg); if (Math.random() < HumanNPC.probabilityToRingAlarmIfHeardNoise) {
game.getLobby().getAdmin().sendMsgToClientsInLobby( game.getLobby().getAdmin().sendMsgToClientsInLobby(
Protocol.printToGUI + "$" + GuiParameters.noiseHeardAtPosition Protocol.printToGUI + "$" + GuiParameters.noiseHeardAtPosition
+ "$" + npc.getPosition()); + "$" + npc.getPosition());
}
} }
break; break;
case ClientGameInfoHandler.humanVoteRequest: case ClientGameInfoHandler.humanVoteRequest:

View File

@ -16,23 +16,23 @@ public class Timer {
/** /**
* The maximum length of the ghost vote in the night, in seconds * 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 / * 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. * 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 * 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, * The length of time in seconds after the human vote, as the 'winner' of the vote is announced,
* before the night begins * before the night begins
*/ */
public static final int humanAfterVoteTime = 5; public static final int humanAfterVoteTime = 8;
/** /**
* The checking interval in seconds * The checking interval in seconds

View File

@ -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.gamelogic.klassenstruktur.Passenger;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters; 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.Protocol;
import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -88,7 +89,7 @@ public class VoteHandler {
ghostification. */ ghostification. */
int[] noiseAmount = new int[6]; int[] noiseAmount = new int[6];
for (int i = 0; i < passengers.length; i++) { 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(); NoiseHandler n = new NoiseHandler();
noiseAmount = n.noiseNotifier(passengers[i], g, noiseAmount); 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 .getIsGhost()) { // if player with most votes is human, notify everyone about it
for (Passenger passenger : passengers) { for (Passenger passenger : passengers) {
passenger.send( 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].getIsGhost()) { // if player is a ghost
if (passengers[voteIndex].getIsOG()) { // if ghost is OG --> end game, humans win 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); System.out.println(ClientGameInfoHandler.gameOverHumansWin);
return ClientGameInfoHandler.gameOverHumansWin; return ClientGameInfoHandler.gameOverHumansWin;
} else { } else {
@ -200,6 +213,8 @@ public class VoteHandler {
} }
} }
} }
Timer.humanAfterVoteTimer();
LOGGER.info(game.getGameState().toString()); LOGGER.info(game.getGameState().toString());
// set hasVoted to false for all passengers for future voting // set hasVoted to false for all passengers for future voting
for (Passenger passenger : passengers) { for (Passenger passenger : passengers) {

View File

@ -9,6 +9,7 @@ import org.apache.logging.log4j.Logger;
public class GhostNPC extends Ghost { public class GhostNPC extends Ghost {
public static final Logger LOGGER = LogManager.getLogger(GhostNPC.class); public static final Logger LOGGER = LogManager.getLogger(GhostNPC.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER); 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. * Creates a new GhostNPC. Should be used at game start or if a HumanNPC is turned into a ghost.

View File

@ -1,6 +1,7 @@
package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig; 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.ClientVoteData;
import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import ch.unibas.dmi.dbis.cs108.gamelogic.Game;
import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; 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 Logger LOGGER = LogManager.getLogger(GhostPlayer.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER); 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 * Creates a new GhostPlayer. Should be used at game start or if a HumanPlayer is turned into a
* ghost. * ghost.
@ -48,6 +50,8 @@ public class GhostPlayer extends Ghost {
String formattedMsg; String formattedMsg;
if (msg.equals(GuiParameters.updateGameState)) { if (msg.equals(GuiParameters.updateGameState)) {
formattedMsg = Protocol.printToGUI + "$" + GuiParameters.updateGameState + game.getGameState().toGhostString(); formattedMsg = Protocol.printToGUI + "$" + GuiParameters.updateGameState + game.getGameState().toGhostString();
} else if (msg.equals(ClientGameInfoHandler.noiseNotification)) {
formattedMsg = Protocol.noiseNotificationProtocol;
} else { } else {
formattedMsg = ServerGameInfoHandler.format(msg, this, game); formattedMsg = ServerGameInfoHandler.format(msg, this, game);
} }

View File

@ -10,6 +10,7 @@ public class HumanNPC extends Human {
public static final Logger LOGGER = LogManager.getLogger(HumanNPC.class); public static final Logger LOGGER = LogManager.getLogger(HumanNPC.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER); public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
public static final double probabilityToRingAlarmIfHeardNoise = 0.9;
/** /**
* Creates a new HumanNPC. * Creates a new HumanNPC.

View File

@ -1,8 +1,10 @@
package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig; 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.Game;
import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; 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.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -29,6 +31,11 @@ public class Spectator extends Passenger{
*/ */
@Override @Override
public void send(String msg, Game game) { 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));
}
} }
} }

View File

@ -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.Sprites;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatController; 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.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.LobbyDisplayHandler;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeApp; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeSceneViewController; 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()); LOGGER.warn("Not a position given for noise " + e.getMessage());
} }
break; break;
case GuiParameters.listOfLobbies:
updateListOfLobbies(data);
//TODO
break;
case GuiParameters.VoteIsOver: case GuiParameters.VoteIsOver:
chatApp.getGameController().setNoiseButtonInvisible(); chatApp.getGameController().setNoiseButtonInvisible();
chatApp.getGameController().clearAllNoiseDisplay(); chatApp.getGameController().clearAllNoiseDisplay();
dayNightChangeListener.setNoiseButtonInvisible(true); dayNightChangeListener.setNoiseButtonInvisible(true);
break; break;
case GuiParameters.getMembersInLobby:
updateLobbyMembers(data);
break;
case GuiParameters.viewChangeToGame: case GuiParameters.viewChangeToGame:
chatApp.getLoungeSceneViewController().addGameView(); chatApp.getLoungeSceneViewController().addGameView();
gameStateModel.setGameOver(false); gameStateModel.setGameOver(false);
dayNightChangeListener = new DayNightChangeListener(gameStateModel, chatApp, Integer.MAX_VALUE); dayNightChangeListener = new DayNightChangeListener(gameStateModel, chatApp, Integer.MAX_VALUE);
ListOfLobbiesController.setGameOngoing(true);
new Thread(dayNightChangeListener).start(); new Thread(dayNightChangeListener).start();
break; break;
case GuiParameters.viewChangeToLobby: case GuiParameters.viewChangeToLobby:
chatApp.getLoungeSceneViewController().removeGameView(); chatApp.getLoungeSceneViewController().removeGameView();
gameStateModel.setGameOver(true); gameStateModel.setGameOver(true);
//TODO ListOfLobbiesController.setGameOngoing(false);
break;
case GuiParameters.addNewMemberToLobby:
addPlayerToLobby(data);
break;
case GuiParameters.newLobbyCreated:
makeNewLobby(data);
break; break;
case GuiParameters.updateHighScore: case GuiParameters.updateHighScore:
chatApp.getLoungeSceneViewController().addHighScore(data); chatApp.getLoungeSceneViewController().addHighScore(data);
@ -408,16 +397,17 @@ public class Client {
case GuiParameters.yourPosition: case GuiParameters.yourPosition:
dayNightChangeListener.setPosition(Integer.parseInt(data)); dayNightChangeListener.setPosition(Integer.parseInt(data));
break; break;
case GuiParameters.updatePrintLobby:
chatApp.getLoungeSceneViewController().clearLobbyPrint();
chatApp.getLoungeSceneViewController().addLobbyPrint(data);
break;
case GuiParameters.removeLobby:
removeLobbyFromGui(data);
break;
case GuiParameters.updateLobbyString: case GuiParameters.updateLobbyString:
lobbyDisplayHandler.updateLobbies(data); if(!data.isEmpty()) {
ChatApp.getListController().updateList(); lobbyDisplayHandler.updateLobbies(data);
if(!ListOfLobbiesController.isGameOngoing()) {
ChatApp.getListController().updateList();
}
} else {
if(!ListOfLobbiesController.isGameOngoing()) {
ChatApp.getListController().clearVBox();
}
}
break; break;
default: default:
notificationTextDisplay(data); 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<SimpleStringProperty> 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 * Starts a new thread, thad adds a message to notificationText in the gameController, waits 3
* seconds and deletes it again. * seconds and deletes it again.
@ -476,7 +430,11 @@ public class Client {
public void notificationTextDisplay(String data) { public void notificationTextDisplay(String data) {
new Thread(() -> { new Thread(() -> {
try { 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); Thread.sleep(5000);
chatApp.getGameController().clearNotificationText(); chatApp.getGameController().clearNotificationText();
} catch (InterruptedException e) { } catch (InterruptedException e) {

View File

@ -91,6 +91,27 @@ public class JClientProtocolParser {
case Protocol.noiseNotificationProtocol: case Protocol.noiseNotificationProtocol:
Sound.ghost(); Sound.ghost();
break; 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: default:
System.out.println("Received unknown command: " + msg); System.out.println("Received unknown command: " + msg);
} }

View File

@ -17,6 +17,9 @@ public class Sound {
static URL bellURL = Sound.class.getResource("sounds/bell.wav"); static URL bellURL = Sound.class.getResource("sounds/bell.wav");
static AudioClip bell = new AudioClip(bellURL.toString()); 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 URL daynoisesURL = Sound.class.getResource("sounds/daynoises.wav");
static AudioClip daynoises = new AudioClip(daynoisesURL.toString()); static AudioClip daynoises = new AudioClip(daynoisesURL.toString());
@ -41,6 +44,32 @@ public class Sound {
static URL ghost04URL = Sound.class.getResource("sounds/ghost04.wav"); static URL ghost04URL = Sound.class.getResource("sounds/ghost04.wav");
static AudioClip ghost04 = new AudioClip(ghost04URL.toString()); 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 URL musicdayURL = Sound.class.getResource("sounds/music_day.wav");
static AudioClip musicday = new AudioClip(musicdayURL.toString()); static AudioClip musicday = new AudioClip(musicdayURL.toString());
@ -77,6 +106,8 @@ public class Sound {
bell.play(defaultvolume - 0.5); bell.play(defaultvolume - 0.5);
} }
public static void trainhorn() {trainhorn.play(defaultvolume); }
public static void startDaynoises() { public static void startDaynoises() {
daynoises.setCycleCount(AudioClip.INDEFINITE); daynoises.setCycleCount(AudioClip.INDEFINITE);
daynoises.play(defaultvolume - 0.5); daynoises.play(defaultvolume - 0.5);
@ -95,9 +126,28 @@ public class Sound {
nightnoises.stop(); 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() { public static void musicday() {
musicday.play(defaultvolume); musicday.play(defaultvolume);
@ -109,8 +159,9 @@ public class Sound {
} }
public static void ghost() { public static void ghost() {
double playbackspeed = (Math.random() / 5.0) + 0.9; //double playbackspeed = (Math.random() / 5.0) + 0.9; causes aliasing artefacts :/
int ghostsoundnr = random.nextInt(4) + 1; double playbackspeed = 1;
int ghostsoundnr = random.nextInt(12) + 1;
System.out.println(ghostsoundnr); System.out.println(ghostsoundnr);
AudioClip ghost; AudioClip ghost;
switch (ghostsoundnr) { switch (ghostsoundnr) {
@ -123,13 +174,57 @@ public class Sound {
case 3: case 3:
ghost = ghost03; ghost = ghost03;
break; break;
default: case 4:
ghost = ghost04; ghost = ghost04;
break; 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();
}
} }

View File

@ -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.game.GameController;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.ListOfLobbiesController; 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.client.gui.lounge.LoungeSceneViewController;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
import java.net.URL; import java.net.URL;
import java.util.Objects; import java.util.Objects;
import javafx.application.Application; import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -208,6 +211,9 @@ public class ChatApp extends Application {
Scene scene = new Scene(lounge); Scene scene = new Scene(lounge);
scene.setRoot(lounge); scene.setRoot(lounge);
primaryStage.setScene(scene); primaryStage.setScene(scene);
scene.getWindow().setOnCloseRequest((WindowEvent we) -> {
clientModel.getClient().sendMsgToServer(Protocol.clientQuitRequest);
});
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -217,7 +223,11 @@ public class ChatApp extends Application {
primaryStage.setResizable(true); primaryStage.setResizable(true);
primaryStage.setMaximized(true); primaryStage.setMaximized(true);
primaryStage.show(); primaryStage.show();
} }
public static void main(String[] args) { public static void main(String[] args) {
launch(args); launch(args);

View File

@ -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; 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 { public class DayNightChangeListener implements Runnable {
@ -63,7 +63,7 @@ public class DayNightChangeListener implements Runnable {
chatApp.getGameController().updateRoomLabels(); chatApp.getGameController().updateRoomLabels();
gameStateModel.setRoleFromPosition(position); gameStateModel.setRoleFromPosition(position);
try { try {
Thread.sleep(100); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -21,12 +21,15 @@ import javafx.scene.control.Button;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane; import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Background; import javafx.scene.layout.Background;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; 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 Logger LOGGER = LogManager.getLogger(ChatController.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER); 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 @FXML
private Group vboxGroup; private Group vboxGroup;
@ -109,6 +121,20 @@ public class ChatController implements Initializable {
ChatScrollPane.setVvalue((Double) newValue); ChatScrollPane.setVvalue((Double) newValue);
} }
}); });
vBoxServer.heightProperty().addListener(new ChangeListener<>() {
/**
* TODO: implement
* Adjust the height when new messages come in.
*/
@Override
public void changed(ObservableValue<? extends Number> 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 * Initialize what happens when the send button is pressed
*/ */
@ -186,11 +212,12 @@ public class ChatController implements Initializable {
l.setMaxHeight(Double.MAX_VALUE); l.setMaxHeight(Double.MAX_VALUE);
if (msg.contains("whispers")) { if (msg.contains("whispers")) {
l.setBackground(Background.fill(Color.TRANSPARENT)); l.setBackground(Background.fill(Color.TRANSPARENT));
l.setPrefWidth(1135); l.setTextFill(Color.rgb(15,26,150));
l.setPrefWidth(680);
l.setScaleShape(false); l.setScaleShape(false);
} else { } else {
l.setBackground(Background.fill(Color.TRANSPARENT)); l.setBackground(Background.fill(Color.TRANSPARENT));
l.setPrefWidth(1135); l.setPrefWidth(680);
l.setScaleShape(false); l.setScaleShape(false);
} }
l.setTextFill(Color.BLACK); 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());
}
}
} }

View File

@ -1,12 +1,17 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game; package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import javafx.animation.Interpolator; import javafx.animation.Interpolator;
import javafx.animation.Transition; import javafx.animation.Transition;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.util.Duration; import javafx.util.Duration;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class BellAnimation extends Transition { public class BellAnimation extends Transition {
public static final Logger LOGGER = LogManager.getLogger(BellAnimation.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
ImageView imageView; ImageView imageView;
Image[] bells; Image[] bells;
int index; int index;
@ -23,9 +28,13 @@ public class BellAnimation extends Transition {
@Override @Override
protected void interpolate(double frac) { protected void interpolate(double frac) {
if(index < 17) { try {
imageView.setImage(bells[index]); if (index < 17) {
imageView.setImage(bells[index]);
}
index++;
} catch (Exception e) {
LOGGER.warn(e.getMessage());
} }
index++;
} }
} }

View File

@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game;
import static javafx.scene.AccessibleRole.PARENT; 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.Sound;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp; import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.GameStateModel; 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.Node;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane; 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 Logger LOGGER = LogManager.getLogger(GameController.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER); public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
static boolean justRangBell = false; //used to track if the bell has been rung recently 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 static boolean playingDayNoises = true; //true if playing day noises, false if playing night noises
private static ClientModel client; private static ClientModel client;
@ -380,8 +382,8 @@ public class GameController implements Initializable {
public void addMessageToNotificationText(String msg) { public void addMessageToNotificationText(String msg) {
LOGGER.trace("addMessage " + msg); LOGGER.trace("addMessage " + msg);
Text notification = new Text(System.lineSeparator() + msg); Text notification = new Text(System.lineSeparator() + msg);
notification.setFill(Color.BLACK); notification.setFill(Color.WHITE);
notification.setStyle("-fx-font: 50 arial;"); notification.setStyle("-fx-font: 50 serif;");
try { try {
Platform.runLater(new Runnable() { Platform.runLater(new Runnable() {
@Override @Override
@ -428,71 +430,30 @@ public class GameController implements Initializable {
String[] roles = gameStateModel.getPassengerTrainClone()[1]; String[] roles = gameStateModel.getPassengerTrainClone()[1];
boolean[] kickedOff = gameStateModel.getKickedOff(); boolean[] kickedOff = gameStateModel.getKickedOff();
Text name0 = new Text(names[0]); Text name0 = new Text(names[0]);
name0.setStyle("-fx-font: 25 arial;"); name0.setStyle("-fx-font: 15 serif;");
name0.setFill(Color.WHITE); name0.setFill(Color.rgb(255,250,250,0.6));
name0.setEffect(new DropShadow(2.5, Color.BLACK));
Text name1 = new Text(names[1]); Text name1 = new Text(names[1]);
name1.setStyle("-fx-font: 25 arial;"); name1.setStyle("-fx-font: 15 serif;");
name1.setFill(Color.WHITE); name1.setFill(Color.rgb(255,250,250,0.6));
name1.setEffect(new DropShadow(2.5, Color.BLACK));
Text name2 = new Text(names[2]); Text name2 = new Text(names[2]);
name2.setStyle("-fx-font: 25 arial;"); name2.setStyle("-fx-font: 15 serif;");
name2.setFill(Color.WHITE); name2.setFill(Color.rgb(255,250,250,0.6));
name2.setEffect(new DropShadow(2.5, Color.BLACK));
Text name3 = new Text(names[3]); Text name3 = new Text(names[3]);
name3.setStyle("-fx-font: 25 arial;"); name3.setStyle("-fx-font: 15 serif;");
name3.setFill(Color.WHITE); name3.setFill(Color.rgb(255,250,250,0.6));
name3.setEffect(new DropShadow(2.5, Color.BLACK));
Text name4 = new Text(names[4]); Text name4 = new Text(names[4]);
name4.setStyle("-fx-font: 25 arial;"); name4.setStyle("-fx-font: 15 serif;");
name4.setFill(Color.WHITE); name4.setFill(Color.rgb(255,250,250,0.6));
name4.setEffect(new DropShadow(2.5, Color.BLACK));
Text name5 = new Text(names[5]); Text name5 = new Text(names[5]);
name5.setStyle("-fx-font: 25 arial;"); name5.setStyle("-fx-font: 15 serif;");
name5.setFill(Color.WHITE); name5.setFill(Color.rgb(255,250,250,0.6));
Text role0; name5.setEffect(new DropShadow(2.5, Color.BLACK));
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);
Platform.runLater(new Runnable() { Platform.runLater(new Runnable() {
@Override @Override
@ -500,22 +461,16 @@ public class GameController implements Initializable {
try { try {
lableRoom0.getChildren().clear(); lableRoom0.getChildren().clear();
lableRoom0.getChildren().add(name0); lableRoom0.getChildren().add(name0);
lableRoom0.getChildren().add(role0);
lableRoom1.getChildren().clear(); lableRoom1.getChildren().clear();
lableRoom1.getChildren().add(name1); lableRoom1.getChildren().add(name1);
lableRoom1.getChildren().add(role1);
lableRoom2.getChildren().clear(); lableRoom2.getChildren().clear();
lableRoom2.getChildren().add(name2); lableRoom2.getChildren().add(name2);
lableRoom2.getChildren().add(role2);
lableRoom3.getChildren().clear(); lableRoom3.getChildren().clear();
lableRoom3.getChildren().add(name3); lableRoom3.getChildren().add(name3);
lableRoom3.getChildren().add(role3);
lableRoom4.getChildren().clear(); lableRoom4.getChildren().clear();
lableRoom4.getChildren().add(name4); lableRoom4.getChildren().add(name4);
lableRoom4.getChildren().add(role4);
lableRoom5.getChildren().clear(); lableRoom5.getChildren().clear();
lableRoom5.getChildren().add(name5); lableRoom5.getChildren().add(name5);
lableRoom5.getChildren().add(role5);
} catch (Exception e) { } catch (Exception e) {
LOGGER.trace("Not yet initialized"); LOGGER.trace("Not yet initialized");
} }
@ -534,17 +489,7 @@ public class GameController implements Initializable {
try { try {
if(!gameStateModel.getKickedOff()[0]) { if(!gameStateModel.getKickedOff()[0]) {
Animation bell = new BellAnimation(noiseImage5, bells); Animation bell = new BellAnimation(noiseImage5, bells);
//wait until it's day: waitForDayThenRingBell(bell);
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();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -565,16 +510,7 @@ public class GameController implements Initializable {
try { try {
if(!gameStateModel.getKickedOff()[1]) { if(!gameStateModel.getKickedOff()[1]) {
Animation bell = new BellAnimation(noiseImage4, bells); Animation bell = new BellAnimation(noiseImage4, bells);
//wait until it's day: waitForDayThenRingBell(bell);
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();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -594,17 +530,7 @@ public class GameController implements Initializable {
try { try {
if(!gameStateModel.getKickedOff()[2]) { if(!gameStateModel.getKickedOff()[2]) {
Animation bell = new BellAnimation(noiseImage3, bells); Animation bell = new BellAnimation(noiseImage3, bells);
//wait until it's day: waitForDayThenRingBell(bell);
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();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -624,17 +550,7 @@ public class GameController implements Initializable {
try { try {
if(!gameStateModel.getKickedOff()[3]) { if(!gameStateModel.getKickedOff()[3]) {
Animation bell = new BellAnimation(noiseImage2, bells); Animation bell = new BellAnimation(noiseImage2, bells);
//wait until it's day: waitForDayThenRingBell(bell);
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();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -654,17 +570,7 @@ public class GameController implements Initializable {
try { try {
if(!gameStateModel.getKickedOff()[4]) { if(!gameStateModel.getKickedOff()[4]) {
Animation bell = new BellAnimation(noiseImage1, bells); Animation bell = new BellAnimation(noiseImage1, bells);
//wait until it's day: waitForDayThenRingBell(bell);
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();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -684,16 +590,7 @@ public class GameController implements Initializable {
try { try {
if(!gameStateModel.getKickedOff()[5]) { if(!gameStateModel.getKickedOff()[5]) {
Animation bell = new BellAnimation(noiseImage0, bells); Animation bell = new BellAnimation(noiseImage0, bells);
//wait until it's day: waitForDayThenRingBell(bell);
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();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -734,6 +631,34 @@ public class GameController implements Initializable {
ChatApp.setGameController(this); 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 * plays bell sound, but only if it hasn't been played recently, to avoid artefacts due to
* overlapping sounds * overlapping sounds

View File

@ -2,10 +2,12 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge;
import static javafx.scene.control.PopupControl.USE_COMPUTED_SIZE; 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.Client;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp; 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.client.gui.ClientModel;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; 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.Lobby;
import ch.unibas.dmi.dbis.cs108.multiplayer.server.LobbyUpdater; import ch.unibas.dmi.dbis.cs108.multiplayer.server.LobbyUpdater;
import java.net.URL; import java.net.URL;
@ -25,8 +27,13 @@ import javafx.scene.layout.Background;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ListOfLobbiesController implements Initializable { public class ListOfLobbiesController implements Initializable {
public static final Logger LOGGER = LogManager.getLogger(ListOfLobbiesController.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
@FXML @FXML
private ScrollPane backDropScrolePane; private ScrollPane backDropScrolePane;
@ -37,17 +44,30 @@ public class ListOfLobbiesController implements Initializable {
private ChatApp chatApp; //TODO: VeryImportant to set this one right! private ChatApp chatApp; //TODO: VeryImportant to set this one right!
private HashSet<TreeView> treeViews = new HashSet<TreeView>(); private HashSet<TreeView> treeViews = new HashSet<TreeView>();
private static boolean gameOngoing = false;
public void setChatApp(ChatApp chatApp) { public void setChatApp(ChatApp chatApp) {
this.chatApp = chatApp; this.chatApp = chatApp;
} }
public static void setGameOngoing(boolean gameOngoing) {
ListOfLobbiesController.gameOngoing = gameOngoing;
}
public static boolean isGameOngoing() {
return gameOngoing;
}
public void updateList() { public void updateList() {
clearVBox(); new Thread(new Runnable() {
for (LobbyModel lobby : LobbyDisplayHandler.getLobbies()) { @Override
newTreeView(lobby.getId(), lobby.getAdmin(), chatApp.getcModel().getUsername(), lobby.getMembers()); 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 lobbyId the id of the lobby
* @param admin the admin of the lobby * @param admin the admin of the lobby
* @param userName the username of the client * @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<String> members) { public void newTreeView(int lobbyId, String admin, boolean isOpen, String userName, HashSet<String> members) {
try { try {
Button button = new Button(); Button button = new Button();
if (admin.equals(userName)) { // the client of this user is the admin of this lobby if (admin.equals(userName)) { // the client of this user is the admin of this lobby
button.setOnAction(event -> startGame()); button.setOnAction(event -> startGame());
button.setText("Start"); button.setText("Start");
} else { } else if (isOpen){
button.setOnAction(event -> joinALobby(lobbyId)); button.setOnAction(event -> joinALobby(lobbyId));
button.setText("Join"); button.setText("Join");
} else {
button.setVisible(false);
} }
HBox rootHBox = new HBox(); HBox rootHBox = new HBox();
rootHBox.setPrefWidth(195); rootHBox.setPrefWidth(300);
rootHBox.setMaxHeight(20); rootHBox.setMaxHeight(45);
Label adminLabel = new Label(lobbyId + " " + admin); String statusLobby;
if (isOpen) {
statusLobby = " (open)";
} else {
statusLobby = " (closed)";
}
Label adminLabel = new Label(" Lobby " + lobbyId + ": " + admin + statusLobby);
adminLabel.setTextFill(Color.WHITE); adminLabel.setTextFill(Color.WHITE);
try {
rootHBox.getChildren().add(button);
} catch (Exception e) {
LOGGER.warn(e.getMessage());
}
rootHBox.getChildren().add(adminLabel); rootHBox.getChildren().add(adminLabel);
rootHBox.getChildren().add(button);
TreeItem<HBox> root = new TreeItem<HBox>(rootHBox); TreeItem<HBox> root = new TreeItem<HBox>(rootHBox);
root.setExpanded(true);
int i = 1;
for (String member : members) { for (String member : members) {
HBox memberBox = new HBox(); HBox memberBox = new HBox();
memberBox.setPrefWidth(195); memberBox.setPrefWidth(300);
memberBox.setMaxHeight(20); memberBox.setMaxHeight(45);
Label memberLabel = new Label(member); memberBox.setPrefHeight(USE_COMPUTED_SIZE);
Label memberLabel = new Label("- " + member);
memberLabel.setTextFill(Color.WHITE); memberLabel.setTextFill(Color.WHITE);
memberBox.getChildren().add(memberLabel); memberBox.getChildren().add(memberLabel);
root.getChildren().add(new TreeItem<HBox>(memberBox)); root.getChildren().add(new TreeItem<HBox>(memberBox));
i++;
} }
TreeView<HBox> treeView = new TreeView<>(root); TreeView<HBox> treeView = new TreeView<>(root);
treeView.setVisible(true); treeView.setVisible(true);
treeView.setPrefWidth(195); treeView.setPrefWidth(300);
treeView.setMaxHeight(USE_COMPUTED_SIZE); treeView.setMinHeight(i*45 + 10);
treeView.setPrefHeight(i*45 + 10);
treeView.setMaxHeight(i*45 + 10);
Platform.runLater(new Runnable() { Platform.runLater(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -96,7 +135,7 @@ public class ListOfLobbiesController implements Initializable {
} }
}); });
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); LOGGER.warn(e.getMessage());
} }
} }

View File

@ -11,11 +11,20 @@ public class LobbyDisplayHandler {
private static HashSet<LobbyModel> lobbies = new HashSet<>(); private static HashSet<LobbyModel> lobbies = new HashSet<>();
private static boolean threadRunning = false;
public static HashSet<LobbyModel> getLobbies() { public static HashSet<LobbyModel> getLobbies() {
return lobbies; 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 * searches lobbies for a lobby with a certain id
* @param id the int representing a Lobby id to be lookes for * @param id the int representing a Lobby id to be lookes for
@ -31,6 +40,17 @@ public class LobbyDisplayHandler {
} }
public void updateLobbies(String data) { 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 { try {
for (LobbyModel model : lobbies) { for (LobbyModel model : lobbies) {
model.setHasBeenVisited(false); model.setHasBeenVisited(false);
@ -46,7 +66,7 @@ public class LobbyDisplayHandler {
if (searchForLobbyId(id) == null) { //the lobby is new and has not been saved yet if (searchForLobbyId(id) == null) { //the lobby is new and has not been saved yet
addLobbyFromString(id, admin, isOpen, oneLobby); addLobbyFromString(id, admin, isOpen, oneLobby);
} else { // the lobby exists but might need to be updated } 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()); //System.out.println("lobby size before removal: " + lobbies.size());
@ -55,7 +75,12 @@ public class LobbyDisplayHandler {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
LOGGER.info("empty list"); LOGGER.info("empty list");
} finally {
setThreadRunning(false);
} }
}
}).start();
} }
private void addLobbyFromString(int id, String admin, boolean isOpen, String[] oneLobby) { 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()); //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"); //System.out.println("update");
LobbyModel oldLobby = searchForLobbyId(id); LobbyModel oldLobby = searchForLobbyId(id);
if (!oldLobby.getAdmin().equals(admin)) {
oldLobby.setAdmin(admin);
}
oldLobby.setHasBeenVisited(true); oldLobby.setHasBeenVisited(true);
oldLobby.setLobbyIsOpen(isOpen); oldLobby.setLobbyIsOpen(isOpen);
oldLobby.removeAllMembers(); oldLobby.removeAllMembers();
@ -87,7 +115,7 @@ public class LobbyDisplayHandler {
LobbyDisplayHandler handler = new LobbyDisplayHandler(); LobbyDisplayHandler handler = new LobbyDisplayHandler();
String lobby = "1:Seraina:true:Alex:Jonas$2:Sebi:false:Maria:Claudia:Hansli$3:Vanessa:true:Lara:Flu"; String lobby = "1:Seraina:true:Alex:Jonas$2:Sebi:false:Maria:Claudia:Hansli$3:Vanessa:true:Lara:Flu";
handler.updateLobbies(lobby); 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) { for (LobbyModel model : lobbies) {
//System.out.println(model); //System.out.println(model);
System.out.println("Lobby " + model.getId() + " " + model.isLobbyIsOpen() + " (" + model.getAdmin() + "):"); System.out.println("Lobby " + model.getId() + " " + model.isLobbyIsOpen() + " (" + model.getAdmin() + "):");

View File

@ -8,7 +8,7 @@ import java.util.HashSet;
*/ */
public class LobbyModel { public class LobbyModel {
private final int id; private final int id;
private final String admin; private String admin;
private HashSet<String> members = new HashSet<String>(5); private HashSet<String> members = new HashSet<String>(5);
private boolean lobbyIsOpen = true; private boolean lobbyIsOpen = true;
private boolean hasBeenVisited = false; private boolean hasBeenVisited = false;
@ -42,6 +42,10 @@ public class LobbyModel {
return admin; return admin;
} }
public void setAdmin(String admin) {
this.admin = admin;
}
public void setHasBeenVisited(boolean hasBeenVisited) { public void setHasBeenVisited(boolean hasBeenVisited) {
this.hasBeenVisited = hasBeenVisited; this.hasBeenVisited = hasBeenVisited;
} }

View File

@ -35,8 +35,10 @@ import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.TilePane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import javafx.scene.text.TextFlow; import javafx.scene.text.TextFlow;
import javafx.util.Duration; 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 Logger LOGGER = LogManager.getLogger(LoungeSceneViewController.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER); public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
@FXML @FXML
private AnchorPane listLobbyAnchorPane; private AnchorPane highScorePane;
@FXML @FXML
private AnchorPane buttonPane; private TilePane listTilePane;
@FXML
private AnchorPane buttonLobbyPane;
@FXML
private AnchorPane backGroundAnimationPane;
@FXML
private AnchorPane backGroundAnchorPane;
@FXML @FXML
private AnchorPane gameDisplayAnchorPane; private AnchorPane gameDisplayAnchorPane;
@FXML @FXML
private AnchorPane listLobbyAnchorPane;
@FXML
private TextFlow highScore; private TextFlow highScore;
@FXML @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; private Button newGameButton;
@FXML @FXML
private AnchorPane gameAnchorPane; private ToolBar LobbyControlsToolBar;
@FXML @FXML
public ListView<LobbyListItem> LobbyListView; private BorderPane allLobbyElementsBorderPane;
@FXML
private AnchorPane ChatArea;
@FXML @FXML
private Button ChangeNameButton; private Button ChangeNameButton;
@FXML @FXML
private Button leaveLobbyButton;
@FXML
private Button LeaveServerButton; private Button LeaveServerButton;
@FXML @FXML
private AnchorPane ChatArea; private AnchorPane backGroundAnchorPane;
@FXML
private AnchorPane backGroundAnimationPane;
@FXML @FXML
private BorderPane LoungeSceneBorderPane; private BorderPane LoungeSceneBorderPane;
@FXML @FXML
private ToolBar NTtBToolBar; private ToolBar NTtBToolBar;
public static ListView<LobbyListItem> lListView;
public static ClientModel client; public static ClientModel client;
private static ChatApp chatApp; private static ChatApp chatApp;
private ChatApp cApp; private ChatApp cApp;
private static TrainAnimationDayController trainAnimationDayController; private static TrainAnimationDayController trainAnimationDayController;
ObservableList<ClientListItem> clients = FXCollections.observableArrayList();
ObservableList<LobbyListItem> lobbies = FXCollections.observableArrayList();
private ObservableMap<String, ObservableList<String>> lobbyToMemberssMap;
private HashMap<String, String> clientToLobbyMap;
private HashMap<String, LobbyListItem> lobbyIDtoLobbyMop;
public LoungeSceneViewController() { public LoungeSceneViewController() {
super(); super();
lobbyToMemberssMap = FXCollections.observableHashMap();
lobbyIDtoLobbyMop = new HashMap<>();
} }
public void setChatApp(ChatApp chatApp) { public void setChatApp(ChatApp chatApp) {
@ -143,122 +124,20 @@ public class LoungeSceneViewController implements Initializable {
ChangeNameButton.setOnAction(event -> changeName()); ChangeNameButton.setOnAction(event -> changeName());
LeaveServerButton.setOnAction(event -> leaveServer()); LeaveServerButton.setOnAction(event -> leaveServer());
newGameButton.setOnAction(event -> newGame()); newGameButton.setOnAction(event -> newGame());
LobbyListView.setVisible(true);
lListView = LobbyListView;
LOGGER.debug("Lobby in initialize" + LobbyListView);
addChatView(); addChatView();
addBackgroundDay(); addBackgroundDay();
addListOfLobbiesView(); addListOfLobbiesView();
LOGGER.debug("cApp = " + cApp); LOGGER.debug("cApp = " + cApp);
LOGGER.debug("chatApp = " + chatApp); LOGGER.debug("chatApp = " + chatApp);
TrainAnimationDayController.setcApp(cApp); 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<LobbyListItem> 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.
*
* <p>It is <strong>very important</strong> 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:
*
* <pre>
* protected void updateItem(T item, boolean empty) {
* super.updateItem(item, empty);
*
* if (empty || item == null) {
* setText(null);
* setGraphic(null);
* } else {
* setText(item.toString());
* }
* }
* </pre>
*
* <p>Note in this code sample two important points:
* <ol>
* <li>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.</li>
* <li>We test for the <code>empty</code> 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.</li>
* </ol>
* @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() { Platform.runLater(new Runnable() {
@Override @Override
public void run() { 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() { public void run() {
try { try {
LOGGER.debug(" in GameView()" + chatApp); LOGGER.debug(" in GameView()" + chatApp);
buttonLobbyPane.setVisible(false); allLobbyElementsBorderPane.setVisible(false);
gameDisplayAnchorPane.getChildren().add(chatApp.game); gameDisplayAnchorPane.getChildren().add(chatApp.game);
chatApp.getGameController().clearAllNoiseDisplay();
chatApp.getGameController().clearNotificationText();
} catch (Exception e) { } catch (Exception e) {
LOGGER.debug("Not yet initialized"); LOGGER.debug("Not yet initialized");
} }
@ -305,7 +186,9 @@ public class LoungeSceneViewController implements Initializable {
public void run() { public void run() {
try { try {
trainAnimationDayController.showFullWagon(); trainAnimationDayController.showFullWagon();
buttonLobbyPane.setVisible(true); allLobbyElementsBorderPane.setVisible(true);
chatApp.getGameController().clearAllNoiseDisplay();
chatApp.getGameController().clearNotificationText();
gameDisplayAnchorPane.getChildren().clear(); gameDisplayAnchorPane.getChildren().clear();
} catch (Exception e) { } catch (Exception e) {
LOGGER.debug("Not yet initialized"); 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<ClientListItem> 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 * Send the joinLobby Protocol message
* *
@ -500,68 +319,13 @@ public class LoungeSceneViewController implements Initializable {
for (String argument : arguments) { for (String argument : arguments) {
LOGGER.debug("HighScore " + argument); LOGGER.debug("HighScore " + argument);
Text text = new Text(argument + System.lineSeparator()); 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); 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<LobbyListItem> 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);
}
});
}
}
}
} }

View File

@ -28,7 +28,7 @@ public class ChatLabelConfigurator {
l.setAlignment(Pos.CENTER_RIGHT); l.setAlignment(Pos.CENTER_RIGHT);
l.setWrapText(true); l.setWrapText(true);
l.setMaxHeight(Double.MAX_VALUE); l.setMaxHeight(Double.MAX_VALUE);
l.setPrefWidth(1135); l.setPrefWidth(680);
l.setScaleShape(false); l.setScaleShape(false);
} else { } else {
//t = new Text(client.getUsername() + " (you): " + msg); //t = new Text(client.getUsername() + " (you): " + msg);
@ -37,7 +37,7 @@ public class ChatLabelConfigurator {
l.setAlignment(Pos.CENTER_RIGHT); l.setAlignment(Pos.CENTER_RIGHT);
l.setWrapText(true); l.setWrapText(true);
l.setMaxHeight(Double.MAX_VALUE); l.setMaxHeight(Double.MAX_VALUE);
l.setPrefWidth(1135); l.setPrefWidth(680);
l.setScaleShape(false); l.setScaleShape(false);
} }
return l; return l;

View File

@ -212,6 +212,13 @@ public class Protocol {
*/ */
public static final String noiseNotificationProtocol = "NOISE"; 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 * 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} * {@code POSOF$position}

View File

@ -129,10 +129,7 @@ public class ClientHandler implements Runnable {
String helper = this.getClientUserName(); String helper = this.getClientUserName();
String oldName = getClientUserName(); String oldName = getClientUserName();
this.clientUserName = nameDuplicateChecker.checkName(newName); this.clientUserName = nameDuplicateChecker.checkName(newName);
guiUpdateAll(Protocol.printToGUI + "$" + GuiParameters.nameChanged + "$" + oldName + ":"
+ getClientUserName());
sendMsgToClient(Protocol.changedUserName + "$" + newName); sendMsgToClient(Protocol.changedUserName + "$" + newName);
broadcastAnnouncementToAll(helper + " has changed their nickname to " + clientUserName); broadcastAnnouncementToAll(helper + " has changed their nickname to " + clientUserName);
try { try {
getLobby().getGame().getGameState().changeUsername(helper, newName); 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 * 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); Thread t = new Thread(game);
t.start(); t.start();
l.addGameToRunningGames(game); l.addGameToRunningGames(game);
sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.viewChangeToGame + "$");
} else { } else {
sendAnnouncementToClient("Only the admin can start the game"); sendAnnouncementToClient("Only the admin can start the game");
} }
@ -475,9 +467,6 @@ public class ClientHandler implements Runnable {
public void createNewLobby() { public void createNewLobby() {
if (Lobby.clientIsInLobby(this) == -1) { if (Lobby.clientIsInLobby(this) == -1) {
Lobby newGame = new Lobby(this); Lobby newGame = new Lobby(this);
guiUpdateAll(
Protocol.printToGUI + "$" + GuiParameters.newLobbyCreated + "$" + getLobby().getLobbyID()
+ ":" + getClientUserName());
LOGGER.debug("Lobby: " + getLobby().getLobbyID() + ". In method createNewLobby()"); LOGGER.debug("Lobby: " + getLobby().getLobbyID() + ". In method createNewLobby()");
} else { } else {
sendAnnouncementToClient("You are already in lobby nr. " + Lobby.clientIsInLobby(this)); sendAnnouncementToClient("You are already in lobby nr. " + Lobby.clientIsInLobby(this));
@ -495,8 +484,6 @@ public class ClientHandler implements Runnable {
if (l != null) { if (l != null) {
if (l.getLobbyIsOpen()) { if (l.getLobbyIsOpen()) {
l.addPlayer(this); l.addPlayer(this);
guiUpdateAll(Protocol.printToGUI + "$" + GuiParameters.addNewMemberToLobby + "$" + i + ":"
+ getClientUserName());
} else { } else {
sendAnnouncementToClient("The game in Lobby " + l.getLobbyID() sendAnnouncementToClient("The game in Lobby " + l.getLobbyID()
+ " has already started, or the lobby is already full."); + " has already started, or the lobby is already full.");
@ -517,8 +504,6 @@ public class ClientHandler implements Runnable {
l.removePlayer(this); l.removePlayer(this);
Game game = l.getGame(); Game game = l.getGame();
if(l.getAdmin().equals(getClientUserName())){ 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{ }else{
//client just leaves lobby //client just leaves lobby
} }

View File

@ -65,8 +65,6 @@ public class JServerProtocolParser {
} catch (Exception e) { } catch (Exception e) {
h.setUsernameOnLogin("U.N. Owen"); h.setUsernameOnLogin("U.N. Owen");
} }
h.guiUpdateAll(Protocol.printToGUI + "$" + GuiParameters.newPlayerOnServer + "$"
+ h.getClientUserName());
break; break;
case Protocol.nameChange: case Protocol.nameChange:
h.changeUsername(msg.substring(6)); h.changeUsername(msg.substring(6));
@ -92,9 +90,6 @@ public class JServerProtocolParser {
break; break;
case Protocol.createNewLobby: case Protocol.createNewLobby:
h.createNewLobby(); h.createNewLobby();
h.guiUpdateAll(
Protocol.printToGUI + "$" + GuiParameters.newLobbyCreated + "$" + h.getLobby()
.getLobbyID() + ":" + h.getClientUserName());
LOGGER.info("Here"); LOGGER.info("Here");
break; break;
case Protocol.listLobbies: case Protocol.listLobbies:
@ -115,7 +110,6 @@ public class JServerProtocolParser {
break; break;
case Protocol.startANewGame: case Protocol.startANewGame:
h.startNewGame(); h.startNewGame();
h.sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.viewChangeToGame + "$");
break; break;
case Protocol.listGames: case Protocol.listGames:
h.listGames(); h.listGames();

View File

@ -1,6 +1,7 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.server; package ch.unibas.dmi.dbis.cs108.multiplayer.server;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig; 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.GuiParameters;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ServerPinger; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ServerPinger;
@ -18,15 +19,25 @@ public class LobbyUpdater implements Runnable{
public void run() { public void run() {
while (true) { while (true) {
try { try {
Thread.sleep(3000); Thread.sleep(1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.warn(e.getMessage()); LOGGER.warn(e.getMessage());
} }
String lobbiesAsString = Lobby.lobbiesToString(); String lobbiesAsString = Lobby.lobbiesToString();
for (ClientHandler client : ClientHandler.getConnectedClients()) { 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()) { if (!Lobby.lobbies.isEmpty()) {
client.sendMsgToClient( client.sendMsgToClient(
Protocol.printToGUI + "$" + GuiParameters.updateLobbyString + "$" + lobbiesAsString); Protocol.printToGUI + "$" + GuiParameters.updateLobbyString + "$" + lobbiesAsString);
} else{
client.sendMsgToClient(
Protocol.printToGUI + "$" + GuiParameters.updateLobbyString + "$");
} }
} }
} }

View File

@ -3,6 +3,17 @@
-fx-background-color: transparent; -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{ #vBoxChatMessages{
-fx-background-color: transparent; -fx-background-color: transparent;
} }

View File

@ -4,6 +4,7 @@
<?import javafx.scene.control.Button?> <?import javafx.scene.control.Button?>
<?import javafx.scene.control.ScrollBar?> <?import javafx.scene.control.ScrollBar?>
<?import javafx.scene.control.ScrollPane?> <?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TextField?> <?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?> <?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?> <?import javafx.scene.image.ImageView?>
@ -14,16 +15,16 @@
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?> <?import javafx.scene.text.Font?>
<AnchorPane fx:id="chatPaneRoot" maxWidth="1300.0" pickOnBounds="false" prefWidth="1300.0" stylesheets="@Chat.css" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatController"> <AnchorPane fx:id="chatPaneRoot" maxWidth="1300.0" pickOnBounds="false" prefHeight="386.0" prefWidth="1300.0" stylesheets="@Chat.css" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatController">
<children> <children>
<ImageView fitHeight="700.0" fitWidth="1300.0" pickOnBounds="true" preserveRatio="true"> <ImageView fitHeight="700.0" fitWidth="1300.0" pickOnBounds="true" preserveRatio="true">
<image> <image>
<Image url="@images/chatwindow.png" /> <Image url="@images/chatwindow.png" />
</image> </image>
</ImageView> </ImageView>
<AnchorPane layoutX="115.0" layoutY="95.0" prefHeight="220.0" prefWidth="1128.0"> <AnchorPane layoutX="115.0" layoutY="95.0" prefHeight="220.0" prefWidth="700.0">
<children> <children>
<GridPane alignment="CENTER" maxWidth="-Infinity" pickOnBounds="false" prefWidth="1300.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <GridPane alignment="CENTER" maxWidth="-Infinity" pickOnBounds="false" prefWidth="700.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="100.0" />
</columnConstraints> </columnConstraints>
@ -32,18 +33,18 @@
<RowConstraints maxHeight="-Infinity" minHeight="10.0" percentHeight="30.0" valignment="CENTER" vgrow="ALWAYS" /> <RowConstraints maxHeight="-Infinity" minHeight="10.0" percentHeight="30.0" valignment="CENTER" vgrow="ALWAYS" />
</rowConstraints> </rowConstraints>
<children> <children>
<ScrollPane fx:id="ChatScrollPane" fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER" maxHeight="1.7976931348623157E308" maxWidth="-Infinity"> <ScrollPane fx:id="ChatScrollPane" fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER" maxHeight="1.7976931348623157E308" maxWidth="-Infinity" prefWidth="700.0">
<content> <content>
<VBox fx:id="vBoxChatMessages" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="1128.0" spacing="2.0" /> <VBox fx:id="vBoxChatMessages" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="695.0" spacing="2.0" />
</content> </content>
</ScrollPane> </ScrollPane>
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="-Infinity" pickOnBounds="false" prefWidth="1300.0" GridPane.rowIndex="1"> <AnchorPane maxHeight="1.7976931348623157E308" maxWidth="-Infinity" pickOnBounds="false" prefWidth="700.0" GridPane.rowIndex="1">
<children> <children>
<GridPane alignment="CENTER" layoutX="10.0" layoutY="20.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="82.0" prefWidth="2072.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <GridPane alignment="CENTER" layoutX="10.0" layoutY="20.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="82.0" prefWidth="700.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" percentWidth="5.0" /> <ColumnConstraints hgrow="SOMETIMES" percentWidth="10.0" />
<ColumnConstraints hgrow="SOMETIMES" percentWidth="11.0" /> <ColumnConstraints hgrow="SOMETIMES" percentWidth="15.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="20.0" percentWidth="84.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="20.0" percentWidth="75.0" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" percentHeight="90.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" percentHeight="90.0" vgrow="SOMETIMES" />
@ -61,7 +62,7 @@
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" /> <Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
</GridPane.margin> </GridPane.margin>
</AnchorPane> </AnchorPane>
<AnchorPane fx:id="whisperAnchor" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="92.0" prefWidth="85.0" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS"> <AnchorPane fx:id="whisperAnchor" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="42.0" prefWidth="164.0" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
<children> <children>
<TextField fx:id="whisperTargetSelectField" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="56.0" prefWidth="488.0" promptText="whisper..." AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> <TextField fx:id="whisperTargetSelectField" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="56.0" prefWidth="488.0" promptText="whisper..." AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children> </children>
@ -108,5 +109,11 @@
<VBox fx:id="vBoxServerMessage" alignment="TOP_RIGHT" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mouseTransparent="true" pickOnBounds="false" prefHeight="184.0" spacing="2.0" GridPane.columnIndex="1" /> <VBox fx:id="vBoxServerMessage" alignment="TOP_RIGHT" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mouseTransparent="true" pickOnBounds="false" prefHeight="184.0" spacing="2.0" GridPane.columnIndex="1" />
</children> </children>
</GridPane> </GridPane>
<ScrollPane fx:id="serverScrollPane" fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER" layoutX="818.0" layoutY="95.0" maxHeight="154.0" maxWidth="434.0" prefHeight="154.0" prefWidth="434.0">
<content>
<VBox fx:id="vBoxServer" maxWidth="430.0" minWidth="-Infinity" prefHeight="154.0" prefWidth="430.0" spacing="2.0" />
</content>
</ScrollPane>
<Separator layoutX="810.0" layoutY="95.0" orientation="VERTICAL" prefHeight="220.0" prefWidth="7.0" />
</children> </children>
</AnchorPane> </AnchorPane>

View File

@ -9,16 +9,23 @@
.button:pressed{ .button:pressed{
-fx-background-color: transparent; -fx-background-color: transparent;
-fx-border-color: transparent; -fx-boarder-color: lightgrey;
} }
#noiseButton{ #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; -fx-text-fill: lightgrey;
} }
#noiseButton:hover{
-fx-effect: innershadow(gaussian, lightsteelblue, 10, 0.5 , 2, 2);
}
#noiseButton:pressed{ #noiseButton:pressed{
-fx-background-color: midnightblue; -fx-background-image: url(bellPressed.jpg);
-fx-background-size: 100%;
-fx-text-fill: lightgrey; -fx-text-fill: lightgrey;
} }
@ -27,6 +34,7 @@
} }
.textField{ .textField{
-fx-text-fill: white; -fx-text-fill: white;
-fx-background-color: transparent; -fx-background-color: transparent;

View File

@ -49,7 +49,7 @@
<ImageView fx:id="noiseImage5" fitHeight="843.75" fitWidth="1500.0" layoutX="-585.0" layoutY="-125.1" preserveRatio="true" /> <ImageView fx:id="noiseImage5" fitHeight="843.75" fitWidth="1500.0" layoutX="-585.0" layoutY="-125.1" preserveRatio="true" />
<Group fx:id="roomButtonGroupDay" layoutX="288.0" layoutY="220.0"> <Group fx:id="roomButtonGroupDay" layoutX="288.0" layoutY="220.0">
<children> <children>
<HBox fx:id="roomLables" alignment="CENTER" layoutY="82.0" prefHeight="62.0" prefWidth="747.0" rotate="12.2"> <HBox fx:id="roomLables" alignment="CENTER" layoutX="-11.0" layoutY="170.0" prefHeight="35.0" prefWidth="717.0" rotate="12.2">
<children> <children>
<TextFlow fx:id="lableRoom0" prefHeight="200.0" prefWidth="200.0" textAlignment="CENTER" /> <TextFlow fx:id="lableRoom0" prefHeight="200.0" prefWidth="200.0" textAlignment="CENTER" />
<TextFlow fx:id="lableRoom1" prefHeight="200.0" prefWidth="200.0" textAlignment="CENTER" /> <TextFlow fx:id="lableRoom1" prefHeight="200.0" prefWidth="200.0" textAlignment="CENTER" />
@ -91,11 +91,12 @@
</Button> </Button>
</children> </children>
</Group> </Group>
<Button fx:id="noiseButton" alignment="CENTER" layoutX="267.0" layoutY="482.0" mnemonicParsing="false" onAction="#noise" prefHeight="114.0" prefWidth="217.0" text="I heard some noise"> <Button fx:id="noiseButton" alignment="CENTER" layoutX="1161.0" layoutY="166.0" mnemonicParsing="false" onAction="#noise" prefHeight="115.0" prefWidth="115.0">
<font> <font>
<Font name="System Bold" size="21.0" /> <Font name="System Bold" size="21.0" />
</font></Button> </font>
<TextFlow fx:id="notificationText" accessibleRole="PARENT" layoutX="210.0" layoutY="20.0" pickOnBounds="false" prefHeight="200.0" prefWidth="800.0" textAlignment="CENTER" /> </Button>
<TextFlow fx:id="notificationText" accessibleRole="PARENT" layoutX="346.0" layoutY="112.0" pickOnBounds="false" prefHeight="200.0" prefWidth="800.0" textAlignment="CENTER" />
<AnchorPane fx:id="chatAreaGame" pickOnBounds="false" /> <AnchorPane fx:id="chatAreaGame" pickOnBounds="false" />
</children> </children>
</AnchorPane> </AnchorPane>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -4,11 +4,11 @@
<?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<ScrollPane fx:id="backDropScrolePane" hbarPolicy="NEVER" prefHeight="300.0" prefWidth="200.0" stylesheets="@listStyle.css" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.ListOfLobbiesController"> <ScrollPane fx:id="backDropScrolePane" hbarPolicy="NEVER" minHeight="400.0" minWidth="450.0" stylesheets="@listStyle.css" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.ListOfLobbiesController">
<content> <content>
<AnchorPane fx:id="scollingAnchorPane"> <AnchorPane fx:id="scollingAnchorPane" minHeight="400.0" minWidth="450.0">
<children> <children>
<VBox fx:id="LobbyListVBox" fillWidth="false" prefWidth="200.0" /> <VBox fx:id="LobbyListVBox" fillWidth="false" maxWidth="450.0" minHeight="400.0" minWidth="450.0" />
</children></AnchorPane> </children></AnchorPane>
</content> </content>
</ScrollPane> </ScrollPane>

View File

@ -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);
}

View File

@ -2,7 +2,6 @@
<?import javafx.scene.control.Button?> <?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?> <?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.ToolBar?> <?import javafx.scene.control.ToolBar?>
<?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?> <?import javafx.scene.layout.BorderPane?>
@ -16,8 +15,6 @@
<top> <top>
<ToolBar fx:id="NTtBToolBar" pickOnBounds="false" prefHeight="30.0" BorderPane.alignment="CENTER"> <ToolBar fx:id="NTtBToolBar" pickOnBounds="false" prefHeight="30.0" BorderPane.alignment="CENTER">
<items> <items>
<Button fx:id="highScoreButton" mnemonicParsing="false" onAction="#sendHIghScore" pickOnBounds="false" text="High Score" />
<Button fx:id="lobbyPrintButton" mnemonicParsing="false" onAction="#sendLilstle" pickOnBounds="false" text="Lobby List" />
<Button fx:id="LeaveServerButton" mnemonicParsing="false" pickOnBounds="false" text="Leave server" /> <Button fx:id="LeaveServerButton" mnemonicParsing="false" pickOnBounds="false" text="Leave server" />
<Button fx:id="leaveLobbyButton" mnemonicParsing="false" onAction="#leaveLobby" pickOnBounds="false" text="Leave Lobby" /> <Button fx:id="leaveLobbyButton" mnemonicParsing="false" onAction="#leaveLobby" pickOnBounds="false" text="Leave Lobby" />
<Button fx:id="ChangeNameButton" mnemonicParsing="false" pickOnBounds="false" text="Change Name" /> <Button fx:id="ChangeNameButton" mnemonicParsing="false" pickOnBounds="false" text="Change Name" />
@ -25,39 +22,48 @@
</ToolBar> </ToolBar>
</top> </top>
<left> <left>
<AnchorPane prefHeight="316.0" prefWidth="181.0" BorderPane.alignment="CENTER"> <AnchorPane prefWidth="200.0" BorderPane.alignment="CENTER" />
<children>
<Label layoutX="59.0" layoutY="200.0" pickOnBounds="false" text="High Score:" />
<TextFlow fx:id="highScore" layoutX="62.0" layoutY="232.0" pickOnBounds="false" prefHeight="167.0" prefWidth="181.0" AnchorPane.bottomAnchor="1.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="232.0" />
<Label layoutX="67.0" layoutY="6.0" pickOnBounds="false" text="Players:" />
<TextFlow fx:id="lobbyPrint" layoutX="5.0" layoutY="23.0" pickOnBounds="false" prefHeight="178.0" prefWidth="171.0" />
</children>
</AnchorPane>
</left> </left>
<center>
<AnchorPane fx:id="buttonLobbyPane" pickOnBounds="false" prefHeight="122.0" prefWidth="85.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="newGameButton" layoutX="9.0" layoutY="109.0" mnemonicParsing="false" pickOnBounds="false" text="New Lobby" AnchorPane.leftAnchor="9.0" />
<AnchorPane fx:id="gameAnchorPane" pickOnBounds="false" />
<Button fx:id="startGame" alignment="BASELINE_CENTER" layoutX="9.0" layoutY="140.0" mnemonicParsing="false" onAction="#startGame" pickOnBounds="false" text="Start Game" />
</children>
</AnchorPane>
</center>
<bottom> <bottom>
<TilePane alignment="CENTER" orientation="VERTICAL" prefColumns="1" prefRows="1" BorderPane.alignment="CENTER"> <TilePane alignment="TOP_CENTER" orientation="VERTICAL" prefColumns="1" prefRows="1" BorderPane.alignment="CENTER">
<children> <children>
<AnchorPane fx:id="ChatArea" pickOnBounds="false" prefHeight="83.0" prefWidth="578.0" /> <AnchorPane fx:id="ChatArea" pickOnBounds="false" prefWidth="578.0" />
</children> </children>
</TilePane> </TilePane>
</bottom> </bottom>
<right> <right>
<AnchorPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER"> <AnchorPane prefWidth="200.0" BorderPane.alignment="CENTER" />
<children>
<ListView fx:id="LobbyListView" opacity="0.0" pickOnBounds="false" />
<AnchorPane fx:id="listLobbyAnchorPane" />
</children>
</AnchorPane>
</right> </right>
<center>
<TilePane alignment="CENTER" orientation="VERTICAL" BorderPane.alignment="CENTER">
<children>
<BorderPane fx:id="allLobbyElementsBorderPane" maxWidth="-Infinity" prefHeight="285.0" prefWidth="500.0" stylesheets="@LobbiesBorderPane.css">
<top>
<ToolBar fx:id="LobbyControlsToolBar" prefHeight="35.0" prefWidth="500.0" BorderPane.alignment="CENTER">
<items>
<Button fx:id="newGameButton" mnemonicParsing="false" pickOnBounds="false" text="New Lobby" />
</items>
</ToolBar>
</top>
<center>
<TilePane fx:id="listTilePane" alignment="TOP_CENTER" maxHeight="-Infinity" orientation="VERTICAL" prefHeight="250.0" prefWidth="500.0" BorderPane.alignment="CENTER">
<children>
<AnchorPane fx:id="listLobbyAnchorPane" minHeight="300.0" minWidth="450.0" prefWidth="0.0" />
</children>
</TilePane>
</center>
<bottom>
<AnchorPane fx:id="highScorePane" prefWidth="416.0" BorderPane.alignment="CENTER">
<children>
<TextFlow fx:id="highScore" layoutX="88.0" layoutY="6.0" pickOnBounds="false" prefHeight="94.0" prefWidth="245.0" />
<Label layoutX="14.0" layoutY="35.0" pickOnBounds="false" text="High Score:" AnchorPane.leftAnchor="10.0" />
</children>
</AnchorPane>
</bottom>
</BorderPane>
</children>
</TilePane>
</center>
</BorderPane> </BorderPane>
<AnchorPane fx:id="gameDisplayAnchorPane" maxHeight="843.75" maxWidth="1500.0" pickOnBounds="false" /> <AnchorPane fx:id="gameDisplayAnchorPane" maxHeight="843.75" maxWidth="1500.0" pickOnBounds="false" />
</children> </children>

View File

@ -4,22 +4,22 @@
} }
#NTtBToolBar{ #NTtBToolBar{
-fx-border-color: grey; -fx-background-color: rgb(15,26,59,0.8);
-fx-background-color: rgba(255,255,255,0.5);
} }
.button{ .button{
-fx-background-color: midnightblue; -fx-background-color: rgb(204,186,138);
-fx-text-fill: lightsteelblue; -fx-effect: innershadow(gaussian, rgb(142,121,89), 10, 0.5 , 2, 2);
-fx-text-fill: black;
} }
.button:pressed{ .button:pressed{
-fx-background-color: lightsteelblue; -fx-background-color: rgb(90,69,51);
-fx-text-fill: midnightblue; -fx-text-fill: rgb(197,177,131);
} }
.button:hover{ .button:hover{
-fx-effect: innershadow(gaussian, lightsteelblue, 10, 0.5 , 2, 2); -fx-effect: innershadow(gaussian, rgb(90,69,51), 10, 0.5 , 2, 2);
} }
*{ *{

View File

@ -1,16 +1,5 @@
*{ *{
-fx-background-color: midnightblue; -fx-background-color: transparent;
}
.button{
-fx-text-fill: black;
-fx-background-color: lightGrey;
}
.button:hover{
-fx-effect: innershadow(gaussian, grey, 10, 0.2 , 2, 2);
}
.button:pressed{
-fx-background-color: grey;
} }
.tree-cell .tree-disclosure-node .arrow { .tree-cell .tree-disclosure-node .arrow {

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

View File

@ -1,19 +1,13 @@
*{
#highScore{ -fx-font-family: serif;
-fx-background-color: midnightblue; -fx-font-size: 15;
} }
#LobbyListView{ #backGroundAnchorPane{
-fx-background-color: transparent; -fx-background-image: url(logo.jpg);
} -fx-background-size: 100%;
-fx-background-position: center;
#lobbyPrint{ -fx-background-repeat: no-repeat;
-fx-background-color: midnightblue;
}
#buttonPane{
-fx-background-color: midnightblue;
-fx-alignment: center;
} }
.anchorPane{ .anchorPane{