Merge remote-tracking branch 'origin/master'

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

View File

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

View File

@@ -122,6 +122,10 @@ public class Game implements Runnable {
LOGGER.info(gameState.toGhostString());
for (ClientHandler client : lobbyClients) {//begins filling the train with clients
//send train horn sound to client:
client.sendMsgToClient(Protocol.playSound + "$" + "TH");
int index = order[i];
if (passengerTrain[index].getIsGhost()) { //if there is a ghost
GhostPlayer ghostPlayer = new GhostPlayer(passengerTrain[index].getPosition(),
@@ -172,6 +176,14 @@ public class Game implements Runnable {
if (gameOverCheck.equals(ClientGameInfoHandler.gameOverGhostsWin) && getOgGhost().getIsPlayer()) {
OgGhostHighScore.addOgGhostWinner(getOgGhost().getName());
}
//send command to play game over sound:
if (gameOverCheck.equals(ClientGameInfoHandler.gameOverGhostsWin)) {
lobby.getAdmin().sendMsgToClientsInLobby(Protocol.playSound + "$" + "GW");
} else {
lobby.getAdmin().sendMsgToClientsInLobby(Protocol.playSound + "$" + "HW");
}
lobby.getAdmin().broadcastAnnouncementToLobby(gameOverCheck);
isOngoing = false;
Timer.ghostAfterVoteTimer();

View File

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

View File

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

View File

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

View File

@@ -16,23 +16,23 @@ public class Timer {
/**
* The maximum length of the ghost vote in the night, in seconds
*/
public static final int ghostVoteTime = 30;
public static final int ghostVoteTime = 40;
/**
* The length of time in seconds after the ghost vote during which the ghosts visually walk to /
* from their victim and the timespan within which humans will hear a noise. After this, the day starts.
*/
public static final int ghostAfterVoteTime = 6;
public static final int ghostAfterVoteTime = 8;
/**
* The maximum length of the human vote in the day, in seconds
*/
public static final int humanVoteTime = 60;
public static final int humanVoteTime = 63;
/**
* The length of time in seconds after the human vote, as the 'winner' of the vote is announced,
* before the night begins
*/
public static final int humanAfterVoteTime = 5;
public static final int humanAfterVoteTime = 8;
/**
* The checking interval in seconds

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.multiplayer.helpers.GuiParameters;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -88,7 +89,7 @@ public class VoteHandler {
ghostification. */
int[] noiseAmount = new int[6];
for (int i = 0; i < passengers.length; i++) {
if (passengers[i].getIsGhost() && i != newGhostPosition) {
if (passengers[i].getIsGhost() && !passengers[i].getKickedOff() && i != newGhostPosition) {
NoiseHandler n = new NoiseHandler();
noiseAmount = n.noiseNotifier(passengers[i], g, noiseAmount);
}
@@ -169,12 +170,24 @@ public class VoteHandler {
.getIsGhost()) { // if player with most votes is human, notify everyone about it
for (Passenger passenger : passengers) {
passenger.send(
ClientGameInfoHandler.humansVotedFor + voteIndex + ClientGameInfoHandler.isAHuman, game);
ClientGameInfoHandler.humansVotedFor + passengers[voteIndex].getName() + ClientGameInfoHandler.isAHuman, game);
}
for (ClientHandler c: game.getLobby().getLobbyClients()) { //send human vote sound to clients
c.sendMsgToClient(Protocol.playSound + "$" + "HV");
}
} else if (!passengers[voteIndex].getIsOG()) {
for (ClientHandler c: game.getLobby().getLobbyClients()) { //send ghost vote sound to clients
c.sendMsgToClient(Protocol.playSound + "$" + "GV");
}
}
Timer.humanAfterVoteTimer();
if (passengers[voteIndex].getIsGhost()) { // if player is a ghost
if (passengers[voteIndex].getIsOG()) { // if ghost is OG --> end game, humans win
for (Passenger passenger : passengers) {
passenger.send(
ClientGameInfoHandler.humansVotedFor + passengers[voteIndex].getName() + ", the Original Ghost!", game);
}
System.out.println(ClientGameInfoHandler.gameOverHumansWin);
return ClientGameInfoHandler.gameOverHumansWin;
} else {
@@ -200,6 +213,8 @@ public class VoteHandler {
}
}
}
Timer.humanAfterVoteTimer();
LOGGER.info(game.getGameState().toString());
// set hasVoted to false for all passengers for future voting
for (Passenger passenger : passengers) {

View File

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

View File

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

View File

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

View File

@@ -1,8 +1,10 @@
package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import ch.unibas.dmi.dbis.cs108.gamelogic.ClientGameInfoHandler;
import ch.unibas.dmi.dbis.cs108.gamelogic.Game;
import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -29,6 +31,11 @@ public class Spectator extends Passenger{
*/
@Override
public void send(String msg, Game game) {
clientHandler.sendMsgToClient(ServerGameInfoHandler.spectatorFormat(msg, game));
if (msg.equals(ClientGameInfoHandler.noiseNotification)) {
clientHandler.sendMsgToClient(Protocol.noiseNotificationProtocol);
} else {
clientHandler.sendMsgToClient(ServerGameInfoHandler.spectatorFormat(msg, game));
}
}
}

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.chat.ChatController;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.GameController;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.ListOfLobbiesController;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LobbyDisplayHandler;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeSceneViewController;
@@ -373,34 +374,22 @@ public class Client {
LOGGER.warn("Not a position given for noise " + e.getMessage());
}
break;
case GuiParameters.listOfLobbies:
updateListOfLobbies(data);
//TODO
break;
case GuiParameters.VoteIsOver:
chatApp.getGameController().setNoiseButtonInvisible();
chatApp.getGameController().clearAllNoiseDisplay();
dayNightChangeListener.setNoiseButtonInvisible(true);
break;
case GuiParameters.getMembersInLobby:
updateLobbyMembers(data);
break;
case GuiParameters.viewChangeToGame:
chatApp.getLoungeSceneViewController().addGameView();
gameStateModel.setGameOver(false);
dayNightChangeListener = new DayNightChangeListener(gameStateModel, chatApp, Integer.MAX_VALUE);
ListOfLobbiesController.setGameOngoing(true);
new Thread(dayNightChangeListener).start();
break;
case GuiParameters.viewChangeToLobby:
chatApp.getLoungeSceneViewController().removeGameView();
gameStateModel.setGameOver(true);
//TODO
break;
case GuiParameters.addNewMemberToLobby:
addPlayerToLobby(data);
break;
case GuiParameters.newLobbyCreated:
makeNewLobby(data);
ListOfLobbiesController.setGameOngoing(false);
break;
case GuiParameters.updateHighScore:
chatApp.getLoungeSceneViewController().addHighScore(data);
@@ -408,16 +397,17 @@ public class Client {
case GuiParameters.yourPosition:
dayNightChangeListener.setPosition(Integer.parseInt(data));
break;
case GuiParameters.updatePrintLobby:
chatApp.getLoungeSceneViewController().clearLobbyPrint();
chatApp.getLoungeSceneViewController().addLobbyPrint(data);
break;
case GuiParameters.removeLobby:
removeLobbyFromGui(data);
break;
case GuiParameters.updateLobbyString:
lobbyDisplayHandler.updateLobbies(data);
ChatApp.getListController().updateList();
if(!data.isEmpty()) {
lobbyDisplayHandler.updateLobbies(data);
if(!ListOfLobbiesController.isGameOngoing()) {
ChatApp.getListController().updateList();
}
} else {
if(!ListOfLobbiesController.isGameOngoing()) {
ChatApp.getListController().clearVBox();
}
}
break;
default:
notificationTextDisplay(data);
@@ -431,42 +421,6 @@ public class Client {
}
private void removeLobbyFromGui(String data) {
loungeSceneViewController.removeLobbyFromView(data);
LOGGER.debug("Made it into removeLobbyFromGui()");
}
private void makeNewLobby(String data) {
String[] params = data.split(":");
loungeSceneViewController.newLobby(params[0], params[1]);
LOGGER.debug("makeNewLobby() seems to have finished");
}
private void addPlayerToLobby(String data) {
String[] params = data.split(":");
loungeSceneViewController.addPlayerToLobby(params[0], params[1]);
LOGGER.debug("addPlayerToLobby() seems to have finished");
}
private void updateLobbyMembers(String data) {
String[] dataArr = data.split(":");
String lobbyID = dataArr[0];
String adminName = dataArr[1];
}
private void updateListOfLobbies(String data) {
String[] arr = data.split(":");
ObservableList<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
* seconds and deletes it again.
@@ -476,7 +430,11 @@ public class Client {
public void notificationTextDisplay(String data) {
new Thread(() -> {
try {
chatApp.getGameController().addMessageToNotificationText(data);
if (data.contains("Game over")) {
chatApp.getGameController().addMessageToNotificationText(data);
} else if (!data.contains("$") && !data.contains("nickname")) {
chatApp.getChatController().addChatMsgToServerView(data);
}
Thread.sleep(5000);
chatApp.getGameController().clearNotificationText();
} catch (InterruptedException e) {

View File

@@ -91,6 +91,27 @@ public class JClientProtocolParser {
case Protocol.noiseNotificationProtocol:
Sound.ghost();
break;
case Protocol.playSound:
switch (msg.substring(6)) {
case "GW":
Sound.gameoverghosts();
break;
case "HW":
Sound.gameoverhumans();
break;
case "GV":
Sound.voteforghost();
break;
case "HV":
Sound.voteforhuman();
break;
case "TH":
Sound.trainhorn();
break;
default:
LOGGER.warn("Invalid sound request");
}
break;
default:
System.out.println("Received unknown command: " + msg);
}

View File

@@ -17,6 +17,9 @@ public class Sound {
static URL bellURL = Sound.class.getResource("sounds/bell.wav");
static AudioClip bell = new AudioClip(bellURL.toString());
static URL trainhornURL = Sound.class.getResource("sounds/trainhorn.wav");
static AudioClip trainhorn = new AudioClip(trainhornURL.toString());
static URL daynoisesURL = Sound.class.getResource("sounds/daynoises.wav");
static AudioClip daynoises = new AudioClip(daynoisesURL.toString());
@@ -41,6 +44,32 @@ public class Sound {
static URL ghost04URL = Sound.class.getResource("sounds/ghost04.wav");
static AudioClip ghost04 = new AudioClip(ghost04URL.toString());
static URL ghost05URL = Sound.class.getResource("sounds/ghost05.wav");
static AudioClip ghost05 = new AudioClip(ghost05URL.toString());
static URL ghost06URL = Sound.class.getResource("sounds/ghost06.wav");
static AudioClip ghost06 = new AudioClip(ghost06URL.toString());
static URL ghost07URL = Sound.class.getResource("sounds/ghost07.wav");
static AudioClip ghost07 = new AudioClip(ghost07URL.toString());
static URL ghost08URL = Sound.class.getResource("sounds/ghost08.wav");
static AudioClip ghost08 = new AudioClip(ghost08URL.toString());
static URL ghost09URL = Sound.class.getResource("sounds/ghost09.wav");
static AudioClip ghost09 = new AudioClip(ghost09URL.toString());
static URL ghost10URL = Sound.class.getResource("sounds/ghost10.wav");
static AudioClip ghost10 = new AudioClip(ghost10URL.toString());
static URL ghost11URL = Sound.class.getResource("sounds/ghost11.wav");
static AudioClip ghost11 = new AudioClip(ghost11URL.toString());
static URL ghost12URL = Sound.class.getResource("sounds/ghost12.wav");
static AudioClip ghost12 = new AudioClip(ghost12URL.toString());
static URL musicdayURL = Sound.class.getResource("sounds/music_day.wav");
static AudioClip musicday = new AudioClip(musicdayURL.toString());
@@ -77,6 +106,8 @@ public class Sound {
bell.play(defaultvolume - 0.5);
}
public static void trainhorn() {trainhorn.play(defaultvolume); }
public static void startDaynoises() {
daynoises.setCycleCount(AudioClip.INDEFINITE);
daynoises.play(defaultvolume - 0.5);
@@ -95,9 +126,28 @@ public class Sound {
nightnoises.stop();
}
public static void gameoverghosts() { gameoverghosts.play(defaultvolume); }
public static void gameoverghosts() {
waitForABitThenEndDayMusic();
voteforghost.stop();
voteforhuman.stop();
gameoverghosts.play(defaultvolume - 0.3); }
public static void gameoverhumans() { gameoverhumans.play(defaultvolume); }
public static void gameoverhumans() {
waitForABitThenEndDayMusic();
voteforghost.stop();
voteforhuman.stop();
gameoverhumans.play(defaultvolume - 0.1);
}
public static void voteforghost() {
waitForABitThenEndDayMusic();
voteforghost.play(defaultvolume - 0.4);
}
public static void voteforhuman() {
waitForABitThenEndDayMusic();
voteforhuman.play(defaultvolume - 0.2);
}
public static void musicday() {
musicday.play(defaultvolume);
@@ -109,8 +159,9 @@ public class Sound {
}
public static void ghost() {
double playbackspeed = (Math.random() / 5.0) + 0.9;
int ghostsoundnr = random.nextInt(4) + 1;
//double playbackspeed = (Math.random() / 5.0) + 0.9; causes aliasing artefacts :/
double playbackspeed = 1;
int ghostsoundnr = random.nextInt(12) + 1;
System.out.println(ghostsoundnr);
AudioClip ghost;
switch (ghostsoundnr) {
@@ -123,13 +174,57 @@ public class Sound {
case 3:
ghost = ghost03;
break;
default:
case 4:
ghost = ghost04;
break;
case 5:
ghost = ghost05;
break;
case 6:
ghost = ghost06;
break;
case 7:
ghost = ghost07;
break;
case 8:
ghost = ghost08;
break;
case 9:
ghost = ghost09;
break;
case 10:
ghost = ghost10;
break;
case 11:
ghost = ghost11;
break;
case 12:
ghost = ghost12;
break;
default:
ghost = ghost01;
break;
}
ghost.play(defaultvolume - 0.3, 0.0, playbackspeed, 0.0, 5);
ghost.play(0.1, 0.0, playbackspeed, 0.0, 5);
}
/**
* waits for a bit, then ends day music. :)
*/
public static void waitForABitThenEndDayMusic() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1820);
//the time it takes for the vote result sound to ramp up, so the music ends exactly on the "big reveal"
} catch (InterruptedException e) {
e.printStackTrace();
}
stopmusicday();
}
}).start();
}
}

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

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;
/**
* This class adds methods to listen if there is a change in the day&night state and calls methods accordingly
* This class adds methods to listen if there is a change in the day and night state and calls methods accordingly
*/
public class DayNightChangeListener implements Runnable {
@@ -63,7 +63,7 @@ public class DayNightChangeListener implements Runnable {
chatApp.getGameController().updateRoomLabels();
gameStateModel.setRoleFromPosition(position);
try {
Thread.sleep(100);
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}

View File

@@ -21,12 +21,15 @@ import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Background;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -34,6 +37,15 @@ public class ChatController implements Initializable {
public static final Logger LOGGER = LogManager.getLogger(ChatController.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
@FXML
private AnchorPane whisperAnchor;
@FXML
private AnchorPane chatinputAnchor;
@FXML
private ScrollPane serverScrollPane;
@FXML
private VBox vBoxServer;
@FXML
private Group vboxGroup;
@@ -109,6 +121,20 @@ public class ChatController implements Initializable {
ChatScrollPane.setVvalue((Double) newValue);
}
});
vBoxServer.heightProperty().addListener(new ChangeListener<>() {
/**
* TODO: implement
* Adjust the height when new messages come in.
*/
@Override
public void changed(ObservableValue<? 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
*/
@@ -186,11 +212,12 @@ public class ChatController implements Initializable {
l.setMaxHeight(Double.MAX_VALUE);
if (msg.contains("whispers")) {
l.setBackground(Background.fill(Color.TRANSPARENT));
l.setPrefWidth(1135);
l.setTextFill(Color.rgb(15,26,150));
l.setPrefWidth(680);
l.setScaleShape(false);
} else {
l.setBackground(Background.fill(Color.TRANSPARENT));
l.setPrefWidth(1135);
l.setPrefWidth(680);
l.setScaleShape(false);
}
l.setTextFill(Color.BLACK);
@@ -202,4 +229,27 @@ public class ChatController implements Initializable {
});
}
public void addChatMsgToServerView(String msg) {
TextFlow textFlow = new TextFlow();
textFlow.setPrefWidth(420);
textFlow.setPrefHeight(Region.USE_COMPUTED_SIZE);
Text text = new Text(msg);
textFlow.getChildren().add(text);
try {
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
vBoxServer.getChildren().add(textFlow);
} catch (Exception e) {
LOGGER.warn(e.getMessage());
}
}
});
} catch(Exception e) {
LOGGER.warn(e.getMessage());
}
}
}

View File

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

View File

@@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game;
import static javafx.scene.AccessibleRole.PARENT;
import ch.unibas.dmi.dbis.cs108.gamelogic.Timer;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.Sound;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.GameStateModel;
@@ -24,6 +25,7 @@ import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
@@ -39,7 +41,7 @@ public class GameController implements Initializable {
public static final Logger LOGGER = LogManager.getLogger(GameController.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
static boolean justRangBell = false; //used to track if the bell has been rung recently
static final int minimumBellTime = 1000; //minimal time that has to pass between bells, in ms
static final int minimumBellTime = 100; //minimal time that has to pass between bells, in ms
static boolean playingDayNoises = true; //true if playing day noises, false if playing night noises
private static ClientModel client;
@@ -380,8 +382,8 @@ public class GameController implements Initializable {
public void addMessageToNotificationText(String msg) {
LOGGER.trace("addMessage " + msg);
Text notification = new Text(System.lineSeparator() + msg);
notification.setFill(Color.BLACK);
notification.setStyle("-fx-font: 50 arial;");
notification.setFill(Color.WHITE);
notification.setStyle("-fx-font: 50 serif;");
try {
Platform.runLater(new Runnable() {
@Override
@@ -428,71 +430,30 @@ public class GameController implements Initializable {
String[] roles = gameStateModel.getPassengerTrainClone()[1];
boolean[] kickedOff = gameStateModel.getKickedOff();
Text name0 = new Text(names[0]);
name0.setStyle("-fx-font: 25 arial;");
name0.setFill(Color.WHITE);
name0.setStyle("-fx-font: 15 serif;");
name0.setFill(Color.rgb(255,250,250,0.6));
name0.setEffect(new DropShadow(2.5, Color.BLACK));
Text name1 = new Text(names[1]);
name1.setStyle("-fx-font: 25 arial;");
name1.setFill(Color.WHITE);
name1.setStyle("-fx-font: 15 serif;");
name1.setFill(Color.rgb(255,250,250,0.6));
name1.setEffect(new DropShadow(2.5, Color.BLACK));
Text name2 = new Text(names[2]);
name2.setStyle("-fx-font: 25 arial;");
name2.setFill(Color.WHITE);
name2.setStyle("-fx-font: 15 serif;");
name2.setFill(Color.rgb(255,250,250,0.6));
name2.setEffect(new DropShadow(2.5, Color.BLACK));
Text name3 = new Text(names[3]);
name3.setStyle("-fx-font: 25 arial;");
name3.setFill(Color.WHITE);
name3.setStyle("-fx-font: 15 serif;");
name3.setFill(Color.rgb(255,250,250,0.6));
name3.setEffect(new DropShadow(2.5, Color.BLACK));
Text name4 = new Text(names[4]);
name4.setStyle("-fx-font: 25 arial;");
name4.setFill(Color.WHITE);
name4.setStyle("-fx-font: 15 serif;");
name4.setFill(Color.rgb(255,250,250,0.6));
name4.setEffect(new DropShadow(2.5, Color.BLACK));
Text name5 = new Text(names[5]);
name5.setStyle("-fx-font: 25 arial;");
name5.setFill(Color.WHITE);
Text role0;
if (kickedOff[0]) {
role0 = new Text("\nkicked off");
} else {
role0 = new Text("\n" + roles[0]);
}
role0.setStyle("-fx-font: 25 arial;");
role0.setFill(Color.WHITE);
Text role1;
if (kickedOff[1]) {
role1 = new Text("\nkicked off");
} else {
role1 = new Text("\n" + roles[1]);
}
role1.setStyle("-fx-font: 25 arial;");
role1.setFill(Color.WHITE);
Text role2;
if (kickedOff[2]) {
role2 = new Text("\nkicked off");
} else {
role2 = new Text("\n" + roles[2]);
}
role2.setStyle("-fx-font: 25 arial;");
role2.setFill(Color.WHITE);
Text role3;
if (kickedOff[3]) {
role3 = new Text("\nkicked off");
} else {
role3 = new Text("\n" + roles[3]);
}
role3.setStyle("-fx-font: 25 arial;");
role3.setFill(Color.WHITE);
Text role4;
if (kickedOff[4]) {
role4 = new Text("\nkicked off");
} else {
role4 = new Text("\n" + roles[4]);
}
role4.setStyle("-fx-font: 25 arial;");
role4.setFill(Color.WHITE);
Text role5;
if (kickedOff[5]) {
role5 = new Text("\nkicked off");
} else {
role5 = new Text("\n" + roles[5]);
}
role5.setStyle("-fx-font: 25 arial;");
role5.setFill(Color.WHITE);
name5.setStyle("-fx-font: 15 serif;");
name5.setFill(Color.rgb(255,250,250,0.6));
name5.setEffect(new DropShadow(2.5, Color.BLACK));
Platform.runLater(new Runnable() {
@Override
@@ -500,22 +461,16 @@ public class GameController implements Initializable {
try {
lableRoom0.getChildren().clear();
lableRoom0.getChildren().add(name0);
lableRoom0.getChildren().add(role0);
lableRoom1.getChildren().clear();
lableRoom1.getChildren().add(name1);
lableRoom1.getChildren().add(role1);
lableRoom2.getChildren().clear();
lableRoom2.getChildren().add(name2);
lableRoom2.getChildren().add(role2);
lableRoom3.getChildren().clear();
lableRoom3.getChildren().add(name3);
lableRoom3.getChildren().add(role3);
lableRoom4.getChildren().clear();
lableRoom4.getChildren().add(name4);
lableRoom4.getChildren().add(role4);
lableRoom5.getChildren().clear();
lableRoom5.getChildren().add(name5);
lableRoom5.getChildren().add(role5);
} catch (Exception e) {
LOGGER.trace("Not yet initialized");
}
@@ -534,17 +489,7 @@ public class GameController implements Initializable {
try {
if(!gameStateModel.getKickedOff()[0]) {
Animation bell = new BellAnimation(noiseImage5, bells);
//wait until it's day:
while (!getGameStateModel().getDayClone()) {
Thread.sleep(100);
}
Thread.sleep(500);
//just so the alarm isn't rung exactly when the day starts, add random delay
Random random = new Random();
Thread.sleep(random.nextInt(1000));
bell.play();
ringBellSound();
waitForDayThenRingBell(bell);
}
} catch (Exception e) {
e.printStackTrace();
@@ -565,16 +510,7 @@ public class GameController implements Initializable {
try {
if(!gameStateModel.getKickedOff()[1]) {
Animation bell = new BellAnimation(noiseImage4, bells);
//wait until it's day:
while (!getGameStateModel().getDayClone()) {
Thread.sleep(100);
}
Thread.sleep(500);
//just so the alarm isn't rung exactly when the day starts, add random delay
Random random = new Random();
Thread.sleep(random.nextInt(1000));
bell.play();
ringBellSound();
waitForDayThenRingBell(bell);
}
} catch (Exception e) {
e.printStackTrace();
@@ -594,17 +530,7 @@ public class GameController implements Initializable {
try {
if(!gameStateModel.getKickedOff()[2]) {
Animation bell = new BellAnimation(noiseImage3, bells);
//wait until it's day:
while (!getGameStateModel().getDayClone()) {
Thread.sleep(100);
}
Thread.sleep(500);
//just so the alarm isn't rung exactly when the day starts, add random delay
Random random = new Random();
Thread.sleep(random.nextInt(1000));
bell.play();
ringBellSound();
waitForDayThenRingBell(bell);
}
} catch (Exception e) {
e.printStackTrace();
@@ -624,17 +550,7 @@ public class GameController implements Initializable {
try {
if(!gameStateModel.getKickedOff()[3]) {
Animation bell = new BellAnimation(noiseImage2, bells);
//wait until it's day:
while (!getGameStateModel().getDayClone()) {
Thread.sleep(100);
}
Thread.sleep(500);
//just so the alarm isn't rung exactly when the day starts, add random delay
Random random = new Random();
Thread.sleep(random.nextInt(1000));
bell.play();
ringBellSound();
waitForDayThenRingBell(bell);
}
} catch (Exception e) {
e.printStackTrace();
@@ -654,17 +570,7 @@ public class GameController implements Initializable {
try {
if(!gameStateModel.getKickedOff()[4]) {
Animation bell = new BellAnimation(noiseImage1, bells);
//wait until it's day:
while (!getGameStateModel().getDayClone()) {
Thread.sleep(100);
}
Thread.sleep(500);
//just so the alarm isn't rung exactly when the day starts, add random delay
Random random = new Random();
Thread.sleep(random.nextInt(1000));
bell.play();
ringBellSound();
waitForDayThenRingBell(bell);
}
} catch (Exception e) {
e.printStackTrace();
@@ -684,16 +590,7 @@ public class GameController implements Initializable {
try {
if(!gameStateModel.getKickedOff()[5]) {
Animation bell = new BellAnimation(noiseImage0, bells);
//wait until it's day:
while (!getGameStateModel().getDayClone()) {
Thread.sleep(100);
}
Thread.sleep(500);
//just so the alarm isn't rung exactly when the day starts, add random delay
Random random = new Random();
Thread.sleep(random.nextInt(1000));
bell.play();
ringBellSound();
waitForDayThenRingBell(bell);
}
} catch (Exception e) {
e.printStackTrace();
@@ -734,6 +631,34 @@ public class GameController implements Initializable {
ChatApp.setGameController(this);
}
public static void waitForDayThenRingBell(Animation bell) {
new Thread(new Runnable() {
@Override
public void run() {
try {
//wait until it's day:
int timeoutCounter = 0; //otherwise this thread can get stuck in a loop if player leaves server
if (!getGameStateModel().getDayClone()) { //used to ring bell immediately if it's already day
while (!getGameStateModel().getDayClone()
&& timeoutCounter < Timer.ghostAfterVoteTime * 15) {
Thread.sleep(100);
timeoutCounter++;
}
//just so the alarm isn't rung exactly when the day starts, also add random delay
Thread.sleep(1000);
Random random = new Random();
Thread.sleep(random.nextInt(1000));
}
} catch (Exception e) {
e.printStackTrace();
}
bell.play();
ringBellSound();
}
}).start();
}
/**
* plays bell sound, but only if it hasn't been played recently, to avoid artefacts due to
* overlapping sounds

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

View File

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

View File

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

View File

@@ -35,8 +35,10 @@ import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.TilePane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.util.Duration;
@@ -47,69 +49,48 @@ public class LoungeSceneViewController implements Initializable {
public static final Logger LOGGER = LogManager.getLogger(LoungeSceneViewController.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
@FXML
private AnchorPane listLobbyAnchorPane;
private AnchorPane highScorePane;
@FXML
private AnchorPane buttonPane;
@FXML
private AnchorPane buttonLobbyPane;
@FXML
private AnchorPane backGroundAnimationPane;
@FXML
private AnchorPane backGroundAnchorPane;
private TilePane listTilePane;
@FXML
private AnchorPane gameDisplayAnchorPane;
@FXML
private AnchorPane listLobbyAnchorPane;
@FXML
private TextFlow highScore;
@FXML
public TextFlow lobbyPrint;
@FXML
private SplitPane chatSplitPane;
@FXML
public Button highScoreButton;
@FXML
private Button leaveLobbyButton;
@FXML
private Button lobbyPrintButton;
@FXML
private Button startGame;
@FXML
private Button newGameButton;
@FXML
private AnchorPane gameAnchorPane;
private ToolBar LobbyControlsToolBar;
@FXML
public ListView<LobbyListItem> LobbyListView;
private BorderPane allLobbyElementsBorderPane;
@FXML
private AnchorPane ChatArea;
@FXML
private Button ChangeNameButton;
@FXML
private Button leaveLobbyButton;
@FXML
private Button LeaveServerButton;
@FXML
private AnchorPane ChatArea;
private AnchorPane backGroundAnchorPane;
@FXML
private AnchorPane backGroundAnimationPane;
@FXML
private BorderPane LoungeSceneBorderPane;
@FXML
private ToolBar NTtBToolBar;
public static ListView<LobbyListItem> lListView;
public static ClientModel client;
private static ChatApp chatApp;
private ChatApp cApp;
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() {
super();
lobbyToMemberssMap = FXCollections.observableHashMap();
lobbyIDtoLobbyMop = new HashMap<>();
}
public void setChatApp(ChatApp chatApp) {
@@ -143,122 +124,20 @@ public class LoungeSceneViewController implements Initializable {
ChangeNameButton.setOnAction(event -> changeName());
LeaveServerButton.setOnAction(event -> leaveServer());
newGameButton.setOnAction(event -> newGame());
LobbyListView.setVisible(true);
lListView = LobbyListView;
LOGGER.debug("Lobby in initialize" + LobbyListView);
addChatView();
addBackgroundDay();
addListOfLobbiesView();
LOGGER.debug("cApp = " + cApp);
LOGGER.debug("chatApp = " + chatApp);
TrainAnimationDayController.setcApp(cApp);
ImageView bgAnimationView = new ImageView();
bgAnimationView.setFitHeight(1950);
bgAnimationView.setFitWidth(6667.968);
LobbyListView.setItems(lobbies);
LOGGER.debug("In Initialize 2 LobbyListView" + LobbyListView);
LobbyListView.setCellFactory(param -> {
ListCell<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() {
@Override
public void run() {
//TODO(SERAINA): bgAnimation?
ImageView bgAnimationView = new ImageView();
bgAnimationView.setFitHeight(1950);
bgAnimationView.setFitWidth(6667.968);
}
});
LOGGER.debug("In Initialize 3 LobbyListView" + LobbyListView);
LobbyListView.setPlaceholder(new Text("No open lobbies!"));
LobbyListView.setVisible(true);
}
/**
@@ -287,8 +166,10 @@ public class LoungeSceneViewController implements Initializable {
public void run() {
try {
LOGGER.debug(" in GameView()" + chatApp);
buttonLobbyPane.setVisible(false);
allLobbyElementsBorderPane.setVisible(false);
gameDisplayAnchorPane.getChildren().add(chatApp.game);
chatApp.getGameController().clearAllNoiseDisplay();
chatApp.getGameController().clearNotificationText();
} catch (Exception e) {
LOGGER.debug("Not yet initialized");
}
@@ -305,7 +186,9 @@ public class LoungeSceneViewController implements Initializable {
public void run() {
try {
trainAnimationDayController.showFullWagon();
buttonLobbyPane.setVisible(true);
allLobbyElementsBorderPane.setVisible(true);
chatApp.getGameController().clearAllNoiseDisplay();
chatApp.getGameController().clearNotificationText();
gameDisplayAnchorPane.getChildren().clear();
} catch (Exception e) {
LOGGER.debug("Not yet initialized");
@@ -344,70 +227,6 @@ public class LoungeSceneViewController implements Initializable {
});
}
/**
* Adds players to a lobby "NMEMB" {@link ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters}
*
* @param lobbyID the Id the Player belongs to
* @param player the player to be added
*/
public void addPlayerToLobby(String lobbyID, String player) {
LOGGER.debug("Lobby ID: " + lobbyID + " player: " + player);
Platform.runLater(new Runnable() {
@Override
public void run() {
Iterator<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
*
@@ -500,68 +319,13 @@ public class LoungeSceneViewController implements Initializable {
for (String argument : arguments) {
LOGGER.debug("HighScore " + argument);
Text text = new Text(argument + System.lineSeparator());
text.setFill(Color.BLACK);
text.setFill(Color.WHITE);
text.setFont(new Font("serif",15));
highScore.getChildren().add(text);
}
}
});
}
/**
* Adds a String to the lobbyPrint TextFlow
*
* @param data the String to be added
*/
public void addLobbyPrint(String data) {
String[] arguments = data.split("/n");
LOGGER.debug(arguments.length);
Platform.runLater(new Runnable() {
@Override
public void run() {
for (String argument : arguments) {
LOGGER.debug("HighScore " + argument);
Text text = new Text(argument + System.lineSeparator());
text.setFill(Color.BLACK);
lobbyPrint.getChildren().add(text);
}
}
});
}
/**
* Clears the lobbyPrint TextFlow
*/
public void clearLobbyPrint() {
Platform.runLater(new Runnable() {
@Override
public void run() {
lobbyPrint.getChildren().clear();
}
});
}
/**
* Should remove the lobby from the lobby list view
*
* @param data to be removed
*/
public void removeLobbyFromView(String data) {
Iterator<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.setWrapText(true);
l.setMaxHeight(Double.MAX_VALUE);
l.setPrefWidth(1135);
l.setPrefWidth(680);
l.setScaleShape(false);
} else {
//t = new Text(client.getUsername() + " (you): " + msg);
@@ -37,7 +37,7 @@ public class ChatLabelConfigurator {
l.setAlignment(Pos.CENTER_RIGHT);
l.setWrapText(true);
l.setMaxHeight(Double.MAX_VALUE);
l.setPrefWidth(1135);
l.setPrefWidth(680);
l.setScaleShape(false);
}
return l;

View File

@@ -212,6 +212,13 @@ public class Protocol {
*/
public static final String noiseNotificationProtocol = "NOISE";
/**
* Used to tell the client to play a sound, namely the sounds for when humans have voted for a human (PLSND$HV),
* when humans have voted for a ghost (PLSND$GV), when humans have won (i.e. have voted for the OG - PLSND$HW)
* or when ghosts have won (PLSND$GW), or the train horn at the start of the game (PLSND$TH). Not used for ghost sounds.
*/
public static final String playSound = "PLSND";
/**
* Sends an information to client at which position in the train from the game (0 to 5) they sit, as soon as the game starts
* {@code POSOF$position}

View File

@@ -129,10 +129,7 @@ public class ClientHandler implements Runnable {
String helper = this.getClientUserName();
String oldName = getClientUserName();
this.clientUserName = nameDuplicateChecker.checkName(newName);
guiUpdateAll(Protocol.printToGUI + "$" + GuiParameters.nameChanged + "$" + oldName + ":"
+ getClientUserName());
sendMsgToClient(Protocol.changedUserName + "$" + newName);
broadcastAnnouncementToAll(helper + " has changed their nickname to " + clientUserName);
try {
getLobby().getGame().getGameState().changeUsername(helper, newName);
@@ -250,12 +247,6 @@ public class ClientHandler implements Runnable {
}
}
public static void guiUpdateAll(String msg) {
System.out.println(msg);
for (ClientHandler client : connectedClients) {
client.sendMsgToClient(msg);
}
}
/**
* Broadcasts a non-chat Message to all clients in the same lobby. This can be used for server
@@ -415,6 +406,7 @@ public class ClientHandler implements Runnable {
Thread t = new Thread(game);
t.start();
l.addGameToRunningGames(game);
sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.viewChangeToGame + "$");
} else {
sendAnnouncementToClient("Only the admin can start the game");
}
@@ -475,9 +467,6 @@ public class ClientHandler implements Runnable {
public void createNewLobby() {
if (Lobby.clientIsInLobby(this) == -1) {
Lobby newGame = new Lobby(this);
guiUpdateAll(
Protocol.printToGUI + "$" + GuiParameters.newLobbyCreated + "$" + getLobby().getLobbyID()
+ ":" + getClientUserName());
LOGGER.debug("Lobby: " + getLobby().getLobbyID() + ". In method createNewLobby()");
} else {
sendAnnouncementToClient("You are already in lobby nr. " + Lobby.clientIsInLobby(this));
@@ -495,8 +484,6 @@ public class ClientHandler implements Runnable {
if (l != null) {
if (l.getLobbyIsOpen()) {
l.addPlayer(this);
guiUpdateAll(Protocol.printToGUI + "$" + GuiParameters.addNewMemberToLobby + "$" + i + ":"
+ getClientUserName());
} else {
sendAnnouncementToClient("The game in Lobby " + l.getLobbyID()
+ " has already started, or the lobby is already full.");
@@ -517,8 +504,6 @@ public class ClientHandler implements Runnable {
l.removePlayer(this);
Game game = l.getGame();
if(l.getAdmin().equals(getClientUserName())){
//Lobby closed because admin left. Lobby must be removed from gui view
guiUpdateAll(Protocol.printToGUI+"$"+GuiParameters.removeLobby+"$"+l.getLobbyID());
}else{
//client just leaves lobby
}

View File

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

View File

@@ -1,6 +1,7 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.server;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import ch.unibas.dmi.dbis.cs108.highscore.OgGhostHighScore;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ServerPinger;
@@ -18,15 +19,25 @@ public class LobbyUpdater implements Runnable{
public void run() {
while (true) {
try {
Thread.sleep(3000);
Thread.sleep(1000);
} catch (InterruptedException e) {
LOGGER.warn(e.getMessage());
}
String lobbiesAsString = Lobby.lobbiesToString();
for (ClientHandler client : ClientHandler.getConnectedClients()) {
String list = OgGhostHighScore.formatGhostHighscoreList();
String[] listarray = list.split("\\R");
StringBuilder forGui = new StringBuilder();
for (String s : listarray) {
forGui.append(s).append("/n");
}
client.sendMsgToClient(Protocol.printToGUI + "$" + GuiParameters.updateHighScore + "$" + forGui.toString());
if (!Lobby.lobbies.isEmpty()) {
client.sendMsgToClient(
Protocol.printToGUI + "$" + GuiParameters.updateLobbyString + "$" + lobbiesAsString);
} else{
client.sendMsgToClient(
Protocol.printToGUI + "$" + GuiParameters.updateLobbyString + "$");
}
}
}

View File

@@ -3,6 +3,17 @@
-fx-background-color: transparent;
}
.text-flow{
-fx-text-alignment: center;
}
.separator *.line {
-fx-border-style: solid;
-fx-border-color: rgb(90,69,51);
-fx-background-color: rgb(90,69,51);
-fx-effect: none;
}
#vBoxChatMessages{
-fx-background-color: transparent;
}

View File

@@ -4,6 +4,7 @@
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ScrollBar?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
@@ -14,16 +15,16 @@
<?import javafx.scene.layout.VBox?>
<?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>
<ImageView fitHeight="700.0" fitWidth="1300.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@images/chatwindow.png" />
</image>
</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>
<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 hgrow="SOMETIMES" minWidth="10.0" percentWidth="100.0" />
</columnConstraints>
@@ -32,18 +33,18 @@
<RowConstraints maxHeight="-Infinity" minHeight="10.0" percentHeight="30.0" valignment="CENTER" vgrow="ALWAYS" />
</rowConstraints>
<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>
<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>
</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>
<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 hgrow="SOMETIMES" percentWidth="5.0" />
<ColumnConstraints hgrow="SOMETIMES" percentWidth="11.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="20.0" percentWidth="84.0" />
<ColumnConstraints hgrow="SOMETIMES" percentWidth="10.0" />
<ColumnConstraints hgrow="SOMETIMES" percentWidth="15.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="20.0" percentWidth="75.0" />
</columnConstraints>
<rowConstraints>
<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" />
</GridPane.margin>
</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>
<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>
@@ -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" />
</children>
</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>
</AnchorPane>

View File

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

View File

@@ -49,7 +49,7 @@
<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">
<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>
<TextFlow fx:id="lableRoom0" 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>
</children>
</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 name="System Bold" size="21.0" />
</font></Button>
<TextFlow fx:id="notificationText" accessibleRole="PARENT" layoutX="210.0" layoutY="20.0" pickOnBounds="false" prefHeight="200.0" prefWidth="800.0" textAlignment="CENTER" />
</font>
</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" />
</children>
</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.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>
<AnchorPane fx:id="scollingAnchorPane">
<AnchorPane fx:id="scollingAnchorPane" minHeight="400.0" minWidth="450.0">
<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>
</content>
</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.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
@@ -16,8 +15,6 @@
<top>
<ToolBar fx:id="NTtBToolBar" pickOnBounds="false" prefHeight="30.0" BorderPane.alignment="CENTER">
<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="leaveLobbyButton" mnemonicParsing="false" onAction="#leaveLobby" pickOnBounds="false" text="Leave Lobby" />
<Button fx:id="ChangeNameButton" mnemonicParsing="false" pickOnBounds="false" text="Change Name" />
@@ -25,39 +22,48 @@
</ToolBar>
</top>
<left>
<AnchorPane prefHeight="316.0" prefWidth="181.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>
<AnchorPane prefWidth="200.0" BorderPane.alignment="CENTER" />
</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>
<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>
<AnchorPane fx:id="ChatArea" pickOnBounds="false" prefHeight="83.0" prefWidth="578.0" />
<AnchorPane fx:id="ChatArea" pickOnBounds="false" prefWidth="578.0" />
</children>
</TilePane>
</bottom>
<right>
<AnchorPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<ListView fx:id="LobbyListView" opacity="0.0" pickOnBounds="false" />
<AnchorPane fx:id="listLobbyAnchorPane" />
</children>
</AnchorPane>
<AnchorPane prefWidth="200.0" BorderPane.alignment="CENTER" />
</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>
<AnchorPane fx:id="gameDisplayAnchorPane" maxHeight="843.75" maxWidth="1500.0" pickOnBounds="false" />
</children>

View File

@@ -4,22 +4,22 @@
}
#NTtBToolBar{
-fx-border-color: grey;
-fx-background-color: rgba(255,255,255,0.5);
-fx-background-color: rgb(15,26,59,0.8);
}
.button{
-fx-background-color: midnightblue;
-fx-text-fill: lightsteelblue;
-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: lightsteelblue;
-fx-text-fill: midnightblue;
-fx-background-color: rgb(90,69,51);
-fx-text-fill: rgb(197,177,131);
}
.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;
}
.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;
-fx-background-color: transparent;
}
.tree-cell .tree-disclosure-node .arrow {

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

View File

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