Merge remote-tracking branch 'origin/NewUI_merge' into NewUI_merge_ryan

This commit is contained in:
Zhi You Tan
2017-09-13 09:44:17 +12:00
29 changed files with 275 additions and 616 deletions
+1
View File
@@ -11,6 +11,7 @@
<properties> <properties>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<dependencies> <dependencies>
+5 -9
View File
@@ -1,20 +1,16 @@
package seng302; package seng302;
import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Level;
import com.jfoenix.controls.JFXDecorator;
import javafx.application.Application; import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage; import javafx.stage.Stage;
import org.apache.commons.cli.*; import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import seng302.visualiser.controllers.ViewManager; import seng302.visualiser.controllers.ViewManager;
import seng302.gameServer.ServerAdvertiser;
import java.io.IOException;
public class App extends Application { public class App extends Application {
@@ -9,12 +9,12 @@ import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import seng302.gameServer.messages.*;
import seng302.model.*;
import seng302.gameServer.messages.BoatAction; import seng302.gameServer.messages.BoatAction;
import seng302.gameServer.messages.BoatStatus; import seng302.gameServer.messages.BoatStatus;
import seng302.gameServer.messages.ChatterMessage; import seng302.gameServer.messages.ChatterMessage;
@@ -38,10 +38,6 @@ import seng302.model.token.TokenType;
import seng302.utilities.GeoUtility; import seng302.utilities.GeoUtility;
import seng302.utilities.XMLParser; import seng302.utilities.XMLParser;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.util.*;
/** /**
* A Static class to hold information about the current state of the game (model) * A Static class to hold information about the current state of the game (model)
* Also contains logic for updating itself on regular time intervals on its own thread * Also contains logic for updating itself on regular time intervals on its own thread
@@ -77,6 +73,7 @@ public class GameState implements Runnable {
private static Double speedMultiplier = 1d; private static Double speedMultiplier = 1d;
private static Boolean customizationFlag; // dirty flag to tell if a player has customized their boat. private static Boolean customizationFlag; // dirty flag to tell if a player has customized their boat.
private static Boolean playerHasLeftFlag;
private static String hostIpAddress; private static String hostIpAddress;
private static List<Player> players; private static List<Player> players;
@@ -106,6 +103,7 @@ public class GameState implements Runnable {
players = new ArrayList<>(); players = new ArrayList<>();
GameState.hostIpAddress = hostIpAddress; GameState.hostIpAddress = hostIpAddress;
customizationFlag = false; customizationFlag = false;
playerHasLeftFlag = false;
speedMultiplier = 1.0; speedMultiplier = 1.0;
currentStage = GameStages.LOBBYING; currentStage = GameStages.LOBBYING;
isRaceStarted = false; isRaceStarted = false;
@@ -839,8 +837,16 @@ public class GameState implements Runnable {
customizationFlag = false; customizationFlag = false;
} }
public static void setPlayerHasLeftFlag(Boolean flag) {
playerHasLeftFlag = flag;
}
public static Boolean getPlayerHasLeftFlag() {
return playerHasLeftFlag;
}
public static Integer getNumberOfPlayers(){ public static Integer getNumberOfPlayers(){
Integer numPlayers = 0; Integer numPlayers = 1;
for(Player p : getPlayers()){ for(Player p : getPlayers()){
if(p.getSocket().isConnected()){ if(p.getSocket().isConnected()){
@@ -1,5 +1,15 @@
package seng302.gameServer; package seng302.gameServer;
import java.io.IOException;
import java.io.StringReader;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.w3c.dom.Document; import org.w3c.dom.Document;
@@ -16,17 +26,6 @@ import seng302.utilities.GeoUtility;
import seng302.utilities.XMLGenerator; import seng302.utilities.XMLGenerator;
import seng302.utilities.XMLParser; import seng302.utilities.XMLParser;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.StringReader;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
/** /**
* A class describing the overall server, which creates and collects server threads for each client * A class describing the overall server, which creates and collects server threads for each client
* Created by wmu16 on 13/07/17. * Created by wmu16 on 13/07/17.
@@ -115,6 +114,20 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
//You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app. //You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app.
while (!terminated) { while (!terminated) {
if (GameState.getPlayerHasLeftFlag()) {
for (ServerToClientThread stc : serverToClientThreads) {
if (!stc.isSocketOpen()) {
GameState.getYachts().remove(stc.getSourceId());
sendSetupMessages();
try {
stc.getSocket().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
GameState.setPlayerHasLeftFlag(false);
}
try { try {
Thread.sleep(1000 / CLIENT_UPDATES_PER_SECOND); Thread.sleep(1000 / CLIENT_UPDATES_PER_SECOND);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@@ -1,17 +1,12 @@
package seng302.gameServer; package seng302.gameServer;
import org.slf4j.Logger; import java.io.BufferedReader;
import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream;
import seng302.gameServer.messages.*; import java.io.IOException;
import seng302.model.Player; import java.io.InputStream;
import seng302.model.ServerYacht; import java.io.InputStreamReader;
import seng302.model.stream.packets.PacketType; import java.io.OutputStream;
import seng302.model.stream.packets.StreamPacket;
import seng302.model.stream.xml.generator.RaceXMLTemplate;
import seng302.utilities.XMLGenerator;
import java.io.*;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException; import java.net.SocketException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -24,7 +19,6 @@ import java.util.zip.Checksum;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import seng302.gameServer.messages.BoatAction; import seng302.gameServer.messages.BoatAction;
import seng302.gameServer.messages.BoatLocationMessage;
import seng302.gameServer.messages.ChatterMessage; import seng302.gameServer.messages.ChatterMessage;
import seng302.gameServer.messages.ClientType; import seng302.gameServer.messages.ClientType;
import seng302.gameServer.messages.CustomizeRequestType; import seng302.gameServer.messages.CustomizeRequestType;
@@ -33,14 +27,11 @@ import seng302.gameServer.messages.RegistrationResponseMessage;
import seng302.gameServer.messages.RegistrationResponseStatus; import seng302.gameServer.messages.RegistrationResponseStatus;
import seng302.gameServer.messages.XMLMessage; import seng302.gameServer.messages.XMLMessage;
import seng302.gameServer.messages.XMLMessageSubType; import seng302.gameServer.messages.XMLMessageSubType;
import seng302.gameServer.messages.YachtEventCodeMessage;
import seng302.model.Player; import seng302.model.Player;
import seng302.model.ServerYacht; import seng302.model.ServerYacht;
import seng302.model.stream.packets.PacketType; import seng302.model.stream.packets.PacketType;
import seng302.model.stream.packets.StreamPacket; import seng302.model.stream.packets.StreamPacket;
import seng302.model.stream.xml.generator.RaceXMLTemplate; import seng302.model.stream.xml.generator.RaceXMLTemplate;
import seng302.model.stream.xml.generator.RegattaXMLTemplate;
import seng302.model.token.Token;
import seng302.utilities.XMLGenerator; import seng302.utilities.XMLGenerator;
/** /**
@@ -104,6 +95,10 @@ public class ServerToClientThread implements Runnable {
thread.start(); thread.start();
} }
public Integer getSourceId() {
return sourceId;
}
private void setUpPlayer(){ private void setUpPlayer(){
BufferedReader fn; BufferedReader fn;
String fName = ""; String fName = "";
@@ -228,9 +223,11 @@ public class ServerToClientThread implements Runnable {
} }
} catch (Exception e) { } catch (Exception e) {
closeSocket(); closeSocket();
GameState.setPlayerHasLeftFlag(true);
return; return;
} }
} }
GameState.setPlayerHasLeftFlag(true);
logger.warn("Closed serverToClientThread" + thread, 1); logger.warn("Closed serverToClientThread" + thread, 1);
} }
@@ -264,6 +261,10 @@ public class ServerToClientThread implements Runnable {
} }
} }
public Boolean isSocketOpen() {
return !socket.isClosed();
}
private int readByte() throws Exception { private int readByte() throws Exception {
int currentByte = -1; int currentByte = -1;
try { try {
+5 -4
View File
@@ -26,7 +26,9 @@ public class Sounds {
} }
} }
public static void setMutes() {
static void setMutes() {
if (soundPlayer != null) { if (soundPlayer != null) {
soundPlayer.setMute(soundEffectsMuted); soundPlayer.setMute(soundEffectsMuted);
} }
@@ -49,14 +51,14 @@ public class Sounds {
toggleMuteMusic(); toggleMuteMusic();
} }
public static void toggleMuteMusic() { static void toggleMuteMusic() {
musicMuted = !musicMuted; musicMuted = !musicMuted;
if (musicPlayer != null) { if (musicPlayer != null) {
musicPlayer.setMute(musicMuted); musicPlayer.setMute(musicMuted);
} }
} }
public static void toggleMuteEffects() { static void toggleMuteEffects() {
soundEffectsMuted = !soundEffectsMuted; soundEffectsMuted = !soundEffectsMuted;
if (soundPlayer != null) { if (soundPlayer != null) {
soundPlayer.setMute(soundEffectsMuted); soundPlayer.setMute(soundEffectsMuted);
@@ -188,5 +190,4 @@ public class Sounds {
} }
} }
} }
@@ -44,7 +44,6 @@ import seng302.utilities.XMLGenerator;
import seng302.utilities.XMLParser; import seng302.utilities.XMLParser;
import seng302.visualiser.controllers.FinishScreenViewController; import seng302.visualiser.controllers.FinishScreenViewController;
import seng302.visualiser.controllers.LobbyController; import seng302.visualiser.controllers.LobbyController;
import seng302.visualiser.controllers.LobbyController_old;
import seng302.visualiser.controllers.RaceViewController; import seng302.visualiser.controllers.RaceViewController;
import seng302.visualiser.controllers.ViewManager; import seng302.visualiser.controllers.ViewManager;
@@ -201,23 +200,6 @@ public class GameClient {
socketThread.addStreamObserver(this::parsePackets); socketThread.addStreamObserver(this::parsePackets);
} }
/**
* Loads a view of the lobby into the clients pane
*
* @return the lobby controller.
*/
private LobbyController_old loadLobby() {
FXMLLoader fxmlLoader = new FXMLLoader(
GameClient.class.getResource("/views/LobbyView.fxml"));
try {
holderPane.getChildren().clear();
holderPane.getChildren().add(fxmlLoader.load());
} catch (IOException e) {
e.printStackTrace();
}
return fxmlLoader.getController();
}
private void loadRaceView() { private void loadRaceView() {
FXMLLoader fxmlLoader = loadFXMLToHolder("/views/RaceView.fxml"); FXMLLoader fxmlLoader = loadFXMLToHolder("/views/RaceView.fxml");
holderPane.getScene().setOnKeyPressed(this::keyPressed); holderPane.getScene().setOnKeyPressed(this::keyPressed);
@@ -1,76 +0,0 @@
package seng302.visualiser.controllers;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import seng302.gameServer.messages.CustomizeRequestType;
import seng302.utilities.Sounds;
import seng302.visualiser.ClientToServerThread;
public class CustomizationController_old {
@FXML
private TextField nameField;
@FXML
private ColorPicker boatColorPicker;
@FXML
private Button customizeSubmit;
private LobbyController_old lc;
private ClientToServerThread socketThread;
private Stage windowStage;
public void initialize() {
}
public void setServerThread(ClientToServerThread ctsThread) {
this.socketThread = ctsThread;
}
@FXML
public void submitCustomization() {
Sounds.playButtonClick();
// System.out.println("Attempting to send");
socketThread.sendCustomizationRequest(CustomizeRequestType.NAME, nameField.getText().getBytes());
// TODO: 16/08/17 ajm412: Turn colors into byte array.
Color color = boatColorPicker.getValue();
short red = (short) (color.getRed() * 255);
short green = (short) (color.getGreen() * 255);
short blue = (short) (color.getBlue() * 255);
byte[] colorArray = new byte[3];
colorArray[0] = (byte) red;
colorArray[1] = (byte) green;
colorArray[2] = (byte) blue;
socketThread.sendCustomizationRequest(CustomizeRequestType.COLOR, colorArray);
lc.setPlayersColor(color);
windowStage.close();
}
public void setLobbyController(LobbyController_old lc) {
this.lc = lc;
}
public void setStage(Stage stage) {
this.windowStage = stage;
}
public void setPlayerName(String name) {
this.nameField.setText(name);
}
public void setPlayerColor(Color playerColor) {
this.boatColorPicker.setValue(playerColor);
}
}
@@ -31,6 +31,7 @@ import seng302.model.stream.xml.parser.RaceXMLData;
import seng302.utilities.Sounds; import seng302.utilities.Sounds;
import seng302.visualiser.GameView; import seng302.visualiser.GameView;
import seng302.visualiser.controllers.cells.PlayerCell; import seng302.visualiser.controllers.cells.PlayerCell;
import seng302.visualiser.controllers.dialogs.BoatCustomizeController;
public class LobbyController implements Initializable { public class LobbyController implements Initializable {
@@ -51,7 +52,6 @@ public class LobbyController implements Initializable {
private Pane serverMap; private Pane serverMap;
//---------FXML END---------// //---------FXML END---------//
private List<LobbyController_old.LobbyCloseListener> lobbyListeners = new ArrayList<>();
private RaceState raceState; private RaceState raceState;
private JFXDialog customizationDialog; private JFXDialog customizationDialog;
public Color playersColor; public Color playersColor;
@@ -93,8 +93,8 @@ public class LobbyController implements Initializable {
Integer playerId = ViewManager.getInstance().getGameClient().getServerThread().getClientId(); Integer playerId = ViewManager.getInstance().getGameClient().getServerThread().getClientId();
String name = ViewManager.getInstance().getGameClient().getPlayerNames().get(playerId - 1); String name = ViewManager.getInstance().getGameClient().getPlayerNames().get(playerId - 1);
Color playerColor = Colors.getColor( playerId - 1); playersColor = Colors.getColor(playerId - 1);
customizationDialog = ViewManager.getInstance().loadCustomizationDialog(serverListMainStackPane, this, playerColor, name); customizationDialog = createCustomizeDialog();
customizeButton.setOnMouseReleased(event -> { customizeButton.setOnMouseReleased(event -> {
Sounds.playButtonClick(); Sounds.playButtonClick();
@@ -109,6 +109,32 @@ public class LobbyController implements Initializable {
initMapPreview(); initMapPreview();
} }
private JFXDialog createCustomizeDialog() {
// TODO: 12/09/17 ajm412: Why is this here? is there no better way we can do this? Ideally inside the LobbyController.
FXMLLoader dialog = new FXMLLoader(
getClass().getResource("/views/dialogs/BoatCustomizeDialog.fxml"));
JFXDialog customizationDialog = null;
try {
customizationDialog = new JFXDialog(serverListMainStackPane, dialog.load(),
JFXDialog.DialogTransition.CENTER);
} catch (IOException e) {
e.printStackTrace();
}
BoatCustomizeController controller = dialog.getController();
controller.setParentController(this);
controller.setPlayerColor(this.playersColor);
return customizationDialog;
}
/**
*
*/
private void refreshMapView(){ private void refreshMapView(){
RaceXMLData raceData = ViewManager.getInstance().getGameClient().getCourseData(); RaceXMLData raceData = ViewManager.getInstance().getGameClient().getCourseData();
List<Limit> border = raceData.getCourseLimit(); List<Limit> border = raceData.getCourseLimit();
@@ -122,12 +148,8 @@ public class LobbyController implements Initializable {
gameView.updateCourse(marks, corners); gameView.updateCourse(marks, corners);
} }
private void getPlayerColors() {
}
/** /**
* * Initializes a top down preview of the race course map.
*/ */
private void initMapPreview() { private void initMapPreview() {
gameView = new GameView(); gameView = new GameView();
@@ -163,7 +185,7 @@ public class LobbyController implements Initializable {
} }
/** /**
* * Refreshes the list of players and their boats, as a series of VBox PlayerCell objects.
*/ */
private void refreshPlayerList() { private void refreshPlayerList() {
playerListVBox.getChildren().clear(); playerListVBox.getChildren().clear();
@@ -192,17 +214,12 @@ public class LobbyController implements Initializable {
} }
} }
/**
*
*/
private void leaveLobby() { private void leaveLobby() {
ViewManager.getInstance().getGameClient().stopGame(); ViewManager.getInstance().getGameClient().stopGame();
ViewManager.getInstance().goToStartView(); ViewManager.getInstance().goToStartView();
} }
/**
*
*/
public void disableReadyButton() { public void disableReadyButton() {
this.beginRaceButton.setDisable(true); this.beginRaceButton.setDisable(true);
this.beginRaceButton.setText("Waiting for host..."); this.beginRaceButton.setText("Waiting for host...");
@@ -1,249 +0,0 @@
package seng302.visualiser.controllers;
import com.sun.media.jfxmedia.logging.Logger;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javafx.application.Platform;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import seng302.gameServer.GameStages;
import seng302.gameServer.GameState;
import seng302.model.Colors;
import seng302.model.RaceState;
import seng302.visualiser.ClientToServerThread;
/**
* A class describing the actions of the lobby screen
* Created by wmu16 on 10/07/17.
*/
public class LobbyController_old {
public enum CloseStatus {
LEAVE,
READY
}
@FunctionalInterface
public interface LobbyCloseListener {
void notify(CloseStatus exitCause);
}
@FXML
private Text lobbyIpText;
@FXML
private Button readyButton;
@FXML
private Button customizeButton;
@FXML
private TextArea playerOneTxt;
@FXML
private TextArea playerTwoTxt;
@FXML
private TextArea playerThreeTxt;
@FXML
private TextArea playerFourTxt;
@FXML
private TextArea playerFiveTxt;
@FXML
private TextArea playerSixTxt;
@FXML
private TextArea playerSevenTxt;
@FXML
private TextArea playerEightTxt;
@FXML
private ImageView firstImageView;
@FXML
private ImageView secondImageView;
@FXML
private ImageView thirdImageView;
@FXML
private ImageView fourthImageView;
@FXML
private ImageView fifthImageView;
@FXML
private ImageView sixthImageView;
@FXML
private ImageView seventhImageView;
@FXML
private ImageView eighthImageView;
@FXML
private Text timeUntilStart;
@FXML
private Text courseNameText;
private List<ImageView> imageViews = new ArrayList<>();
private List<TextArea> listViews = new ArrayList<>();
private RaceState raceState;
private ClientToServerThread socketThread;
private Stage customizeStage;
private Color playersColor;
private int MAX_NUM_PLAYERS = 8;
private Integer playerID;
private List<LobbyCloseListener> lobbyListeners = new ArrayList<>();
private ObservableList<String> players;
/**
* Add all FXObjects to lists and initialize images.
*/
public void initialize() {
Collections.addAll(listViews,
playerOneTxt, playerTwoTxt, playerThreeTxt, playerFourTxt, playerFiveTxt, playerSixTxt,
playerSevenTxt, playerEightTxt
);
Collections.addAll(imageViews,
firstImageView, secondImageView, thirdImageView, fourthImageView,
fifthImageView, sixthImageView, seventhImageView, eighthImageView
);
initialiseImageView();
timeUntilStart.setText("Waiting For Host...");
}
/**
* Updates player names.
*/
private void updatePlayers() {
//Update players if one added.
for (int i = 0; i < players.size(); i++) {
listViews.get(i).setText(players.get(i));
if (playerID == (i + 1)) {
listViews.get(i).setText(listViews.get(i).getText() + " (YOU)");
}
imageViews.get(i).setVisible(true);
}
//Update empty text fields if player left.
for (int i = MAX_NUM_PLAYERS-1; i >= players.size(); i--) {
listViews.get(i).setText("");
imageViews.get(i).setVisible(false);
}
}
/**
* Sets all images and hides them till players join.
*/
private void initialiseImageView() {
for (ImageView viewer : imageViews) {
viewer.setImage(
new Image(
RaceViewController.class.getResourceAsStream(
"/pics/sail.png")
)
);
viewer.setVisible(false);
}
}
@FXML
public void customize() {
Parent root;
try {
FXMLLoader fxmlLoader = new FXMLLoader(LobbyController_old.class.getResource("/views/customizeView.fxml"));
root = fxmlLoader.load();
root.getStylesheets().add("/css/master.css");
customizeStage = new Stage();
customizeStage.setTitle("Customize Boat");
customizeStage.setScene(new Scene(root, 700, 450));
CustomizationController_old cc = fxmlLoader.getController();
cc.setServerThread(this.socketThread);
cc.setPlayerName(this.players.get(playerID - 1));
if (this.playersColor == null) {
this.playersColor = Colors.getColor(playerID - 1);
}
cc.setPlayerColor(this.playersColor);
cc.setStage(customizeStage); // pass the stage through so it can be closed later.
cc.setLobbyController(this);
customizeStage.show();
} catch (IOException e) {
Logger.logMsg(4, "Failed to load Customization View from resources.");
}
}
public void setSocketThread(ClientToServerThread thread) {
this.socketThread = thread;
}
@FXML
public void leaveLobbyButtonPressed() {
// TODO: 10/07/17 wmu16 - Finish function!
GameState.setCurrentStage(GameStages.CANCELLED);
// TODO: 20/07/17 wmu16 - Implement some way of terminating the game
for (LobbyCloseListener readyListener : lobbyListeners)
readyListener.notify(CloseStatus.LEAVE);
}
@FXML
public void readyButtonPressed() {
GameState.setCurrentStage(GameStages.PRE_RACE);
// Do countdown logic here
for (LobbyCloseListener readyListener : lobbyListeners)
readyListener.notify(CloseStatus.READY);
customizeButton.setDisable(true);
}
public void setTitle (String title) {
lobbyIpText.setText(title);
}
public void setCourseName(String courseName){
courseNameText.setText(courseName);
}
public void addCloseListener(LobbyCloseListener listener) {
lobbyListeners.add(listener);
}
public void setPlayerListSource (ObservableList<String> players) {
this.players = players;
players.addListener((ListChangeListener<? super String>) (lcl) ->
Platform.runLater(this::updatePlayers)
);
Platform.runLater(this::updatePlayers);
}
public void setPlayerID(Integer id) {
playerID = id;
}
public void updateRaceState(RaceState raceState){
this.raceState = raceState;
/*if (this.customizeStage != null) {
this.customizeStage.close();
}*/ // TODO: 17/08/17 ajm412: close the customization window if the host starts the game while customizing
if (!customizeButton.isDisabled()) {
customizeButton.setDisable(true);
}
timeUntilStart.setText("Starting in: " + raceState.getRaceTimeStr());
}
public void disableReadyButton () {
readyButton.setDisable(true);
readyButton.setVisible(false);
}
//TODO here newui
public void setPlayersColor(Color playerColor) {
this.playersColor = playerColor;
}
}
@@ -11,6 +11,8 @@ import java.util.concurrent.TimeUnit;
import javafx.animation.Timeline; import javafx.animation.Timeline;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.ReadOnlyBooleanProperty; import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
@@ -174,6 +176,19 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
rvAnchorPane.setOnMouseClicked((event) -> rvAnchorPane.setOnMouseClicked((event) ->
rvAnchorPane.requestFocus() rvAnchorPane.requestFocus()
); );
//Makes the chat history non transparent when clicked on
chatInput.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
Boolean newValue) {
if (newValue) {
chatHistory.increaseOpacity();
} else {
chatHistory.decreaseOpacity();
}
}
});
} }
public void loadRace ( public void loadRace (
@@ -771,8 +786,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
} }
public boolean isChatInputFocused() { public boolean isChatInputFocused() {
// return chatInput.focusedProperty().getValue(); return chatInput.focusedProperty().getValue();
return false;
} }
public String readChatInput() { public String readChatInput() {
@@ -18,7 +18,6 @@ import javafx.geometry.Pos;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane; import javafx.scene.control.ScrollPane;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -57,10 +56,14 @@ public class ServerListController implements Initializable, ServerListenerDelega
private Label noServersFound; private Label noServersFound;
private Logger logger = LoggerFactory.getLogger(ServerListController.class); private Logger logger = LoggerFactory.getLogger(ServerListController.class);
// TODO: 12/09/17 ajm412: break this method down, its way too long.
@Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
serverListVBox.minWidthProperty().bind(serverListScrollPane.widthProperty()); serverListVBox.minWidthProperty().bind(serverListScrollPane.widthProperty());
// Set Event Bindings // Set Event Bindings
connectButton.setOnMouseEntered(event -> Sounds.playHoverSound());
serverListHostButton.setOnMouseEntered(event -> Sounds.playHoverSound());
connectButton.setOnMouseReleased(event -> { connectButton.setOnMouseReleased(event -> {
attemptToDirectConnect(); attemptToDirectConnect();
Sounds.playButtonClick(); Sounds.playButtonClick();
@@ -126,7 +129,7 @@ public class ServerListController implements Initializable, ServerListenerDelega
} }
/** /**
* * Validates the connection and attempts to connect to a given hostname and port number.
*/ */
private void attemptToDirectConnect() { private void attemptToDirectConnect() {
if (validateDirectConnection(serverHostName.getText(), serverPortNumber.getText())) { if (validateDirectConnection(serverHostName.getText(), serverPortNumber.getText())) {
@@ -135,10 +138,10 @@ public class ServerListController implements Initializable, ServerListenerDelega
} }
/** /**
* * Checks if the hostName and portNumber are valid values to connect to.
* @param hostName * @param hostName host name to check.
* @param portNumber * @param portNumber port number to check
* @return * @return boolean value if host and port number are valid values
*/ */
private Boolean validateDirectConnection(String hostName, String portNumber) { private Boolean validateDirectConnection(String hostName, String portNumber) {
Boolean hostNameValid = ValidationTools.validateTextField(serverHostName); Boolean hostNameValid = ValidationTools.validateTextField(serverHostName);
@@ -148,7 +151,7 @@ public class ServerListController implements Initializable, ServerListenerDelega
} }
/** /**
* * Connects the user to a lobby via the Direct Connect form.
*/ */
private void DirectConnect() { private void DirectConnect() {
Sounds.playButtonClick(); Sounds.playButtonClick();
@@ -156,8 +159,8 @@ public class ServerListController implements Initializable, ServerListenerDelega
} }
/** /**
* * Refreshes the list of available servers.
* @param servers * @param servers A list of ServerDescription objects showing available servers.
*/ */
private void refreshServers(List<ServerDescription> servers) { private void refreshServers(List<ServerDescription> servers) {
serverListVBox.getChildren().clear(); serverListVBox.getChildren().clear();
@@ -184,11 +187,6 @@ public class ServerListController implements Initializable, ServerListenerDelega
} }
} }
public void playButtonHoverSound(MouseEvent mouseEvent) {
Sounds.playHoverSound();
}
@Override @Override
public void serverRemoved(List<ServerDescription> servers) { public void serverRemoved(List<ServerDescription> servers) {
Platform.runLater(() -> refreshServers(servers)); Platform.runLater(() -> refreshServers(servers));
@@ -5,15 +5,11 @@ import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.List; import java.util.List;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import seng302.gameServer.ServerDescription; import seng302.gameServer.ServerDescription;
@@ -34,20 +30,21 @@ public class StartScreenController implements Initializable{
private List<ServerDescription> servers; private List<ServerDescription> servers;
private GameClient gameClient; private GameClient gameClient;
/** public void initialize(URL location, ResourceBundle resources) {
* startBtn.setOnMousePressed(event -> {
*/ startBtn.setText("LOADING...");
private void setInitialDropShadow() { Sounds.playButtonClick();
DropShadow dropShadow = new DropShadow(); });
dropShadow.setRadius(10.0);
dropShadow.setOffsetX(3.0); startBtn.setOnMouseReleased(event -> goToServerBrowser());
dropShadow.setOffsetY(4.0); startBtn.setOnMouseEntered(event -> Sounds.playHoverSound());
dropShadow.setColor(Color.color(0, 0, 0, 0.5));
headText.setEffect(dropShadow); preloadServerListView();
} }
/** /**
* * Preloads the server list view to reduce load time between start screen and server list screen.
*/ */
private void preloadServerListView(){ private void preloadServerListView(){
try { try {
@@ -60,7 +57,7 @@ public class StartScreenController implements Initializable{
} }
/** /**
* * Changes the view to the Server Browser.
*/ */
private void goToServerBrowser() { private void goToServerBrowser() {
try { try {
@@ -70,40 +67,4 @@ public class StartScreenController implements Initializable{
} }
} }
public void initialize(URL location, ResourceBundle resources) {
startBtn.setOnMousePressed(event -> {
startBtn.setText("LOADING...");
Sounds.playButtonClick();
});
startBtn.setOnMouseReleased(event -> goToServerBrowser());
setInitialDropShadow();
preloadServerListView();
}
public void toggleMusic(ActionEvent actionEvent) {
Sounds.toggleMuteMusic();
Sounds.playButtonClick();
if (Sounds.isMusicMuted()) {
// muteMusicButton.setText("UnMute Music");
} else {
// muteMusicButton.setText("Mute Music");
}
}
public void toggleSounds(ActionEvent actionEvent) {
Sounds.toggleMuteEffects();
Sounds.playButtonClick();
if (Sounds.isSoundEffectsMuted()) {
// muteSoundsButton.setText("UnMute Sounds");
} else {
// muteSoundsButton.setText("Mute Sounds");
}
}
public void playButtonHoverSound(MouseEvent mouseEvent) {
Sounds.playHoverSound();
}
} }
@@ -2,7 +2,6 @@ package seng302.visualiser.controllers;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDecorator; import com.jfoenix.controls.JFXDecorator;
import com.jfoenix.controls.JFXDialog;
import com.jfoenix.svg.SVGGlyph; import com.jfoenix.svg.SVGGlyph;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@@ -13,9 +12,9 @@ import javafx.scene.Cursor;
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.scene.SceneAntialiasing;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.stage.Stage; import javafx.stage.Stage;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -24,7 +23,6 @@ import seng302.gameServer.ServerAdvertiser;
import seng302.utilities.BonjourInstallChecker; import seng302.utilities.BonjourInstallChecker;
import seng302.utilities.Sounds; import seng302.utilities.Sounds;
import seng302.visualiser.GameClient; import seng302.visualiser.GameClient;
import seng302.visualiser.controllers.dialogs.BoatCustomizeController;
public class ViewManager { public class ViewManager {
@@ -78,7 +76,7 @@ public class ViewManager {
gameClient = new GameClient(decorator); gameClient = new GameClient(decorator);
stage.getIcons().add(new Image(getClass().getResourceAsStream("/PP.png"))); stage.getIcons().add(new Image(getClass().getResourceAsStream("/PP.png")));
Scene scene = new Scene(decorator, 1200, 800); Scene scene = new Scene(decorator, 1200, 800, false, SceneAntialiasing.BALANCED);
stage.setMinHeight(800); stage.setMinHeight(800);
stage.setMinWidth(1200); stage.setMinWidth(1200);
stage.setScene(scene); stage.setScene(scene);
@@ -105,6 +103,12 @@ public class ViewManager {
}); });
} }
/**
* Sets the decorator when a new one is created (and ideally the old one destroyed)
* Also allows injection of buttons into the decorator for custom functions.
*
* @param newDecorator The new JFXDecorator to handle the game window.
*/
private void setDecorator(JFXDecorator newDecorator) { private void setDecorator(JFXDecorator newDecorator) {
decorator = newDecorator; decorator = newDecorator;
@@ -152,6 +156,9 @@ public class ViewManager {
} }
/**
* Determines if a PC has compatibility with the bonjour protocol for server detection.
*/
private void checkCompatibility() { private void checkCompatibility() {
if (BonjourInstallChecker.isBonjourSupported()) { if (BonjourInstallChecker.isBonjourSupported()) {
BonjourInstallChecker.openInstallUrl(); BonjourInstallChecker.openInstallUrl();
@@ -209,6 +216,11 @@ public class ViewManager {
return playerList; return playerList;
} }
/**
* Change the view to the Lobby Screen
* @param disableReadyButton Boolean value so that clients can't try start a game.
* @return A LobbyController object for the Lobby Screen.
*/
public LobbyController goToLobby(Boolean disableReadyButton) { public LobbyController goToLobby(Boolean disableReadyButton) {
FXMLLoader loader = loadFxml("/views/LobbyView.fxml"); FXMLLoader loader = loadFxml("/views/LobbyView.fxml");
@@ -226,6 +238,11 @@ public class ViewManager {
return loader.getController(); return loader.getController();
} }
/**
* Sets up the view for the race. Creating a new decorator and destroying the old one.
* @return A RaceViewController for the race view screen.
*/
public RaceViewController loadRaceView() { public RaceViewController loadRaceView() {
FXMLLoader loader = loadFxml("/views/RaceView.fxml"); FXMLLoader loader = loadFxml("/views/RaceView.fxml");
@@ -276,29 +293,4 @@ public class ViewManager {
return loader.getController(); return loader.getController();
} }
public JFXDialog loadCustomizationDialog(StackPane parent, LobbyController lobbyController,
Color playerColor, String name) {
FXMLLoader dialog = loadFxml("/views/dialogs/BoatCustomizeDialog.fxml");
JFXDialog customizationDialog = null;
try {
customizationDialog = new JFXDialog(parent, dialog.load(),
JFXDialog.DialogTransition.CENTER);
} catch (IOException e) {
e.printStackTrace();
}
BoatCustomizeController controller = dialog.getController();
controller.setParentController(lobbyController);
controller.setPlayerColor(playerColor);
controller.setPlayerName(name);
controller.setServerThread(gameClient.getServerThread());
controller.setPlayerColor(lobbyController.playersColor);
return customizationDialog;
}
} }
@@ -3,11 +3,9 @@ package seng302.visualiser.controllers.cells;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Group; import javafx.scene.Group;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import seng302.utilities.Sounds;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType; import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
import seng302.visualiser.fxObjects.assets_3D.BoatModel; import seng302.visualiser.fxObjects.assets_3D.BoatModel;
import seng302.visualiser.fxObjects.assets_3D.ModelFactory; import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
@@ -34,12 +32,13 @@ public class PlayerCell {
} }
public void initialize() { public void initialize() {
// Set Player Name
playerName.setText(name); playerName.setText(name);
// Add Rotating Boat to Player Cell with players color on it.
Group group = new Group(); Group group = new Group();
boatPane.getChildren().add(group); boatPane.getChildren().add(group);
BoatModel bo = ModelFactory.boatIconView(BoatMeshType.DINGHY, this.boatColor); BoatModel bo = ModelFactory.boatIconView(BoatMeshType.DINGHY, this.boatColor);
group.getChildren().add(bo.getAssets()); group.getChildren().add(bo.getAssets());
} }
public Integer getPlayerId() { public Integer getPlayerId() {
@@ -53,8 +52,4 @@ public class PlayerCell {
public Color getBoatColor() { public Color getBoatColor() {
return boatColor; return boatColor;
} }
public void playButtonHoverSound(MouseEvent mouseEvent) {
Sounds.playHoverSound();
}
} }
@@ -1,27 +1,15 @@
package seng302.visualiser.controllers.cells; package seng302.visualiser.controllers.cells;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDecorator;
import com.sun.org.apache.bcel.internal.classfile.Unknown;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URL; import java.net.URL;
import java.net.UnknownHostException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import com.jfoenix.controls.JFXTextField;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color; import javafx.scene.layout.VBox;
import seng302.gameServer.ServerDescription; import seng302.gameServer.ServerDescription;
import seng302.utilities.Sounds; import seng302.utilities.Sounds;
import seng302.visualiser.GameClient;
import seng302.visualiser.controllers.ViewManager; import seng302.visualiser.controllers.ViewManager;
public class ServerCell implements Initializable { public class ServerCell implements Initializable {
@@ -29,6 +17,8 @@ public class ServerCell implements Initializable {
//--------FXML BEGIN--------// //--------FXML BEGIN--------//
//Layout //Layout
@FXML @FXML
private VBox serverCellVBox;
@FXML
private GridPane serverListCell; private GridPane serverListCell;
//Server Information //Server Information
@FXML @FXML
@@ -66,21 +56,21 @@ public class ServerCell implements Initializable {
serverPlayerCount.setText(currPlayerCount); serverPlayerCount.setText(currPlayerCount);
mapName.setText(mapNameString); mapName.setText(mapNameString);
serverCellVBox.setOnMouseEntered(event -> Sounds.playHoverSound());
serverConnButton.setOnMouseReleased(event -> { serverConnButton.setOnMouseReleased(event -> {
Sounds.playButtonClick(); Sounds.playButtonClick();
joinServer(); joinServer();
}); });
} }
/** /**
* * Attempts to connect to the chosen server using the button on the serverCell.
*/ */
private void joinServer() { private void joinServer() {
System.out.println("Connecting to " + serverName.getText()); System.out.println("Connecting to " + serverName.getText());
ViewManager.getInstance().getGameClient().runAsClient(hostName, portNumber); ViewManager.getInstance().getGameClient().runAsClient(hostName, portNumber);
} }
public void playButtonHoverSound(MouseEvent mouseEvent) {
Sounds.playHoverSound();
}
} }
@@ -4,18 +4,17 @@ import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXColorPicker; import com.jfoenix.controls.JFXColorPicker;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import com.jfoenix.validation.RequiredFieldValidator; import com.jfoenix.validation.RequiredFieldValidator;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.stage.Stage;
import seng302.gameServer.messages.CustomizeRequestType; import seng302.gameServer.messages.CustomizeRequestType;
import seng302.utilities.Sounds; import seng302.utilities.Sounds;
import seng302.visualiser.ClientToServerThread; import seng302.visualiser.ClientToServerThread;
import java.net.URL;
import java.util.ResourceBundle;
import seng302.visualiser.controllers.LobbyController; import seng302.visualiser.controllers.LobbyController;
import seng302.visualiser.controllers.ViewManager;
import seng302.visualiser.validators.FieldLengthValidator; import seng302.visualiser.validators.FieldLengthValidator;
import seng302.visualiser.validators.ValidationTools; import seng302.visualiser.validators.ValidationTools;
@@ -44,6 +43,8 @@ public class BoatCustomizeController implements Initializable{
submitCustomization(); submitCustomization();
}); });
socketThread = ViewManager.getInstance().getGameClient().getServerThread();
RequiredFieldValidator playerNameReqValidator = new RequiredFieldValidator(); RequiredFieldValidator playerNameReqValidator = new RequiredFieldValidator();
playerNameReqValidator.setMessage("Player name required."); playerNameReqValidator.setMessage("Player name required.");
@@ -56,7 +57,7 @@ public class BoatCustomizeController implements Initializable{
} }
/** /**
* * Attempts to submit a valid customization packet for boat name and boat color.
*/ */
private void submitCustomization() { private void submitCustomization() {
@@ -88,10 +89,6 @@ public class BoatCustomizeController implements Initializable{
this.colorPicker.setValue(playerColor); this.colorPicker.setValue(playerColor);
} }
public void setServerThread(ClientToServerThread ctsThread) {
this.socketThread = ctsThread;
}
public void setParentController(LobbyController lobbyController){ public void setParentController(LobbyController lobbyController){
this.lobbyController = lobbyController; this.lobbyController = lobbyController;
} }
@@ -4,6 +4,9 @@ import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXSlider; import com.jfoenix.controls.JFXSlider;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import com.jfoenix.validation.RequiredFieldValidator; import com.jfoenix.validation.RequiredFieldValidator;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.control.Label; import javafx.scene.control.Label;
@@ -12,9 +15,6 @@ import seng302.gameServer.ServerDescription;
import seng302.utilities.Sounds; import seng302.utilities.Sounds;
import seng302.visualiser.controllers.ViewManager; import seng302.visualiser.controllers.ViewManager;
import seng302.visualiser.validators.FieldLengthValidator; import seng302.visualiser.validators.FieldLengthValidator;
import java.net.URL;
import java.util.ResourceBundle;
import seng302.visualiser.validators.ValidationTools; import seng302.visualiser.validators.ValidationTools;
public class ServerCreationController implements Initializable { public class ServerCreationController implements Initializable {
@@ -48,10 +48,11 @@ public class ServerCreationController implements Initializable {
Sounds.playButtonClick(); Sounds.playButtonClick();
validateServerSettings(); validateServerSettings();
}); });
} }
/** /**
* * Validates that a server has a valid name and creates the server.
*/ */
private void validateServerSettings() { private void validateServerSettings() {
submitBtn.setText("CREATING..."); submitBtn.setText("CREATING...");
@@ -63,7 +64,7 @@ public class ServerCreationController implements Initializable {
} }
/** /**
* * Creates a server with a given set of details.
*/ */
private void createServer() { private void createServer() {
ServerDescription serverDescription = ViewManager.getInstance().getGameClient() ServerDescription serverDescription = ViewManager.getInstance().getGameClient()
@@ -75,7 +76,7 @@ public class ServerCreationController implements Initializable {
} }
/** /**
* * Updates a label as the user slides along the max players slider.
*/ */
private void updateMaxPlayerLabel() { private void updateMaxPlayerLabel() {
maxPlayersSlider.setValue(Math.floor(maxPlayersSlider.getValue())); maxPlayersSlider.setValue(Math.floor(maxPlayersSlider.getValue()));
@@ -24,10 +24,10 @@ public class ChatHistory extends ScrollPane {
this.setMaxWidth(Double.MAX_VALUE); this.setMaxWidth(Double.MAX_VALUE);
this.setVbarPolicy(ScrollBarPolicy.AS_NEEDED); this.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
this.setHbarPolicy(ScrollBarPolicy.NEVER); this.setHbarPolicy(ScrollBarPolicy.NEVER);
this.lookup(".scroll-pane").setStyle("-fx-background: rgba(255, 255, 255, 0.1); -fx-background-color: rgba(255, 255, 255, 0.1);"); this.lookup(".scroll-pane").setStyle("-fx-background: rgba(135, 206, 235, 0.0); -fx-background-color: rgba(135, 206, 235, 0.0);");
this.textFlow.setStyle( this.textFlow.setStyle(
"-fx-background: rgba(255, 255, 255, 0.1); -fx-background-color: rgba(255, 255, 255, 0.1); -fx-padding: 10px" "-fx-background: rgba(135, 206, 235, 0.0); -fx-background-color: rgba(135, 206, 235, 0.0); -fx-padding: 10px"
); );
//This makes the window auto scroll. //This makes the window auto scroll.
textFlow.getChildren().addListener((ListChangeListener<Node>) c -> textFlow.getChildren().addListener((ListChangeListener<Node>) c ->
@@ -71,6 +71,19 @@ public class ChatHistory extends ScrollPane {
} }
public void increaseOpacity() {
this.lookup(".scroll-pane").setStyle("-fx-background: rgba(255, 255, 255, 0.2); -fx-background-color: rgba(255, 255, 255, 0.2);");
this.textFlow.setStyle(
"-fx-background: rgba(255, 255, 255, 0.2); -fx-background-color: rgba(255, 255, 255, 0.2); -fx-padding: 10px"
);
}
public void decreaseOpacity() {
this.lookup(".scroll-pane").setStyle("-fx-background: rgba(135, 206, 235, 0.0); -fx-background-color: rgba(135, 206, 235, 0.0);");
this.textFlow.setStyle(
"-fx-background: rgba(135, 206, 235, 0.0); -fx-background-color: rgba(135, 206, 235, 0.0); -fx-padding: 10px"
);
}
} }
@@ -4,7 +4,7 @@ import javafx.animation.AnimationTimer;
import javafx.scene.Group; import javafx.scene.Group;
/** /**
* Created by CJIRWIN on 7/09/2017. * Class for generic imported 3D model. Animation terminates on if removed from scene.
*/ */
public class Model { public class Model {
@@ -16,6 +16,12 @@ public class Model {
this.animationTimer = animation; this.animationTimer = animation;
if (animation != null) { if (animation != null) {
animation.start(); animation.start();
assets.sceneProperty().addListener((obs, oldVal, newVal) -> {
if (newVal == null) {
animationTimer.stop();
animationTimer = null;
}
});
} }
} }
@@ -2,7 +2,6 @@ package seng302.visualiser.fxObjects.assets_3D;
import com.interactivemesh.jfx.importer.col.ColModelImporter; import com.interactivemesh.jfx.importer.col.ColModelImporter;
import com.interactivemesh.jfx.importer.stl.StlMeshImporter; import com.interactivemesh.jfx.importer.stl.StlMeshImporter;
import java.util.Random;
import javafx.animation.AnimationTimer; import javafx.animation.AnimationTimer;
import javafx.geometry.Point3D; import javafx.geometry.Point3D;
import javafx.scene.AmbientLight; import javafx.scene.AmbientLight;
@@ -15,6 +14,8 @@ import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale; import javafx.scene.transform.Scale;
import javafx.scene.transform.Translate; import javafx.scene.transform.Translate;
/** /**
* Factory class for creating 3D models of boats. * Factory class for creating 3D models of boats.
*/ */
@@ -22,28 +23,30 @@ public class ModelFactory {
public static BoatModel boatIconView(BoatMeshType boatType, Color primaryColour) { public static BoatModel boatIconView(BoatMeshType boatType, Color primaryColour) {
Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour); Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour);
final Rotate animationRotate = new Rotate(0, new Point3D(0,0,1));
boatAssets.getTransforms().addAll( boatAssets.getTransforms().addAll(
new Scale(10, 10, 10), new Scale(3.3, 3.3, 3.3),
new Rotate(45, new Point3D(0,0,1)), new Rotate(-70, new Point3D(1,0,0)),
new Rotate(90, new Point3D(0, 1, 0)), new Translate(13,50, 0),
new Rotate(270, new Point3D(1, 0, 0)), animationRotate
new Translate(12, 14, 0)
); );
boatAssets.getTransforms().add(animationRotate);
BoatModel bo = new BoatModel(boatAssets, null, boatType); BoatModel bo = new BoatModel(boatAssets, null, boatType);
bo.showSail();
bo.rotateSail(45); bo.rotateSail(45);
bo.setAnimation(new AnimationTimer() {
Group group = bo.getAssets();
double boatAngle = 0;
int id = new Random().nextInt();
bo.setAnimation(new AnimationTimer() {
double boatAngle = 0;
Rotate rotate = animationRotate;
@Override @Override
public void handle(long now) { public void handle(long now) {
((Rotate) group.getTransforms().get(3)).setAngle(boatAngle++); boatAngle += 0.5;
rotate.setAngle(boatAngle);
} }
}); });
boatAssets.getChildren().add(new AmbientLight(new Color(1, 1, 1, 0.01))); boatAssets.getChildren().addAll(
new AmbientLight()
);
return bo; return bo;
} }
@@ -52,19 +55,21 @@ public class ModelFactory {
boatAssets.getTransforms().addAll( boatAssets.getTransforms().addAll(
new Scale(40, 40, 40), new Scale(40, 40, 40),
new Rotate(90, new Point3D(0,0,1)), new Rotate(90, new Point3D(0,0,1)),
new Rotate(90, new Point3D(0, 1, 0)), new Rotate(90, new Point3D(0, 1, 0))
new Rotate(0, new Point3D(1,1,1))
); );
// TODO: 7/09/17 This seems like it will never be garbage claimed. Might have to call BoatModel.stopAnimation();
final Rotate animationRotate = new Rotate(0, new Point3D(1,1,1));
boatAssets.getTransforms().add(animationRotate);
return new BoatModel(boatAssets, new AnimationTimer() { return new BoatModel(boatAssets, new AnimationTimer() {
private double rotation = 0; private double rotation = 0;
private final Group group = boatAssets; private Rotate rotate = animationRotate;
@Override @Override
public void handle(long now) { public void handle(long now) {
rotation += 0.5; rotation += 0.5;
((Rotate) group.getTransforms().get(3)).setAngle(rotation); rotate.setAngle(rotation);
} }
}, boatType); }, boatType);
} }
+1
View File
@@ -13,6 +13,7 @@
-fx-pp-dropshadow-light: dropshadow(gaussian, rgba(0, 0, 0, 0.1), 10.0, 0.2, 3, 4); -fx-pp-dropshadow-light: dropshadow(gaussian, rgba(0, 0, 0, 0.1), 10.0, 0.2, 3, 4);
-fx-pp-dropshadow-dark: dropshadow(gaussian, rgba(0, 0, 0, 0.3), 10.0, 0.2, 5, 6); -fx-pp-dropshadow-dark: dropshadow(gaussian, rgba(0, 0, 0, 0.3), 10.0, 0.2, 5, 6);
-fx-pp-dropshadow-headers: dropshadow(gaussian, rgba(0, 0, 0, 0.5), 10.0, 0.2, 3, 4);
} }
/*GridPane .jfx-button {*/ /*GridPane .jfx-button {*/
@@ -22,4 +22,5 @@
-fx-background-color: transparent; -fx-background-color: transparent;
-fx-font-size: 80px; -fx-font-size: 80px;
-fx-text-fill: -fx-pp-light-text-color; -fx-text-fill: -fx-pp-light-text-color;
-fx-effect: -fx-pp-dropshadow-headers;
} }
+5 -2
View File
@@ -18,7 +18,10 @@
<children> <children>
<GridPane fx:id="connectGridPane" GridPane.rowIndex="2"> <GridPane fx:id="connectGridPane" GridPane.rowIndex="2">
<children> <children>
<JFXButton fx:id="connectButton" buttonType="RAISED" onMouseEntered="#playButtonHoverSound" prefHeight="45.0" prefWidth="220.0" ripplerFill="#3493e3" text="CONNECT" textFill="WHITE" GridPane.columnIndex="5" GridPane.halignment="RIGHT" GridPane.valignment="CENTER"> <JFXButton fx:id="connectButton" buttonType="RAISED" prefHeight="45.0"
prefWidth="220.0" ripplerFill="#3493e3" text="CONNECT" textFill="WHITE"
GridPane.columnIndex="5" GridPane.halignment="RIGHT"
GridPane.valignment="CENTER">
<GridPane.margin> <GridPane.margin>
<Insets right="50.0" /> <Insets right="50.0" />
</GridPane.margin> </GridPane.margin>
@@ -74,7 +77,7 @@
</padding> </padding>
</Label> </Label>
<JFXButton id="hostButton" fx:id="serverListHostButton" buttonType="RAISED" <JFXButton id="hostButton" fx:id="serverListHostButton" buttonType="RAISED"
onMouseEntered="#playButtonHoverSound" prefHeight="45.0" prefWidth="220.0" prefHeight="45.0" prefWidth="220.0"
text="HOST" GridPane.columnIndex="1" GridPane.halignment="RIGHT" text="HOST" GridPane.columnIndex="1" GridPane.halignment="RIGHT"
GridPane.valignment="CENTER"> GridPane.valignment="CENTER">
<GridPane.margin> <GridPane.margin>
@@ -26,7 +26,8 @@
<Insets bottom="150.0" /> <Insets bottom="150.0" />
</StackPane.margin> </StackPane.margin>
</Label> </Label>
<JFXButton fx:id="startBtn" buttonType="RAISED" onMouseEntered="#playButtonHoverSound" prefHeight="80.0" prefWidth="337.0" text="START"> <JFXButton fx:id="startBtn" buttonType="RAISED" prefHeight="80.0" prefWidth="337.0"
text="START">
<font> <font>
<Font size="20.0" /> <Font size="20.0" />
</font> </font>
@@ -9,7 +9,9 @@
<?import javafx.scene.layout.RowConstraints?> <?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?> <?import javafx.scene.text.Font?>
<VBox fx:id="serverCellVBox" maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" onMouseEntered="#playButtonHoverSound" prefHeight="95.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> <VBox fx:id="serverCellVBox" maxHeight="-Infinity" maxWidth="1.7976931348623157E308"
minHeight="-Infinity" minWidth="-Infinity" prefHeight="95.0" prefWidth="900.0"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<stylesheets> <stylesheets>
<String fx:value="/css/Master.css"/> <String fx:value="/css/Master.css"/>
<String fx:value="/css/cells/ServerCell.css" /> <String fx:value="/css/cells/ServerCell.css" />
@@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ColorPicker?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Text?>
<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: #2C2c36;"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="seng302.visualiser.controllers.CustomizationController_old">
<columnConstraints>
<ColumnConstraints fillWidth="false" halignment="CENTER" hgrow="SOMETIMES"
maxWidth="1.7976931348623157E308" minWidth="1.0" percentWidth="10.0" prefWidth="1.0"/>
<ColumnConstraints fillWidth="false" halignment="CENTER" hgrow="SOMETIMES" maxWidth="299.0"
minWidth="10.0" percentWidth="30.0" prefWidth="299.0"/>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="299.0" minWidth="10.0" percentWidth="50.0"
prefWidth="154.0"/>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="123.0" minWidth="0.0" percentWidth="10.0"
prefWidth="122.0"/>
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" percentHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" percentHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
</rowConstraints>
<children>
<TextField fx:id="nameField" maxWidth="200.0" minWidth="200.0" prefWidth="200.0"
GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="1"
GridPane.valignment="CENTER"/>
<ColorPicker fx:id="boatColorPicker" prefWidth="200.0" style="-fx-background-color: eeeeee;"
GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="2"
GridPane.valignment="CENTER"/>
<Text fill="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="Player Name"
GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<Text fill="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="Boat Color"
GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<Button fx:id="customizeSubmit" mnemonicParsing="false" onAction="#submitCustomization"
text="Submit" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="3"
GridPane.valignment="CENTER"/>
</children>
</GridPane>
@@ -0,0 +1,25 @@
package seng302.utilities;
import static org.junit.Assert.assertEquals;
import org.junit.Assert;
import org.junit.Test;
/**
* Used to test the muting functionality of the sounds util
* Created by kre39 on 12/09/17.
*/
public class SoundsTest {
@Test
public void testMutes() throws Exception {
Sounds.setMutes();
Assert.assertFalse(Sounds.isMusicMuted());
Assert.assertFalse(Sounds.isSoundEffectsMuted());
Sounds.toggleAllSounds();
Sounds.toggleMuteEffects();
Sounds.toggleMuteMusic();
Assert.assertFalse(Sounds.isMusicMuted());
Assert.assertFalse(Sounds.isSoundEffectsMuted());
}
}
+10 -2
View File
@@ -43,8 +43,11 @@ public class SendChatSteps {
ie.printStackTrace(); ie.printStackTrace();
} }
mst.startGame(); mst.startGame();
Thread.sleep(200); try {
} Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
} }
@When("^the first client has sent the message \"([^\"]*)\"$") @When("^the first client has sent the message \"([^\"]*)\"$")
@@ -54,6 +57,11 @@ public class SendChatSteps {
@Then("^the other client should receive the message \"([^\"]*)\"$") @Then("^the other client should receive the message \"([^\"]*)\"$")
public void the_other_client_should_receive_the_message(String arg1) throws Throwable { public void the_other_client_should_receive_the_message(String arg1) throws Throwable {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
Object[] packets = host.getPacketQueue().toArray(); Object[] packets = host.getPacketQueue().toArray();
Pair<Integer, String> message = StreamParser.extractChatterText((StreamPacket) packets[packets.length - 1]); Pair<Integer, String> message = StreamParser.extractChatterText((StreamPacket) packets[packets.length - 1]);
Assert.assertEquals("[time_prefix] <name_prefix> " + arg1, message.getValue()); Assert.assertEquals("[time_prefix] <name_prefix> " + arg1, message.getValue());