mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a1d468c689 | |||
| 4f80640718 | |||
| 27379ae96d | |||
| ce3e08abfc | |||
| 923c381797 | |||
| ece45ff967 | |||
| 02dc1dbd3d | |||
| d9b9c2f808 | |||
| 4e3de02a93 | |||
| 261f68f143 | |||
| ed9b7acc62 | |||
| 74c1219e0d | |||
| 83218ae0a0 | |||
| 0231c43a2c | |||
| a05a41d5ec | |||
| 06bc3644bc | |||
| 7620f0023e | |||
| 77ee1ebbc0 | |||
| 6d0835b0cf | |||
| 54410efa12 | |||
| 74241ee819 | |||
| a9ce8901f5 | |||
| 8810554ce9 | |||
| 7e3ed872ed | |||
| 21ce34dda2 | |||
| 2bf318a122 | |||
| e56d284792 | |||
| 80c26a9e4a | |||
| c4a3df32c8 | |||
| 1e19dd5ab6 | |||
| 1aedcaddf5 | |||
| d7fc339ad5 | |||
| 02aabc3162 | |||
| d2a05de25a | |||
| c72c4929ff | |||
| 265b20ad61 |
@@ -103,8 +103,7 @@ public class App extends Application {
|
||||
public void run() {
|
||||
System.gc();
|
||||
}
|
||||
}, 0, 1200);
|
||||
|
||||
}, 0, 1_000);
|
||||
|
||||
try {
|
||||
parseArgs(args);
|
||||
|
||||
@@ -48,7 +48,7 @@ public class DiscoveryServer {
|
||||
" .:;...'cxxxxxxxxxxxxoc;,::,..cdl;;l' \n" +
|
||||
" .cl;':,'';oxxxxxxdxxxxxx:....,cooc,cO; \n" +
|
||||
" .,,,::;,lxoc:,,:lxxxxxxxxxxxo:,,;lxxl;'oNc \n" +
|
||||
" .cdxo;':lxxxxxxc'';cccccoxxxxxxxxxxxxo,.;lc. " + ANSI_YELLOW + "Party-Parrots-At-Sea Discovery Server v0.1 " + selectedColor +"\n" +
|
||||
" .cdxo;':lxxxxxxc'';cccccoxxxxxxxxxxxxo,.;lc. " + ANSI_YELLOW + "Party-Parrots-At-Sea Discovery Server v1.0.0 (Release) " + selectedColor +"\n" +
|
||||
" .loc'.'lxxxxxxxxocc;''''';ccoxxxxxxxxx:..oc \n" +
|
||||
"olc,..',:cccccccccccc:;;;;;;;;:ccccccccc,.'c, \n" +
|
||||
"Ol;......................................;l' ");
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class DiscoveryServerClient {
|
||||
private final Integer UPDATE_INTERVAL_MS = 5000;
|
||||
private final Integer UPDATE_INTERVAL_MS = 1000;
|
||||
|
||||
private static String roomCode = null;
|
||||
private Timer serverListingUpdateTimer;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package seng302.discoveryServer.util;
|
||||
|
||||
public class ServerListing {
|
||||
public final static int SERVER_TTL_DEFAULT = 10;
|
||||
public final static int SERVER_TTL_DEFAULT = 5;
|
||||
|
||||
private String serverName = "";
|
||||
private String mapName = "";
|
||||
|
||||
@@ -68,7 +68,7 @@ public class GameState implements Runnable {
|
||||
|
||||
//Collision constants
|
||||
private static final Double MARK_COLLISION_DISTANCE = 15d;
|
||||
public static final Double YACHT_COLLISION_DISTANCE = 25.0;
|
||||
public static final Double YACHT_COLLISION_DISTANCE = 15.0;
|
||||
private static final Double BOUNCE_DISTANCE_MARK = 20.0;
|
||||
public static final Double BOUNCE_DISTANCE_YACHT = 30.0;
|
||||
private static final Double COLLISION_VELOCITY_PENALTY = 0.3;
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.net.ServerSocket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import org.slf4j.Logger;
|
||||
@@ -19,12 +18,6 @@ import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||
import seng302.utilities.GeoUtility;
|
||||
|
||||
import java.io.IOException;
|
||||
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
|
||||
@@ -32,22 +25,32 @@ import java.util.TimerTask;
|
||||
*/
|
||||
public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(MainServerThread.class);
|
||||
|
||||
private static final int PORT = 4942;
|
||||
private static int selectedPort = PORT;
|
||||
private static final Integer CLIENT_UPDATES_PER_SECOND = 60;
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(MainServerThread.class);
|
||||
private boolean terminated;
|
||||
|
||||
private Thread thread;
|
||||
private boolean hasStarted = false;
|
||||
|
||||
private ServerSocket serverSocket = null;
|
||||
private ArrayList<ServerToClientThread> serverToClientThreads = new ArrayList<>();
|
||||
private static Integer capacity;
|
||||
private RaceXMLData raceXMLData;
|
||||
private RegattaXMLData regattaXMLData;
|
||||
private boolean serverStarted = false;
|
||||
|
||||
public MainServerThread() {
|
||||
new GameState();
|
||||
try {
|
||||
serverSocket = new ServerSocket(0);
|
||||
selectedPort = serverSocket.getLocalPort();
|
||||
} catch (IOException e) {
|
||||
logger.trace("IO error in server thread handler upon trying to make new server socket",
|
||||
0);
|
||||
}
|
||||
terminated = false;
|
||||
Thread thread = new Thread(this, "MainServer");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private void startAdvertisingServer() {
|
||||
Integer capacity = GameState.getCapacity();
|
||||
@@ -65,25 +68,12 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
.setMapName(regattaXMLData.getCourseName())
|
||||
.setCapacity(capacity)
|
||||
.setNumberOfPlayers(numPlayers - 1)
|
||||
.registerGame(PORT, regattaXMLData.getRegattaName());
|
||||
.registerGame(selectedPort, regattaXMLData.getRegattaName());
|
||||
} catch (IOException e) {
|
||||
logger.warn("Could not register server");
|
||||
}
|
||||
}
|
||||
|
||||
public MainServerThread() {
|
||||
new GameState();
|
||||
try {
|
||||
serverSocket = new ServerSocket(PORT);
|
||||
} catch (IOException e) {
|
||||
logger.trace("IO error in server thread handler upon trying to make new server socket",
|
||||
0);
|
||||
}
|
||||
terminated = false;
|
||||
thread = new Thread(this, "MainServer");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private void startServer() {
|
||||
PolarTable.parsePolarFile(getClass().getResourceAsStream("/server_config/acc_polars.csv"));
|
||||
MessageFactory.updateXMLGenerator(raceXMLData, regattaXMLData);
|
||||
@@ -122,7 +112,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
} catch (InterruptedException e) {
|
||||
logger.trace("Interrupted exception in Main Server Thread thread sleep", 1);
|
||||
}
|
||||
if (GameState.getCurrentStage() == GameStages.LOBBYING && GameState.getCustomizationFlag()) {
|
||||
if (GameState.getCurrentStage() == GameStages.LOBBYING && GameState
|
||||
.getCustomizationFlag()) {
|
||||
MessageFactory.updateBoats(new ArrayList<>(GameState.getYachts().values()));
|
||||
sendSetupMessages();
|
||||
GameState.resetCustomizationFlag();
|
||||
@@ -141,7 +132,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
else if (GameState.getCurrentStage() == GameStages.FINISHED) {
|
||||
broadcastMessage(MessageFactory.getRaceStatusMessage());
|
||||
try {
|
||||
Thread.sleep(1000); //Hackish fix to make sure all threads have sent closing RaceStatus
|
||||
Thread.sleep(
|
||||
1000); //Hackish fix to make sure all threads have sent closing RaceStatus
|
||||
terminate();
|
||||
} catch (InterruptedException ie) {
|
||||
logger.trace("Thread interrupted while waiting to terminate clients", 1);
|
||||
@@ -149,7 +141,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
}
|
||||
}
|
||||
try {
|
||||
synchronized (this){
|
||||
synchronized (this) {
|
||||
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
|
||||
serverToClientThread.terminate();
|
||||
}
|
||||
@@ -205,9 +197,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
startServer();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//serverToClientThread.addConnectionListener(this::sendSetupMessages);
|
||||
}
|
||||
|
||||
serverToClientThreads.add(serverToClientThread);
|
||||
|
||||
try {
|
||||
@@ -216,7 +207,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
logger.warn("Couldn't update advertisement");
|
||||
}
|
||||
|
||||
while (regattaXMLData == null && raceXMLData == null){
|
||||
while (regattaXMLData == null && raceXMLData == null) {
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
@@ -242,7 +233,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
|
||||
if (serverToClientThread.getSocket() == player.getSocket()) {
|
||||
closedConnection = serverToClientThread;
|
||||
} else if (GameState.getCurrentStage() != GameStages.RACING){
|
||||
} else if (GameState.getCurrentStage() != GameStages.RACING) {
|
||||
serverToClientThread.sendSetupMessages();
|
||||
}
|
||||
}
|
||||
@@ -255,8 +246,10 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
logger.warn("Couldn't update advertisement");
|
||||
}
|
||||
|
||||
if (closedConnection != null) {
|
||||
closedConnection.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
public void startGame() {
|
||||
try {
|
||||
@@ -279,10 +272,6 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
}
|
||||
}, 0, 500);
|
||||
|
||||
|
||||
// if (GameState.getCurrentStage() == GameStages.LOBBYING) {
|
||||
// sendSetupMessages();
|
||||
// }
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
@@ -293,108 +282,6 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
* Initialise boats to specific spaced out geopoints behind starting line.
|
||||
*/
|
||||
private void initialiseBoatPositions() {
|
||||
// CompoundMark cm = GameState.getMarkOrder().getMarkOrder().get(0);
|
||||
// GeoPoint startMark1 = cm.getSubMark(1);
|
||||
// GeoPoint startMark2 = cm.getSubMark(2);
|
||||
//
|
||||
// // Calculating midpoint
|
||||
// Double perpendicularAngle = GeoUtility.getBearing(startMark1, startMark2);
|
||||
// Double length = GeoUtility.getDistance(startMark1, startMark2);
|
||||
// GeoPoint midpoint = GeoUtility.getGeoCoordinate(startMark1, perpendicularAngle, length / 2);
|
||||
//
|
||||
// // Setting each boats position side by side
|
||||
// final double SEPARATION = 50.0; // distance apart in meters
|
||||
//
|
||||
// int boatIndex = 0;
|
||||
// for (ServerYacht yacht : GameState.getYachts().values()) {
|
||||
// int distanceApart = boatIndex / 2;
|
||||
//
|
||||
// if (boatIndex % 2 == 1 && boatIndex != 0) {
|
||||
// distanceApart++;
|
||||
// distanceApart *= -1;
|
||||
// }
|
||||
//
|
||||
// GeoPoint spawnMark = GeoUtility
|
||||
// .getGeoCoordinate(midpoint, perpendicularAngle, distanceApart * SEPARATION);
|
||||
//
|
||||
// if (yacht.getHeading() < perpendicularAngle) {
|
||||
// spawnMark = GeoUtility
|
||||
// .getGeoCoordinate(spawnMark, perpendicularAngle + 90, SEPARATION);
|
||||
// } else {
|
||||
// spawnMark = GeoUtility
|
||||
// .getGeoCoordinate(spawnMark, perpendicularAngle + 270, SEPARATION);
|
||||
// }
|
||||
//
|
||||
// yacht.setLocation(spawnMark);
|
||||
// boatIndex++;
|
||||
// }
|
||||
|
||||
// final double SEPARATION = 50.0; // distance apart in meters
|
||||
//
|
||||
// //Reverse of the angle from start to first mark
|
||||
// double angleToFirstMark = 360 - GeoUtility.getBearing(
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getMidPoint(),
|
||||
// GameState.getMarkOrder().getMarkOrder().get(1).getMidPoint()
|
||||
// );
|
||||
//
|
||||
// //Length of start line
|
||||
// double startLineLength = GeoUtility.getDistance(
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(1),
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(2)
|
||||
// );
|
||||
//
|
||||
// //Angle of start line
|
||||
// double startMarkToMarkAngle = GeoUtility.getBearing(
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(1),
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(2)
|
||||
// );
|
||||
//
|
||||
// //How many yachts can fit along the start line
|
||||
// int spacesAlongLine = (int) Math.round(startLineLength / SEPARATION);
|
||||
// //The free space left by the boats.
|
||||
// double buffer = (startLineLength % SEPARATION) / 2;
|
||||
//
|
||||
// //Randomize starting order.
|
||||
// List<ServerYacht> serverYachtList = new ArrayList<>(GameState.getYachts().values());
|
||||
// Collections.shuffle(serverYachtList);
|
||||
//
|
||||
// //set the starting point away from start line.
|
||||
// GeoPoint startingPoint = GeoUtility.getGeoCoordinate(
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(1),
|
||||
// angleToFirstMark, SEPARATION
|
||||
// );
|
||||
//
|
||||
// //Move it along the start line
|
||||
// startingPoint = GeoUtility.getGeoCoordinate(
|
||||
// startingPoint, startMarkToMarkAngle, buffer
|
||||
// );
|
||||
//
|
||||
// int yachtCount = 0;
|
||||
// int repeats = 0;
|
||||
//
|
||||
// GeoPoint yachtLocation;
|
||||
//
|
||||
// for (ServerYacht serverYacht : serverYachtList) {
|
||||
//
|
||||
// //Move away from start line
|
||||
// yachtLocation = GeoUtility.getGeoCoordinate(
|
||||
// startingPoint, angleToFirstMark,repeats * SEPARATION
|
||||
// );
|
||||
// //Move along start line
|
||||
// yachtLocation = GeoUtility.getGeoCoordinate(
|
||||
// yachtLocation, startMarkToMarkAngle, yachtCount * SEPARATION
|
||||
// );
|
||||
// serverYacht.setLocation(yachtLocation);
|
||||
// serverYacht.setHeading(GeoUtility.getBearing(
|
||||
// yachtLocation, GameState.getMarkOrder().getMarkOrder().get(1).getMidPoint()
|
||||
// ));
|
||||
// //Set location for next yacht
|
||||
// yachtCount++;
|
||||
// if (yachtCount > spacesAlongLine) {
|
||||
// yachtCount = 0;
|
||||
// repeats++;
|
||||
// }
|
||||
// }
|
||||
|
||||
final double DISTANCE_TO_START = 75d;
|
||||
final double YACHT_SEPARATION = 20d;
|
||||
@@ -434,14 +321,16 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
Collections.shuffle(randomisedYachts);
|
||||
while (randomisedYachts.size() > 0) {
|
||||
|
||||
int numYachtsInLine = spacesAlongLine > randomisedYachts.size() ? randomisedYachts.size() : spacesAlongLine;
|
||||
int numYachtsInLine =
|
||||
spacesAlongLine > randomisedYachts.size() ? randomisedYachts.size()
|
||||
: spacesAlongLine;
|
||||
double yachtSpace = numYachtsInLine * YACHT_SEPARATION / 2;
|
||||
|
||||
GeoPoint firstYachtPoint = GeoUtility.getGeoCoordinate(
|
||||
startingPoint, startMarkToMarkAngle + 180, yachtSpace
|
||||
);
|
||||
|
||||
for (int i=0; i<numYachtsInLine; i++){
|
||||
for (int i = 0; i < numYachtsInLine; i++) {
|
||||
randomisedYachts.get(0).setHeading(angleFromStart);
|
||||
randomisedYachts.get(0).setLocation(firstYachtPoint);
|
||||
firstYachtPoint = GeoUtility.getGeoCoordinate(
|
||||
@@ -459,4 +348,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
public boolean hasStarted() {
|
||||
return hasStarted;
|
||||
}
|
||||
|
||||
public int getPortNumber() {
|
||||
return selectedPort;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package seng302.gameServer;
|
||||
|
||||
import seng302.gameServer.messages.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import seng302.gameServer.messages.BoatLocationMessage;
|
||||
@@ -25,9 +24,6 @@ import seng302.model.token.Token;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.utilities.XMLGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A Class for interfacing between the data we have in the GameState to the messages we need to send
|
||||
* through the MainServerThread.
|
||||
@@ -77,9 +73,6 @@ public class MessageFactory {
|
||||
}
|
||||
|
||||
public static void updateBoats(List<ServerYacht> yachts) {
|
||||
// for (ServerYacht serverYacht : yachts) {
|
||||
// System.out.println(serverYacht);
|
||||
// }
|
||||
xmlGenerator.getRace().setBoats(yachts);
|
||||
String xmlStr = xmlGenerator.getBoatsAsXml();
|
||||
MessageFactory.boats = new XMLMessage(xmlStr, XMLMessageSubType.BOAT, xmlStr.length());
|
||||
|
||||
@@ -146,6 +146,8 @@ public class ServerAdvertiser {
|
||||
public void unregister(){
|
||||
if (serviceInfo != null)
|
||||
jmdnsInstance.unregisterService(serviceInfo);
|
||||
|
||||
repositoryClient.unregister();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,15 +13,11 @@ import javafx.beans.property.ReadOnlyIntegerProperty;
|
||||
import javafx.beans.property.ReadOnlyIntegerWrapper;
|
||||
import javafx.beans.property.ReadOnlyLongProperty;
|
||||
import javafx.beans.property.ReadOnlyLongWrapper;
|
||||
import javafx.beans.value.ObservableObjectValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.paint.Color;
|
||||
import jdk.nashorn.internal.objects.annotations.Function;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||
|
||||
/**
|
||||
@@ -286,6 +282,7 @@ public class ClientYacht extends Observable {
|
||||
|
||||
public void setHeading(Double heading) {
|
||||
this.heading = heading;
|
||||
System.out.println(heading);
|
||||
setHeadingProperty();
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,6 @@ public class CompoundMark {
|
||||
getSubMark(1).setRoundingSide(RoundingSide.STARBOARD);
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package seng302.visualiser;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.util.Pair;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import seng302.gameServer.messages.*;
|
||||
import seng302.model.stream.packets.PacketType;
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
import seng302.utilities.XMLParser;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -43,7 +34,7 @@ import seng302.model.stream.xml.generator.RaceXMLTemplate;
|
||||
import seng302.model.stream.xml.generator.RegattaXMLTemplate;
|
||||
import seng302.utilities.XMLGenerator;
|
||||
import seng302.utilities.XMLParser;
|
||||
import seng302.visualiser.controllers.ViewManager;
|
||||
|
||||
|
||||
/**
|
||||
* A class describing a single connection to a Server for the purposes of sending and receiving on
|
||||
@@ -180,10 +171,12 @@ public class ClientToServerThread implements Runnable {
|
||||
notifyDisconnectListeners("Connection to server was terminated");
|
||||
closeSocket();
|
||||
|
||||
Platform.runLater(() -> {
|
||||
ViewManager.getInstance().showErrorSnackBar("Server rejected connection.");
|
||||
ViewManager.getInstance().goToStartView();
|
||||
});
|
||||
//thread.interrupt();
|
||||
|
||||
// Platform.runLater(() -> {
|
||||
// ViewManager.getInstance().showErrorSnackBar("Server rejected connection.");
|
||||
// ViewManager.getInstance().goToStartView();
|
||||
// });
|
||||
}
|
||||
|
||||
public void sendCustomizationRequest(CustomizeRequestType reqType, byte[] payload) {
|
||||
|
||||
@@ -5,9 +5,7 @@ import java.text.SimpleDateFormat;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.Timer;
|
||||
@@ -17,7 +15,6 @@ import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.util.Pair;
|
||||
import seng302.gameServer.GameStages;
|
||||
@@ -55,7 +52,6 @@ import seng302.visualiser.controllers.dialogs.PopupDialogController;
|
||||
*/
|
||||
public class GameClient {
|
||||
|
||||
private Pane holderPane;
|
||||
private ClientToServerThread socketThread;
|
||||
private MainServerThread server;
|
||||
|
||||
@@ -77,10 +73,8 @@ public class GameClient {
|
||||
/**
|
||||
* Create an instance of the game client. Does not do anything until run with runAsClient()
|
||||
* runAsHost().
|
||||
* @param holder The JavaFX Pane that the visual elements for the race will be inserted into.
|
||||
*/
|
||||
public GameClient(Pane holder) {
|
||||
this.holderPane = holder;
|
||||
public GameClient() {
|
||||
this.gameKeyBind = GameKeyBind.getInstance();
|
||||
}
|
||||
|
||||
@@ -89,7 +83,7 @@ public class GameClient {
|
||||
* @param ipAddress IP to connect to.
|
||||
* @param portNumber Port to connect to.
|
||||
*/
|
||||
public void runAsClient(String ipAddress, Integer portNumber) {
|
||||
public boolean runAsClient(String ipAddress, Integer portNumber) {
|
||||
try {
|
||||
startClientToServerThread(ipAddress, portNumber);
|
||||
socketThread.addDisconnectionListener((cause) -> {
|
||||
@@ -100,41 +94,40 @@ public class GameClient {
|
||||
|
||||
ViewManager.getInstance().setPlayerList(clientLobbyList);
|
||||
|
||||
while (regattaData == null){
|
||||
int triesLeft = 10;
|
||||
|
||||
while (regattaData == null && triesLeft >= 0){
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException ignored) {
|
||||
;
|
||||
}
|
||||
triesLeft--;
|
||||
}
|
||||
|
||||
if (triesLeft < 1){
|
||||
return false;
|
||||
}
|
||||
|
||||
ViewManager.getInstance().setProperty("serverName", regattaData.getRegattaName());
|
||||
ViewManager.getInstance().setProperty("mapName", regattaData.getCourseName());
|
||||
|
||||
getServerThread().setConnectionErrorListener((eMessage) -> {
|
||||
ViewManager.getInstance().showErrorSnackBar(eMessage);
|
||||
//destroyClientToServerThread();
|
||||
});
|
||||
getServerThread().setConnectionErrorListener((eMessage) -> ViewManager.getInstance().showErrorSnackBar(eMessage));
|
||||
|
||||
this.lobbyController = ViewManager.getInstance().goToLobby(true);
|
||||
|
||||
} catch (IOException ioe) {
|
||||
ViewManager.getInstance().showErrorSnackBar("There are no servers currently available.");
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyClientToServerThread() {
|
||||
socketThread.closeSocket();
|
||||
socketThread = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to a game as the host at the given address and starts the visualiser.
|
||||
* @param ipAddress IP to connect to.
|
||||
* @param portNumber Port to connect to.
|
||||
*/
|
||||
public ServerDescription runAsHost(
|
||||
String ipAddress, Integer portNumber, String serverName, Integer maxPlayers, String race,
|
||||
String serverName, Integer maxPlayers, String race,
|
||||
Integer numLegs, Boolean tokensEnabled
|
||||
) {
|
||||
XMLGenerator.setDefaultRaceName(serverName);
|
||||
@@ -150,7 +143,7 @@ public class GameClient {
|
||||
}
|
||||
|
||||
try {
|
||||
startClientToServerThread(ipAddress, 4942);
|
||||
startClientToServerThread("localhost", server.getPortNumber());
|
||||
} catch (IOException e) {
|
||||
showConnectionError("Cannot connect to server as host");
|
||||
}
|
||||
@@ -184,8 +177,11 @@ public class GameClient {
|
||||
|
||||
this.lobbyController = ViewManager.getInstance().goToLobby(false);
|
||||
|
||||
lobbyController.setPortNumber(""+server.getPortNumber());
|
||||
|
||||
ViewManager.getInstance().setPlayerList(clientLobbyList);
|
||||
return new ServerDescription(serverName, regattaData.getCourseName(), GameState.getNumberOfPlayers(), GameState.getCapacity(), ipAddress, 4942);
|
||||
return new ServerDescription(serverName, regattaData.getCourseName(), GameState.getNumberOfPlayers(), GameState.getCapacity(),
|
||||
"localhost", server.getPortNumber());
|
||||
}
|
||||
|
||||
private void tearDownConnection() {
|
||||
@@ -288,6 +284,7 @@ public class GameClient {
|
||||
case CHATTER_TEXT:
|
||||
Pair<Integer, String> playerIdMessagePair = StreamParser
|
||||
.extractChatterText(packet);
|
||||
if (playerIdMessagePair != null) {
|
||||
raceView.updateChatHistory(
|
||||
allBoatsMap.get(playerIdMessagePair.getKey()).getColour(),
|
||||
playerIdMessagePair.getValue()
|
||||
@@ -295,6 +292,7 @@ public class GameClient {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startRaceIfAllDataReceived() {
|
||||
if (allXMLReceived() && raceView == null) {
|
||||
@@ -328,8 +326,6 @@ public class GameClient {
|
||||
positionData.getLon(), positionData.getHeading(),
|
||||
positionData.getGroundSpeed());
|
||||
}
|
||||
} else if (positionData.getType() == DeviceType.MARK_TYPE) {
|
||||
//CompoundMark mark = courseData.getCompoundMarks().get(positionData.getDeviceId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,21 +363,17 @@ public class GameClient {
|
||||
ClientYacht clientYacht = allBoatsMap.get((int) boatData[0]);
|
||||
clientYacht.setEstimateTimeTillNextMark(raceState.getRaceTime() - boatData[1]);
|
||||
clientYacht.setEstimateTimeAtFinish(boatData[2]);
|
||||
// int legNumber = (int) boatData[3];
|
||||
clientYacht.setBoatStatus((int) boatData[4]);
|
||||
// if (legNumber != clientYacht.getLegNumber()) {
|
||||
// clientYacht.setLegNumber(legNumber);
|
||||
// }
|
||||
}
|
||||
|
||||
if (raceFinished) {
|
||||
raceViewController.showFinishDialog(finishedBoats);
|
||||
if (raceFinished && !raceState.getRaceFinished()) {
|
||||
raceState.setRaceFinished();
|
||||
Sounds.playFinishSound();
|
||||
close();
|
||||
ViewManager.getInstance().getGameClient().stopGame();
|
||||
raceViewController.showFinishDialog(finishedBoats);
|
||||
// close();
|
||||
// ViewManager.getInstance().getGameClient().stopGame();
|
||||
//loadFinishScreenView();
|
||||
}
|
||||
raceState.setRaceFinished();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,10 +384,6 @@ public class GameClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void close() {
|
||||
socketThread.setSocketToClose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the key-pressed event from the text field.
|
||||
* @param e The key event triggering this call
|
||||
@@ -522,10 +510,6 @@ public class GameClient {
|
||||
return socketThread;
|
||||
}
|
||||
|
||||
public List<String> getPlayerNames(){
|
||||
return Collections.unmodifiableList(clientLobbyList.sorted());
|
||||
}
|
||||
|
||||
public void stopGame() {
|
||||
GameState.setCurrentStage(GameStages.CANCELLED);
|
||||
if (server != null) server.terminate();
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
package seng302.visualiser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Node;
|
||||
import seng302.model.ClientYacht;
|
||||
import seng302.model.Limit;
|
||||
import seng302.model.ScaledPoint;
|
||||
import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.mark.Corner;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.fxObjects.Marker;
|
||||
|
||||
/**
|
||||
* Abstract class for keeping functionality common between race visualisation.
|
||||
@@ -24,8 +29,36 @@ public abstract class GameView {
|
||||
List<CompoundMark> course = new ArrayList<>();
|
||||
List<CompoundMark> compoundMarks = new ArrayList<>();
|
||||
List<Corner> courseOrder = new ArrayList<>();
|
||||
HashMap<Mark, Marker> markerObjects = new HashMap<>();
|
||||
|
||||
public abstract Node getAssets();
|
||||
public abstract void updateCourse(List<CompoundMark> newCourse, List<Corner> sequence);
|
||||
public abstract void updateBorder(List<Limit> border);
|
||||
|
||||
void updateMarkArrows (ClientYacht yacht, int legNumber) {
|
||||
CompoundMark compoundMark;
|
||||
if (legNumber - 1 >= 0 && legNumber-1 < course.size()) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
compoundMark = course.get(legNumber-1);
|
||||
for (Mark mark : compoundMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextExitArrow();
|
||||
}
|
||||
}
|
||||
CompoundMark nextMark = null;
|
||||
if (legNumber < course.size()) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
nextMark = course.get(legNumber);
|
||||
for (Mark mark : nextMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextEnterArrow();
|
||||
}
|
||||
}
|
||||
if (legNumber - 2 >= 0) {
|
||||
CompoundMark lastMark = course.get(Math.max(0, legNumber - 2));
|
||||
if (lastMark != nextMark) {
|
||||
for (Mark mark : lastMark.getMarks()) {
|
||||
markerObjects.get(mark).hideAllArrows();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import seng302.model.mark.Corner;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.token.Token;
|
||||
import seng302.utilities.GeoUtility;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.cameras.ChaseCamera;
|
||||
import seng302.visualiser.cameras.IsometricCamera;
|
||||
import seng302.visualiser.cameras.RaceCamera;
|
||||
@@ -55,7 +54,7 @@ public class GameView3D extends GameView {
|
||||
|
||||
private final double FOV = 60;
|
||||
private final double DEFAULT_CAMERA_X = 0;
|
||||
private final double DEFAULT_CAMERA_Y = 100;
|
||||
private final double DEFAULT_CAMERA_Y = 160;
|
||||
|
||||
private Group root3D;
|
||||
private SubScene view;
|
||||
@@ -66,11 +65,6 @@ public class GameView3D extends GameView {
|
||||
private PerspectiveCamera isometricCam;
|
||||
private PerspectiveCamera topDownCam;
|
||||
private PerspectiveCamera chaseCam;
|
||||
|
||||
/* Note that if either of these is null then values for it have not been added and the other
|
||||
should be used as the limits of the map. */
|
||||
private Map<Mark, Marker3D> markerObjects;
|
||||
|
||||
private BoatObject playerBoat;
|
||||
private Map<ClientYacht, BoatObject> boatObjects = new HashMap<>();
|
||||
private Group wakesGroup = new Group();
|
||||
@@ -95,11 +89,11 @@ public class GameView3D extends GameView {
|
||||
}
|
||||
|
||||
gameObjects = new Group();
|
||||
root3D = new Group(isometricCam, gameObjects);
|
||||
root3D = new Group(chaseCam, gameObjects);
|
||||
view = new SubScene(
|
||||
root3D, 5000, 3000, true, SceneAntialiasing.BALANCED
|
||||
);
|
||||
view.setCamera(isometricCam);
|
||||
view.setCamera(chaseCam);
|
||||
|
||||
skybox = new Skybox(new Image(getClass().getResourceAsStream("/images/skybox.jpg")), 100000, isometricCam);
|
||||
skybox.getTransforms().addAll(new Rotate(90, Rotate.X_AXIS));
|
||||
@@ -350,7 +344,7 @@ public class GameView3D extends GameView {
|
||||
for (ObservableValue o : Arrays
|
||||
.asList(playerBoat.layoutXProperty(), playerBoat.layoutXProperty())) {
|
||||
o.addListener((obs, oldVal, newVal) -> {
|
||||
|
||||
if (playerYacht.getLegNumber() < course.size()) {
|
||||
List<Mark> marks = course.get(playerYacht.getLegNumber()).getMarks();
|
||||
Point2D midPoint = new Point2D(0, 0);
|
||||
if (marks.size() == 1) {
|
||||
@@ -363,6 +357,7 @@ public class GameView3D extends GameView {
|
||||
if (midPoint != null) {
|
||||
playerBoat.updateMarkIndicator(midPoint);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
@@ -501,6 +496,7 @@ public class GameView3D extends GameView {
|
||||
}
|
||||
|
||||
public void setBoatAsPlayer (ClientYacht playerYacht) {
|
||||
playerBoat.updateMarkIndicator(scaledPoint.findScaledXY(course.get(0).getMidPoint()));
|
||||
playerYacht.toggleSail();
|
||||
playerBoatAnimationTimer = new AnimationTimer() {
|
||||
|
||||
@@ -534,31 +530,4 @@ public class GameView3D extends GameView {
|
||||
public void setWindDir(double windDir) {
|
||||
this.windDir = windDir;
|
||||
}
|
||||
|
||||
private void updateMarkArrows (ClientYacht yacht, int legNumber) {
|
||||
CompoundMark compoundMark;
|
||||
if (legNumber - 1 >= 0) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
compoundMark = course.get(legNumber-1);
|
||||
for (Mark mark : compoundMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextExitArrow();
|
||||
}
|
||||
}
|
||||
CompoundMark nextMark = null;
|
||||
if (legNumber < course.size() - 1) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
nextMark = course.get(legNumber);
|
||||
for (Mark mark : nextMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextEnterArrow();
|
||||
}
|
||||
}
|
||||
if (legNumber - 2 >= 0) {
|
||||
CompoundMark lastMark = course.get(Math.max(0, legNumber - 2));
|
||||
if (lastMark != nextMark) {
|
||||
for (Mark mark : lastMark.getMarks()) {
|
||||
markerObjects.get(mark).hideAllArrows();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package seng302.visualiser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
@@ -35,7 +34,8 @@ public class MapMaker {
|
||||
private int index = 0;
|
||||
private XMLGenerator xmlGenerator = new XMLGenerator();
|
||||
|
||||
private List<String> maps = new ArrayList<>(Arrays.asList("default.xml", "horseshoe.xml", "loop.xml"));
|
||||
private List<String> maps = new ArrayList<>(
|
||||
Arrays.asList("default.xml", "horseshoe.xml", "loop.xml", "madagascar.xml", "waiheke.xml"));
|
||||
|
||||
public static MapMaker getInstance() {
|
||||
if (instance == null) {
|
||||
@@ -108,10 +108,6 @@ public class MapMaker {
|
||||
return mapPreviews.get(index).getAssets();
|
||||
}
|
||||
|
||||
public RaceXMLData getCurrentRace() {
|
||||
return races.get(index);
|
||||
}
|
||||
|
||||
public RegattaXMLData getCurrentRegatta() {
|
||||
return regattas.get(index);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package seng302.visualiser;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.Node;
|
||||
@@ -19,6 +18,7 @@ import seng302.model.mark.Corner;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.utilities.GeoUtility;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory;
|
||||
import seng302.visualiser.fxObjects.Marker;
|
||||
import seng302.visualiser.fxObjects.assets_2D.CourseBoundary;
|
||||
import seng302.visualiser.fxObjects.assets_2D.Gate;
|
||||
import seng302.visualiser.fxObjects.assets_2D.Marker2D;
|
||||
@@ -29,7 +29,6 @@ import seng302.visualiser.fxObjects.assets_2D.Marker2D;
|
||||
public class MapPreview extends GameView {
|
||||
|
||||
private Polygon raceBorder = new CourseBoundary();
|
||||
protected Map<Mark, Marker2D> markerObjects;
|
||||
|
||||
public MapPreview(List<CompoundMark> marks, List<Corner> course, List<Limit> border) {
|
||||
this.compoundMarks = marks;
|
||||
@@ -240,7 +239,7 @@ public class MapPreview extends GameView {
|
||||
* @param colour The desired colour of the gate.
|
||||
* @return the new gate.
|
||||
*/
|
||||
private Gate makeAndBindGate(Marker2D m1, Marker2D m2, Paint colour) {
|
||||
private Gate makeAndBindGate(Marker m1, Marker m2, Paint colour) {
|
||||
Gate gate = new Gate(colour);
|
||||
gate.startXProperty().bind(
|
||||
m1.layoutXProperty()
|
||||
|
||||
@@ -11,8 +11,6 @@ import seng302.model.ClientYacht;
|
||||
import seng302.model.Limit;
|
||||
import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.mark.Corner;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.utilities.Sounds;
|
||||
|
||||
/**
|
||||
* Class converts a map preview to a minimap by adding boats.
|
||||
@@ -20,15 +18,9 @@ import seng302.utilities.Sounds;
|
||||
public class MiniMap extends MapPreview {
|
||||
|
||||
private HashMap<ClientYacht, Polygon> boatIcons = new HashMap<>();
|
||||
private Polygon playerBoat;
|
||||
private double playerRotation;
|
||||
private List<ClientYacht> boats;
|
||||
private ClientYacht player;
|
||||
|
||||
public MiniMap (List<CompoundMark> marks, List<Corner> course, List<Limit> border, List<ClientYacht> boats, ClientYacht player) {
|
||||
super(marks, course, border);
|
||||
this.boats = boats;
|
||||
this.player = player;
|
||||
setBoats(boats);
|
||||
player.addMarkRoundingListener(this::updateMarkArrows);
|
||||
}
|
||||
@@ -56,31 +48,4 @@ public class MiniMap extends MapPreview {
|
||||
gameObjects.getChildren().addAll(boatIcons.values());
|
||||
});
|
||||
}
|
||||
|
||||
private void updateMarkArrows (ClientYacht yacht, int legNumber) {
|
||||
CompoundMark compoundMark;
|
||||
if (legNumber - 1 >= 0) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
compoundMark = course.get(legNumber-1);
|
||||
for (Mark mark : compoundMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextExitArrow();
|
||||
}
|
||||
}
|
||||
CompoundMark nextMark = null;
|
||||
if (legNumber < course.size() - 1) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
nextMark = course.get(legNumber);
|
||||
for (Mark mark : nextMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextEnterArrow();
|
||||
}
|
||||
}
|
||||
if (legNumber - 2 >= 0) {
|
||||
CompoundMark lastMark = course.get(Math.max(0, legNumber - 2));
|
||||
if (lastMark != nextMark) {
|
||||
for (Mark mark : lastMark.getMarks()) {
|
||||
markerObjects.get(mark).hideAllArrows();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package seng302.visualiser;
|
||||
|
||||
import seng302.gameServer.ServerAdvertiser;
|
||||
import seng302.gameServer.ServerDescription;
|
||||
import static seng302.gameServer.ServerAdvertiser.getLocalHostIp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.jmdns.JmDNS;
|
||||
import javax.jmdns.ServiceEvent;
|
||||
import javax.jmdns.ServiceListener;
|
||||
import javax.jmdns.impl.JmDNSImpl;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.*;
|
||||
|
||||
import static seng302.gameServer.ServerAdvertiser.getLocalHostIp;
|
||||
import seng302.gameServer.ServerAdvertiser;
|
||||
import seng302.gameServer.ServerDescription;
|
||||
|
||||
/**
|
||||
* Listens for servers on the local network
|
||||
@@ -58,7 +58,7 @@ public class ServerListener{
|
||||
servers.remove(toRemove);
|
||||
}
|
||||
|
||||
delegate.serverRemoved(new ArrayList<ServerDescription>(servers));
|
||||
delegate.serverRemoved(new ArrayList<>(servers));
|
||||
|
||||
// Get all other servers with the same name to respond if they are up
|
||||
jmdns.requestServiceInfo(ServerAdvertiser.SERVICE_TYPE, serverName);
|
||||
@@ -94,13 +94,6 @@ public class ServerListener{
|
||||
|
||||
listener = new GameServeMonitor();
|
||||
jmdns.addServiceListener(ServerAdvertiser.SERVICE_TYPE, listener);
|
||||
|
||||
/*new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
refresh();
|
||||
}
|
||||
}, 50, SERVICE_REFRESH_INTERVAL);*/
|
||||
}
|
||||
|
||||
public static ServerListener getInstance() throws IOException {
|
||||
@@ -134,7 +127,7 @@ public class ServerListener{
|
||||
for (ServerDescription server : servers){
|
||||
if (server.serverShouldBeRemoved()){
|
||||
listener.servers.remove(server);
|
||||
delegate.serverRemoved(new ArrayList<ServerDescription>(listener.servers));
|
||||
delegate.serverRemoved(new ArrayList<>(listener.servers));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ public class IsometricCamera extends PerspectiveCamera implements RaceCamera {
|
||||
private final Double MAX_Y = 170.0;
|
||||
|
||||
private final Double PAN_LIMIT = 160.0;
|
||||
private final Double NEAR_ZOOM_LIMIT = -50.0;
|
||||
private final Double FAR_ZOOM_LIMIT = -160.0;
|
||||
private final Double NEAR_ZOOM_LIMIT = -30.0;
|
||||
private final Double FAR_ZOOM_LIMIT = -180.0;
|
||||
|
||||
private Double horizontalPan;
|
||||
private Double verticalPan;
|
||||
@@ -29,7 +29,7 @@ public class IsometricCamera extends PerspectiveCamera implements RaceCamera {
|
||||
super(true);
|
||||
transforms = this.getTransforms();
|
||||
|
||||
zoomFactor = (FAR_ZOOM_LIMIT + NEAR_ZOOM_LIMIT) / 2.0;
|
||||
zoomFactor = FAR_ZOOM_LIMIT;
|
||||
horizontalPan = cameraStartX;
|
||||
verticalPan = cameraStartY;
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@ import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||
|
||||
public class TopDownCamera extends PerspectiveCamera implements RaceCamera {
|
||||
|
||||
private final Double PAN_LIMIT = 30.0;
|
||||
private final Double NEAR_ZOOM_LIMIT = -30.0;
|
||||
private final Double FAR_ZOOM_LIMIT = -130.0;
|
||||
private final Double PAN_LIMIT = 40d;
|
||||
private final Double NEAR_ZOOM_LIMIT = -20.0;
|
||||
private final Double FAR_ZOOM_LIMIT = -200d;
|
||||
private final Double ZOOM_STEP = 2.5;
|
||||
|
||||
private ObservableList<Transform> transforms;
|
||||
@@ -27,7 +27,7 @@ public class TopDownCamera extends PerspectiveCamera implements RaceCamera {
|
||||
super(true);
|
||||
transforms = this.getTransforms();
|
||||
|
||||
zoomFactor = (FAR_ZOOM_LIMIT + NEAR_ZOOM_LIMIT) / 2.0;
|
||||
zoomFactor = FAR_ZOOM_LIMIT;
|
||||
horizontalPan = 0.0;
|
||||
verticalPan = 0.0;
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
package seng302.visualiser.controllers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import seng302.model.ClientYacht;
|
||||
import seng302.utilities.Sounds;
|
||||
|
||||
public class FinishScreenViewController implements Initializable {
|
||||
|
||||
@FXML
|
||||
private GridPane finishScreenGridPane;
|
||||
@FXML
|
||||
private TableView<ClientYacht> finishOrderTable;
|
||||
@FXML
|
||||
private TableColumn<ClientYacht, String> posCol;
|
||||
@FXML
|
||||
private TableColumn<ClientYacht, String> boatNameCol;
|
||||
@FXML
|
||||
private TableColumn<ClientYacht, String> shortNameCol;
|
||||
@FXML
|
||||
private TableColumn<ClientYacht, String> countryCol;
|
||||
|
||||
ObservableList<ClientYacht> data = FXCollections.observableArrayList();
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
finishScreenGridPane.getStylesheets()
|
||||
.add(getClass().getResource("/css/Master.css").toString());
|
||||
finishOrderTable.getStylesheets().add(getClass().getResource("/css/Master.css").toString());
|
||||
|
||||
// set up data for table
|
||||
finishOrderTable.setItems(data);
|
||||
|
||||
// setting table col data
|
||||
posCol.setCellValueFactory(
|
||||
new PropertyValueFactory<>("position")
|
||||
);
|
||||
boatNameCol.setCellValueFactory(
|
||||
new PropertyValueFactory<>("boatName")
|
||||
);
|
||||
shortNameCol.setCellValueFactory(
|
||||
new PropertyValueFactory<>("shortName")
|
||||
);
|
||||
countryCol.setCellValueFactory(
|
||||
new PropertyValueFactory<>("country")
|
||||
);
|
||||
finishOrderTable.refresh();
|
||||
}
|
||||
|
||||
public void setFinishers(Collection<ClientYacht> participants) {
|
||||
List<ClientYacht> sorted = new ArrayList<>(participants);
|
||||
sorted.sort(Comparator.comparingInt(ClientYacht::getPlacing));
|
||||
finishOrderTable.getItems().setAll(sorted);
|
||||
}
|
||||
|
||||
private void setContentPane(String jfxUrl) {
|
||||
try {
|
||||
// get the main controller anchor pane (FinishView -> MainView)
|
||||
AnchorPane contentPane = (AnchorPane) finishScreenGridPane.getParent();
|
||||
contentPane.getChildren().removeAll();
|
||||
contentPane.getChildren().clear();
|
||||
contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
||||
contentPane.getChildren()
|
||||
.addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl)));
|
||||
} catch (javafx.fxml.LoadException e) {
|
||||
System.out.println("[Controller] FXML load exception");
|
||||
} catch (IOException e) {
|
||||
System.out.println("[Controller] IO exception");
|
||||
}
|
||||
}
|
||||
|
||||
public void switchToStartScreenView() {
|
||||
Sounds.playButtonClick();
|
||||
setContentPane("/views/StartScreenView.fxml");
|
||||
}
|
||||
|
||||
public void playButtonHoverSound(MouseEvent mouseEvent) {
|
||||
Sounds.playHoverSound();
|
||||
}
|
||||
}
|
||||
@@ -71,6 +71,8 @@ public class LobbyController implements Initializable {
|
||||
@FXML
|
||||
private Label roomLabel;
|
||||
@FXML
|
||||
private Label portNumber;
|
||||
@FXML
|
||||
private Pane speedTokenPane, handlingTokenPane, windWalkerTokenPane, bumperTokenPane, randomTokenPane;
|
||||
//---------FXML END---------//
|
||||
|
||||
@@ -85,6 +87,8 @@ public class LobbyController implements Initializable {
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
roomLabel.setText("");
|
||||
portNumber.setText("");
|
||||
|
||||
this.playerBoats = ViewManager.getInstance().getGameClient().getAllBoatsMap();
|
||||
|
||||
if (this.playersColor == null) {
|
||||
@@ -376,4 +380,8 @@ public class LobbyController implements Initializable {
|
||||
public void setRoomCode(String roomCode) {
|
||||
roomLabel.setText("Room: " + roomCode);
|
||||
}
|
||||
|
||||
public void setPortNumber(String p){
|
||||
portNumber.setText("Port: " + p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ public class RaceViewController extends Thread {
|
||||
@FXML
|
||||
private Pane chatHistoryHolder;
|
||||
@FXML
|
||||
private JFXButton chatToggleButton;
|
||||
@FXML
|
||||
private TextField chatInput;
|
||||
@FXML
|
||||
private Label timerLabel;
|
||||
@@ -85,6 +87,8 @@ public class RaceViewController extends Thread {
|
||||
public void initialize() {
|
||||
miniMapPane.setVisible(false);
|
||||
miniMapButton.setVisible(false);
|
||||
chatHistoryHolder.setVisible(false);
|
||||
chatToggleButton.setVisible(false);
|
||||
contentStackPane.setVisible(false);
|
||||
Image loadingImage = new Image("PP.png");
|
||||
loadingScreen.setImage(loadingImage);
|
||||
@@ -120,6 +124,9 @@ public class RaceViewController extends Thread {
|
||||
chatHistoryHolder.heightProperty()
|
||||
);
|
||||
|
||||
contentStackPane.getChildren().remove(chatToggleButton);
|
||||
contentStackPane.getChildren().add(chatToggleButton);
|
||||
|
||||
contentStackPane.setOnMouseClicked(event -> {
|
||||
contentStackPane.requestFocus();
|
||||
});
|
||||
@@ -146,12 +153,10 @@ public class RaceViewController extends Thread {
|
||||
contentStackPane.setVisible(true);
|
||||
miniMapPane.setVisible(true);
|
||||
miniMapButton.setVisible(true);
|
||||
Platform.runLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
contentStackPane.requestFocus();
|
||||
}
|
||||
});
|
||||
chatHistoryHolder.setVisible(true);
|
||||
chatToggleButton.setVisible(true);
|
||||
|
||||
Platform.runLater(() -> contentStackPane.requestFocus());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,10 +200,20 @@ public class RaceViewController extends Thread {
|
||||
miniMapButton.setOnMouseClicked((event) -> {
|
||||
if (miniMapPane.visibleProperty().get()) {
|
||||
miniMapPane.setVisible(false);
|
||||
miniMapButton.setText("✓");
|
||||
miniMapButton.setText("+");
|
||||
} else {
|
||||
miniMapPane.setVisible(true);
|
||||
miniMapButton.setText("✕");
|
||||
miniMapButton.setText("—");
|
||||
}
|
||||
});
|
||||
|
||||
chatToggleButton.setOnMouseClicked((event) -> {
|
||||
if (chatHistoryHolder.visibleProperty().get()) {
|
||||
chatHistoryHolder.setVisible(false);
|
||||
chatToggleButton.setText("+");
|
||||
} else {
|
||||
chatHistoryHolder.setVisible(true);
|
||||
chatToggleButton.setText("—");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -288,7 +303,7 @@ public class RaceViewController extends Thread {
|
||||
}
|
||||
}
|
||||
|
||||
public void removeIcon(ClientYacht yacht) {
|
||||
private void removeIcon(ClientYacht yacht) {
|
||||
if (yacht == player) {
|
||||
blinkingTimer.cancel();
|
||||
iconToDisplay.setVisible(false);
|
||||
|
||||
@@ -140,7 +140,9 @@ public class ServerListController implements Initializable, ServerListenerDelega
|
||||
return;
|
||||
}
|
||||
|
||||
ViewManager.getInstance().getGameClient().runAsClient(listing.getAddress(), listing.getPortNumber());
|
||||
if (!ViewManager.getInstance().getGameClient().runAsClient(listing.getAddress(), listing.getPortNumber())){
|
||||
ViewManager.getInstance().showErrorSnackBar("Could not connect to server");
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,6 +9,7 @@ import javafx.scene.layout.StackPane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* The pre loading screen before launch the start view
|
||||
* Created by Kusal on 26-Sep-17.
|
||||
*/
|
||||
public class SplashScreenController implements Initializable{
|
||||
@@ -26,9 +27,7 @@ public class SplashScreenController implements Initializable{
|
||||
public void run(){
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
Platform.runLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
Stage stage = new Stage();
|
||||
ViewManager.getInstance().initialStartView(stage);
|
||||
@@ -36,7 +35,6 @@ public class SplashScreenController implements Initializable{
|
||||
e.printStackTrace();
|
||||
}
|
||||
rootPane.getScene().getWindow().hide();
|
||||
}
|
||||
});
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -6,10 +6,16 @@ import com.jfoenix.controls.JFXDialog;
|
||||
import com.jfoenix.controls.JFXDialog.DialogTransition;
|
||||
import com.jfoenix.controls.JFXSnackbar;
|
||||
import com.jfoenix.svg.SVGGlyph;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.*;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.SceneAntialiasing;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
@@ -24,9 +30,6 @@ import seng302.visualiser.GameClient;
|
||||
import seng302.visualiser.controllers.dialogs.KeyBindingDialogController;
|
||||
import seng302.visualiser.controllers.dialogs.PopupDialogController;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ViewManager {
|
||||
|
||||
private static ViewManager instance;
|
||||
@@ -79,7 +82,7 @@ public class ViewManager {
|
||||
decorator.applyCss();
|
||||
decorator.getStylesheets()
|
||||
.add(getClass().getResource("/css/Master.css").toExternalForm());
|
||||
gameClient = new GameClient(decorator);
|
||||
gameClient = new GameClient();
|
||||
setDecorator(decorator);
|
||||
|
||||
stage.getIcons().add(new Image(getClass().getResourceAsStream("/PP.png")));
|
||||
@@ -376,8 +379,8 @@ public class ViewManager {
|
||||
scene.setOnKeyPressed(gameClient::keyPressed);
|
||||
scene.setOnKeyReleased(gameClient::keyReleased);
|
||||
|
||||
stage.setMinHeight(500);
|
||||
stage.setMinWidth(800);
|
||||
stage.setMinHeight(800);
|
||||
stage.setMinWidth(1200);
|
||||
stage.setTitle("Party Parrots At Sea");
|
||||
stage.getIcons().add(new Image(getClass().getResourceAsStream("/PP.png")));
|
||||
stage.setOnCloseRequest(e -> closeAll());
|
||||
|
||||
@@ -115,7 +115,7 @@ public class ServerCreationController implements Initializable {
|
||||
*/
|
||||
private void createServer() {
|
||||
ServerDescription serverDescription = ViewManager.getInstance().getGameClient()
|
||||
.runAsHost("localhost", 4941, serverName.getText(), (int) maxPlayersSlider
|
||||
.runAsHost(serverName.getText(), (int) maxPlayersSlider
|
||||
.getValue(), mapMaker.getCurrentRacePath(), (int) legsSlider.getValue(), pickupsCheckBox.isSelected());
|
||||
|
||||
if (serverDescription == null){
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package seng302.visualiser.fxObjects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.scene.Group;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory.RoundingSide;
|
||||
|
||||
/**
|
||||
* Created by cir27 on 28/09/17.
|
||||
*/
|
||||
public abstract class Marker extends Group{
|
||||
|
||||
protected List<Group> enterArrows = new ArrayList<>();
|
||||
protected List<Group> exitArrows = new ArrayList<>();
|
||||
protected int enterArrowIndex = 0;
|
||||
protected int exitArrowIndex = 0;
|
||||
|
||||
public abstract void addArrows(RoundingSide roundingSide, double entryAngle, double exitAngle);
|
||||
/**
|
||||
* Shows the next EnterArrow. Does nothing if there are no more enter arrows. Other arrows become hidden.
|
||||
*/
|
||||
public void showNextEnterArrow() {
|
||||
showArrow(enterArrows, enterArrowIndex);
|
||||
enterArrowIndex++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the next ExitArrow. Does nothing if there are no more enter arrows. Other arrows become hidden.
|
||||
*/
|
||||
public void showNextExitArrow() {
|
||||
showArrow(exitArrows, exitArrowIndex);
|
||||
exitArrowIndex++;
|
||||
}
|
||||
|
||||
protected abstract void showArrow(List<Group> arrowList, int arrowListIndex);
|
||||
|
||||
public abstract void hideAllArrows();
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
package seng302.visualiser.fxObjects.assets_2D;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.CacheHint;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
/**
|
||||
* Grouping of string objects over a semi transparent background.
|
||||
*/
|
||||
public class AnnotationBox extends Group {
|
||||
|
||||
@FunctionalInterface
|
||||
public interface AnnotationFormatter<T> {
|
||||
String transformString (T input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class stores a text object and relationship for updating the text object if needed
|
||||
*
|
||||
* @param <T> The type of observable value passed to the annotation, if there is one.
|
||||
*/
|
||||
public class Annotation<T> {
|
||||
private Text text;
|
||||
private ObservableValue<T> source;
|
||||
private AnnotationFormatter<T> format;
|
||||
|
||||
/**
|
||||
* Constructor for observing annotation
|
||||
* @param textObject the javaFX text object the annotation is displayed in
|
||||
* @param source observable value that the annotation is taken from
|
||||
* @param formatter interface describing how to format the source data if needed
|
||||
*/
|
||||
public Annotation (Text textObject, ObservableValue<T> source, AnnotationFormatter<T> formatter) {
|
||||
this.text = textObject;
|
||||
this.source = source;
|
||||
this.format = formatter;
|
||||
source.addListener((obs, oldVal, newVal) ->
|
||||
Platform.runLater(() -> text.setText(format.transformString(newVal)))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for a static annotation
|
||||
* @param textObject the javaFX text object the annotation is displayed in
|
||||
* @param annotationText the static value of the test object
|
||||
*/
|
||||
public Annotation (Text textObject, String annotationText) {
|
||||
textObject.setText(annotationText);
|
||||
text = textObject;
|
||||
}
|
||||
|
||||
private Text getText () {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
//Text offset constants
|
||||
private static final double X_OFFSET_TEXT = 20d;
|
||||
private static final double Y_OFFSET_TEXT_INIT = -35d;
|
||||
private static final double Y_OFFSET_PER_TEXT = 12d;
|
||||
//Background constants
|
||||
private static final double TEXT_BUFFER = 3;
|
||||
private static final double BACKGROUND_X = X_OFFSET_TEXT - TEXT_BUFFER;
|
||||
private static final double BACKGROUND_Y = Y_OFFSET_TEXT_INIT - TEXT_BUFFER;
|
||||
private static final double BACKGROUND_H_PER_TEXT = 9.5d;
|
||||
private static final double BACKGROUND_ARC_SIZE = 10;
|
||||
|
||||
private int visibleAnnotations = 0;
|
||||
private double backgroundWidth = 145d;
|
||||
|
||||
private Rectangle background = new Rectangle();
|
||||
private Paint theme = Color.BLACK;
|
||||
|
||||
private Map<String, Annotation> annotationsByName = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates an empty annotation box. The box is offset from (0,0) by (17, -38).
|
||||
*/
|
||||
public AnnotationBox() {
|
||||
this.setCache(true);
|
||||
background.setX(BACKGROUND_X);
|
||||
background.setY(BACKGROUND_Y);
|
||||
background.setWidth(backgroundWidth);
|
||||
background.setHeight(Math.abs(BACKGROUND_X) + TEXT_BUFFER + BACKGROUND_H_PER_TEXT * 4);
|
||||
background.setArcHeight(BACKGROUND_ARC_SIZE);
|
||||
background.setArcWidth(BACKGROUND_ARC_SIZE);
|
||||
background.setFill(new Color(1, 1, 1, 0.75));
|
||||
background.setStroke(theme);
|
||||
background.setStrokeWidth(2);
|
||||
background.setCache(true);
|
||||
background.setCacheHint(CacheHint.SCALE);
|
||||
this.getChildren().add(background);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an annotation to the box. Use the name to reference the annotation for removal or\
|
||||
* changing visibility.
|
||||
* @param annotationName the name of the annotation.
|
||||
* @param annotation the annotation.
|
||||
*/
|
||||
public void addAnnotation (String annotationName, Annotation annotation) {
|
||||
annotationsByName.put(annotationName, annotation);
|
||||
Platform.runLater(() -> {
|
||||
this.getChildren().add(annotation.getText());
|
||||
visibleAnnotations++;
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an annotation with a constant text.
|
||||
* @param annotationName The name of the annotation. Will be used to reference it later.
|
||||
* @param annotationText The desired text.
|
||||
*/
|
||||
public void addAnnotation (String annotationName, String annotationText) {
|
||||
Text text = getTextObject();
|
||||
addAnnotation(annotationName, new Annotation(text, annotationText));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an annotation with the given name. The annotation will contain the value of the given
|
||||
* ObservableValue. The formatter should return a String and takes an object of the same type as
|
||||
* the ObservableValue as a parameter. The String is how you want the annotation to look.
|
||||
* @param annotationName The annotation name.
|
||||
* @param observable The observable value the annotation will display.
|
||||
* @param formatter A formatting function for the observable value.
|
||||
* @param <E> The type of ObservableValue.
|
||||
*/
|
||||
public <E> void addAnnotation (String annotationName, ObservableValue<E> observable,
|
||||
AnnotationFormatter<E> formatter) {
|
||||
Text newText = getTextObject();
|
||||
addAnnotation(annotationName, new Annotation<>(newText, observable, formatter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the visibility of the annotation with the given name if it exists.
|
||||
* @param annotationName The name of the annotation
|
||||
* @param visibility the desired visibility
|
||||
*/
|
||||
public void setAnnotationVisibility (String annotationName, boolean visibility) {
|
||||
if (annotationsByName.containsKey(annotationName)) {
|
||||
Text textField = annotationsByName.get(annotationName).text;
|
||||
boolean currentState = textField.visibleProperty().get();
|
||||
if (visibility != currentState) {
|
||||
if (visibility)
|
||||
visibleAnnotations++;
|
||||
else
|
||||
visibleAnnotations--;
|
||||
}
|
||||
textField.setVisible(visibility);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the annotation with the given name if it exits.
|
||||
* @param annotationName The name given when the annotation was created.
|
||||
*/
|
||||
public void removeAnnotation (String annotationName) {
|
||||
if (annotationName.contains(annotationName)) {
|
||||
Platform.runLater(() -> {
|
||||
this.getChildren().remove(annotationsByName.remove(annotationName).getText());
|
||||
visibleAnnotations--;
|
||||
update();
|
||||
});
|
||||
annotationsByName.remove(annotationName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the annotation.
|
||||
* @param x x location
|
||||
* @param y y location
|
||||
*/
|
||||
public void setLocation (double x, double y) {
|
||||
Platform.runLater(()-> this.relocate(x + BACKGROUND_X, y + BACKGROUND_Y));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the width of the annotation box. Default is 145.
|
||||
* @param width new width.
|
||||
*/
|
||||
public void setWidth (double width) {
|
||||
backgroundWidth = width;
|
||||
Platform.runLater(() -> background.setWidth(backgroundWidth));
|
||||
}
|
||||
|
||||
private void update () {
|
||||
background.setVisible(visibleAnnotations != 0);
|
||||
background.setHeight(Math.abs(BACKGROUND_X) + TEXT_BUFFER + BACKGROUND_H_PER_TEXT * visibleAnnotations);
|
||||
for (int i = 1; i <= visibleAnnotations; i++) {
|
||||
Text text = (Text) this.getChildren().get(i);
|
||||
if (text.visibleProperty().get()) {
|
||||
text.setX(X_OFFSET_TEXT);
|
||||
text.setY(Y_OFFSET_TEXT_INIT + Y_OFFSET_PER_TEXT * i);
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a text object for an annotation.
|
||||
* @return The text object
|
||||
*/
|
||||
private Text getTextObject() {
|
||||
Text text = new Text();
|
||||
text.setFill(theme);
|
||||
text.setStrokeWidth(2);
|
||||
// text.setCacheHint(CacheHint.QUALITY);
|
||||
text.setCache(true);
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the colour of the annotation box's border and text colour.
|
||||
* @param value desired colour.
|
||||
*/
|
||||
public void setFill (Paint value) {
|
||||
theme = value;
|
||||
background.setStroke(theme);
|
||||
annotationsByName.forEach((name, annotation) -> annotation.getText().setFill(theme));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package seng302.visualiser.fxObjects.assets_2D;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Group;
|
||||
@@ -8,18 +7,15 @@ import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Circle;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory;
|
||||
import seng302.visualiser.fxObjects.Marker;
|
||||
|
||||
/**
|
||||
* Visual object for a mark. Contains a coloured circle and any specified arrows.
|
||||
*/
|
||||
public class Marker2D extends Group {
|
||||
public class Marker2D extends Marker {
|
||||
|
||||
private Circle mark = new Circle();
|
||||
private Paint colour = Color.BLACK;
|
||||
private List<Group> enterArrows = new ArrayList<>();
|
||||
private List<Group> exitArrows = new ArrayList<>();
|
||||
private int enterArrowIndex = 0;
|
||||
private int exitArrowIndex = 0;
|
||||
|
||||
/**
|
||||
* Creates a new Marker containing only a circle. The default colour is black.
|
||||
@@ -79,7 +75,8 @@ public class Marker2D extends Group {
|
||||
exitArrowIndex++;
|
||||
}
|
||||
|
||||
private void showArrow(List<Group> arrowList, int arrowListIndex) {
|
||||
@Override
|
||||
protected void showArrow(List<Group> arrowList, int arrowListIndex) {
|
||||
if (arrowListIndex < arrowList.size()) {
|
||||
Platform.runLater(() ->
|
||||
this.getChildren().setAll(mark, arrowList.get(arrowListIndex))
|
||||
|
||||
@@ -16,10 +16,6 @@ public class Wake extends Group {
|
||||
|
||||
//The number of wakes
|
||||
private int numWakes = 8;
|
||||
//The total possible difference between the first wake and the last. Increasing/Decreasing this will make wakes fan out more/less.
|
||||
private final double MAX_DIFF = 75;
|
||||
//Increasing/decreasing this will alter the speed that wakes converge when the heading stop changing. Anything over about 1500 may cause oscillation.
|
||||
private final int UNIFICATION_SPEED = 45;
|
||||
|
||||
|
||||
private Arc[] arcs = new Arc[numWakes];
|
||||
@@ -69,34 +65,6 @@ public class Wake extends Group {
|
||||
rad += (14 / numWakes) + (velocity / 2.5);
|
||||
}
|
||||
});
|
||||
// } else {
|
||||
// rotations[0] = rotation;
|
||||
// ((Rotate) arcs[0].getTransforms().get(0)).setAngle(rotation);
|
||||
// for (int i = 1; i < numWakes; i++) {
|
||||
// double wakeSeparationRad = Math.toRadians(rotations[i - 1] - rotations[i]);
|
||||
// double shortestDistance = Math.atan2(
|
||||
// Math.sin(wakeSeparationRad),
|
||||
// Math.cos(wakeSeparationRad)
|
||||
// );
|
||||
// double distDeg = Math.toDegrees(shortestDistance);
|
||||
// if (rotationalVelocities[i - 1] < 0.01 && rotationalVelocities[i - 1] > -0.01) {
|
||||
// rotationalVelocities[i] = distDeg / UNIFICATION_SPEED * 2 * Math.log(Math.abs(distDeg) + 1) / Math.log(MAX_DIFF / numWakes);
|
||||
//
|
||||
// } else {
|
||||
// if (distDeg < (MAX_DIFF / numWakes)) {
|
||||
// rotationalVelocities[i] = distDeg / UNIFICATION_SPEED * Math.log(Math.abs(distDeg) + 1) / Math.log(MAX_DIFF / numWakes);
|
||||
// } else
|
||||
// rotationalVelocities[i] = rotationalVelocities[i - 1];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// double rad = (14 / numWakes) + velocity;
|
||||
// for (Arc arc : arcs) {
|
||||
// arc.setRadiusX(rad);
|
||||
// arc.setRadiusY(rad);
|
||||
// rad += (14 / numWakes) + (velocity / 2.5);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package seng302.visualiser.fxObjects.assets_2D;
|
||||
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Polyline;
|
||||
import javafx.scene.shape.StrokeLineCap;
|
||||
import javafx.scene.shape.StrokeLineJoin;
|
||||
|
||||
/**
|
||||
* Created by cir27 on 5/09/17.
|
||||
*/
|
||||
public class WindArrow extends Polyline {
|
||||
public WindArrow(Paint fill) {
|
||||
this.getPoints().addAll(
|
||||
-10d, 15d,
|
||||
0d, 25d,
|
||||
0d, -25d,
|
||||
0d, 25d,
|
||||
10d, 15d
|
||||
);
|
||||
this.setStrokeLineCap(StrokeLineCap.ROUND);
|
||||
this.setStroke(fill);
|
||||
this.setStrokeWidth(5);
|
||||
this.setStrokeLineJoin(StrokeLineJoin.ROUND);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public enum BoatMeshType {
|
||||
PIRATE_SHIP("pirateship_hull.stl", "pirateship_mast.stl", -0.5415, "pirateship_mainsail.stl",
|
||||
-0.5415, "pirateship_frontsail.stl", true, 1.2, 1.6, 1.2),
|
||||
DUCKY("ducky_hull.stl", "ducky_mast.stl", -2.18539, "ducky_sail.stl", -2.18539, "ducky_eyes.stl", false, 1.2, 1.1, 1.4),
|
||||
PARROT("parrot_hull.stl", null, 0, "parrot_sail.stl", 0, "parrot_features.stl", true, 1, 1, 1),
|
||||
PARROT("parrot_hull.stl", null, 0, "parrot_features.stl", 0, "parrot_sail.stl", true, 1, 1, 1),
|
||||
WAKA("waka_hull.stl", "waka_mast.stl", 0, "waka_sail.stl", 0, null, true, 1.7, 0.5, 1.5);
|
||||
|
||||
final String hullFile, mastFile, sailFile, jibFile;
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
package seng302.visualiser.fxObjects.assets_3D;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Group;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory.RoundingSide;
|
||||
import seng302.visualiser.fxObjects.Marker;
|
||||
|
||||
/**
|
||||
* Visual object for a mark. Contains a coloured circle and any specified arrows.
|
||||
*/
|
||||
public class Marker3D extends Group {
|
||||
public class Marker3D extends Marker {
|
||||
|
||||
private Model mark;
|
||||
private List<Group> enterArrows = new ArrayList<>();
|
||||
private List<Group> exitArrows = new ArrayList<>();
|
||||
private int enterArrowIndex = 0;
|
||||
private int exitArrowIndex = 0;
|
||||
private ModelType markType;
|
||||
private ModelType arrowType;
|
||||
|
||||
@@ -60,23 +55,8 @@ public class Marker3D extends Group {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the next EnterArrow. Does nothing if there are no more enter arrows. Other arrows become hidden.
|
||||
*/
|
||||
public void showNextEnterArrow() {
|
||||
showArrow(enterArrows, enterArrowIndex);
|
||||
enterArrowIndex++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the next ExitArrow. Does nothing if there are no more enter arrows. Other arrows become hidden.
|
||||
*/
|
||||
public void showNextExitArrow() {
|
||||
showArrow(exitArrows, exitArrowIndex);
|
||||
exitArrowIndex++;
|
||||
}
|
||||
|
||||
private void showArrow(List<Group> arrowList, int arrowListIndex) {
|
||||
@Override
|
||||
protected void showArrow(List<Group> arrowList, int arrowListIndex) {
|
||||
if (arrowListIndex < arrowList.size()) {
|
||||
Platform.runLater(() ->
|
||||
this.getChildren().setAll(mark.getAssets(), arrowList.get(arrowListIndex))
|
||||
|
||||
@@ -100,19 +100,19 @@ public class ModelFactory {
|
||||
mast.setMaterial(new PhongMaterial(primaryColour));
|
||||
boatAssets.getChildren().add(mast);
|
||||
} else {
|
||||
boatAssets.getChildren().add(new Group());
|
||||
boatAssets.getChildren().add(new MeshView());
|
||||
}
|
||||
|
||||
MeshView sail = importBoatSTL(boatType.sailFile);
|
||||
sail.setMaterial(
|
||||
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.DARKGRAY : Color.WHITE)
|
||||
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.BLACK : Color.WHITE)
|
||||
);
|
||||
boatAssets.getChildren().add(sail);
|
||||
|
||||
if (boatType.jibFile != null) {
|
||||
MeshView jib = importBoatSTL(boatType.jibFile);
|
||||
jib.setMaterial(
|
||||
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.BLACK : Color.WHITE)
|
||||
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.DARKGRAY : Color.WHITE)
|
||||
);
|
||||
boatAssets.getChildren().add(jib);
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package seng302.visualiser.map;
|
||||
|
||||
/**
|
||||
* The Boundary class represents a rectangle territorial boundary on a map. It
|
||||
* contains four extremity double values(N, E, S, W). N and S are represented as
|
||||
* latitudes in radians. E and W are represented as longitudes in radians.
|
||||
*
|
||||
* Created by Haoming on 10/5/17
|
||||
*/
|
||||
public class Boundary {
|
||||
|
||||
private double northLat, eastLng, southLat, westLng;
|
||||
|
||||
public Boundary(double northLat, double eastLng, double southLat, double westLng) {
|
||||
this.northLat = northLat;
|
||||
this.eastLng = eastLng;
|
||||
this.southLat = southLat;
|
||||
this.westLng = westLng;
|
||||
}
|
||||
|
||||
double getCentreLat() {
|
||||
return (northLat + southLat) / 2;
|
||||
}
|
||||
|
||||
double getCentreLng() {
|
||||
return (eastLng + westLng) / 2;
|
||||
}
|
||||
|
||||
double getNorthLat() {
|
||||
return northLat;
|
||||
}
|
||||
|
||||
double getEastLng() {
|
||||
return eastLng;
|
||||
}
|
||||
|
||||
double getSouthLat() {
|
||||
return southLat;
|
||||
}
|
||||
|
||||
double getWestLng() {
|
||||
return westLng;
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package seng302.visualiser.map;
|
||||
|
||||
import java.net.URL;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.image.Image;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import seng302.model.GeoPoint;
|
||||
|
||||
/**
|
||||
* CanvasMap retrieves a map image with given geo boundary from Google Map server.
|
||||
* By passing a rectangle like geo boundary, it returns a map image with the
|
||||
* highest resolution. However, due to free quote account usage limit, the maximum
|
||||
* resolution is only 1280 * 1280.
|
||||
*
|
||||
* Created by Haoming on 15/5/2017
|
||||
*/
|
||||
public class CanvasMap {
|
||||
|
||||
private Boundary boundary;
|
||||
private long width, height; // desired image size
|
||||
private int zoom;
|
||||
|
||||
private String KEY = "AIzaSyC-5oOShMCY5Oy_9L7guYMPUPFHDMr37wE";
|
||||
|
||||
public CanvasMap(Boundary boundary) {
|
||||
this.boundary = boundary;
|
||||
calculateOptimalMapSize();
|
||||
}
|
||||
|
||||
public Image getMapImage() {
|
||||
try {
|
||||
URL url = new URL(getRequest());
|
||||
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
||||
|
||||
return new Image(connection.getInputStream());
|
||||
} catch (Exception e) {
|
||||
System.out.println("[CanvasMap] Exception");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String getRequest() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("https://maps.googleapis.com/maps/api/staticmap?");
|
||||
sb.append(String.format("center=%f,%f", boundary.getCentreLat(), boundary.getCentreLng()));
|
||||
sb.append(String.format("&zoom=%d", zoom));
|
||||
sb.append(String.format("&size=%dx%d&scale=2", width, height));
|
||||
sb.append("&style=feature:all|element:labels|visibility:off"); // hide all labels on map
|
||||
// sb.append(String.format("&markers=%f,%f", boundary.getSouthLat(), boundary.getWestLng()));
|
||||
// sb.append(String.format("&key=%s", KEY));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void calculateOptimalMapSize() {
|
||||
for (int z = 20; z > 0; z--) {
|
||||
MapSize mapSize = getMapSize(z, boundary);
|
||||
zoom = z;
|
||||
width = mapSize.width;
|
||||
height = mapSize.height;
|
||||
// if map size is valid, exit the loop as we have the highest resolution
|
||||
if (mapSize.isValid()) break;
|
||||
}
|
||||
}
|
||||
|
||||
private MapSize getMapSize(int zoom, Boundary boundary) {
|
||||
double scale = Math.pow(2, zoom);
|
||||
GeoPoint geoSW = new GeoPoint(boundary.getSouthLat(), boundary.getWestLng());
|
||||
GeoPoint geoNE = new GeoPoint(boundary.getNorthLat(), boundary.getEastLng());
|
||||
Point2D pointSW = MercatorProjection.toMapPoint(geoSW);
|
||||
Point2D pointNE = MercatorProjection.toMapPoint(geoNE);
|
||||
return new MapSize(Math.abs(pointNE.getX() - pointSW.getX()) * scale,
|
||||
Math.abs(pointNE.getY() - pointSW.getY()) * scale);
|
||||
}
|
||||
|
||||
class MapSize {
|
||||
long width, height;
|
||||
|
||||
MapSize(double width, double height) {
|
||||
this.width = Math.round(width);
|
||||
this.height = Math.round(height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map size is valid when width and height are both less than 640 pixels
|
||||
* @return true if both dimensions are less than 640px
|
||||
*/
|
||||
boolean isValid() {
|
||||
return Math.max(width, height) <= 640;
|
||||
}
|
||||
}
|
||||
|
||||
public long getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public long getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getZoom() {
|
||||
return zoom;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package seng302.visualiser.map;
|
||||
|
||||
import javafx.geometry.Point2D;
|
||||
import seng302.model.GeoPoint;
|
||||
|
||||
/**
|
||||
* An utility class useful to convert between Geo locations and Mercator projection
|
||||
* planar coordinates.
|
||||
* Created by Haoming on 15/5/2017
|
||||
*/
|
||||
public class MercatorProjection {
|
||||
|
||||
private static final double MERCATOR_RANGE = 256;
|
||||
private static final double pixelsPerLngDegree = MERCATOR_RANGE / 360.0;
|
||||
private static final double pixelsPerLngRadian = MERCATOR_RANGE / (2 * Math.PI);
|
||||
|
||||
/**
|
||||
* A help function keeps the value in bound between -0.9999 and 0.9999.
|
||||
* @param value in bound value
|
||||
* @return the value in bound
|
||||
*/
|
||||
private static double bound(double value) {
|
||||
return Math.min(Math.max(value, -0.9999), 0.9999);
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects a Geo Location (lat, lng) on a planar
|
||||
* @param geo GeoPoint (lat, lng) location to be projected
|
||||
* @return the projection Point2D (x, y) on planar
|
||||
*/
|
||||
public static Point2D toMapPoint(GeoPoint geo) {
|
||||
double x, y;
|
||||
Point2D origin = new Point2D(MERCATOR_RANGE / 2.0, MERCATOR_RANGE / 2.0);
|
||||
x = (origin.getX() + geo.getLng() * pixelsPerLngDegree);
|
||||
|
||||
// NOTE(appleton): Truncating to 0.9999 effectively limits latitude to
|
||||
// 89.189. This is about a third of a tile past the edge of the world tile.
|
||||
double sinY = bound(Math.sin(Math.toRadians(geo.getLat())));
|
||||
y = origin.getY() + 0.5 * Math.log((1 + sinY) / (1 - sinY)) * (-pixelsPerLngRadian);
|
||||
return new Point2D(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the planar projection (x, y) back to Geo Location (lat, lng)
|
||||
* @param point Point2D (x, y) to be converted back
|
||||
* @return the original Geo location converted from the given projection point
|
||||
*/
|
||||
public static GeoPoint toMapGeo(Point2D point) {
|
||||
Point2D origin = new Point2D(MERCATOR_RANGE / 2.0, MERCATOR_RANGE / 2.0);
|
||||
double lng = (point.getX() - origin.getX()) / pixelsPerLngDegree;
|
||||
double latRadians = (point.getY() - origin.getY()) / (-pixelsPerLngRadian);
|
||||
double lat = Math.toDegrees(2 * Math.atan(Math.exp(latRadians)) - Math.PI / 2.0);
|
||||
return new GeoPoint(lat, lng);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package seng302.visualiser.map;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
|
||||
public class TestMapController implements Initializable{
|
||||
|
||||
@FXML
|
||||
private Canvas mapCanvas;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
GraphicsContext gc = mapCanvas.getGraphicsContext2D();
|
||||
Boundary bound = new Boundary(57.662943, 11.848501, 57.673945, 11.824966);
|
||||
CanvasMap canvasMap = new CanvasMap(bound);
|
||||
gc.drawImage(canvasMap.getMapImage(), 0, 0, canvasMap.getWidth(), canvasMap.getHeight());
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#timerGrid{
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-effect: -fx-pp-dropshadow-light;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
GridPane .timer * {
|
||||
@@ -27,20 +28,24 @@ GridPane .timer * {
|
||||
#chatHistoryHolder {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-effect: -fx-pp-dropshadow-light;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
#chatInputHolder {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-effect: -fx-pp-dropshadow-light;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
#windGridPane {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-effect: -fx-pp-dropshadow-light;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
#windHolder {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.5);
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
#chatSend {
|
||||
@@ -64,3 +69,15 @@ GridPane .timer * {
|
||||
#windImageView {
|
||||
-fx-image: url("/images/wind-180.png");
|
||||
}
|
||||
|
||||
#miniMapPane {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
#miniMapButton {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-background-radius: 5;
|
||||
-fx-min-width: 30;
|
||||
-fx-min-height: 30;
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
<Marks>
|
||||
<CompoundMark CompoundMarkID="1">
|
||||
<Mark Lat="-14.071412" Lng="47.05756"/>
|
||||
<Mark Lat="-14.069914" Lng="47.058541"/>
|
||||
<Mark Lat="-14.070412" Lng="47.05746"/>
|
||||
<Mark Lat="-14.068014" Lng="47.057541"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="2">
|
||||
<Mark Lat="-14.067194" Lng="47.053818" />
|
||||
@@ -64,7 +64,7 @@
|
||||
<CourseLimit>
|
||||
<Limit Lat="-14.073371" Lng="47.058213" />
|
||||
<Limit Lat="-14.06453" Lng="47.050003" />
|
||||
<Limit Lat="-14.059022" Lng="47.057286" />
|
||||
<Limit Lat="-14.057022" Lng="47.057286" />
|
||||
<Limit Lat="-14.058723" Lng="47.064358" />
|
||||
<Limit Lat="-14.06261" Lng="47.071293" />
|
||||
<Limit Lat="-14.070814" Lng="47.06762" />
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="2">
|
||||
<Mark Lat="57.670914" Lng="11.835263"/>
|
||||
<Mark Lat="57.6699024" Lng="11.8353195"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="3">
|
||||
<Mark Lat="57.6674596" Lng="11.8417500"/>
|
||||
@@ -29,21 +28,27 @@
|
||||
<Mark Lat="57.667311" Lng="11.828857"/>
|
||||
<Mark Lat="57.667334" Lng="11.825853"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="6">
|
||||
<Mark Lat="57.6675700" Lng="11.8359880"/>
|
||||
<Mark Lat="57.667610" Lng="11.833473"/>
|
||||
</CompoundMark>
|
||||
</Marks>
|
||||
|
||||
<Course>
|
||||
<OpeningSegment>
|
||||
<Corner CompoundMarkID="1" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="2" Rounding="P"/>
|
||||
<Corner CompoundMarkID="2" Rounding="S"/>
|
||||
</OpeningSegment>
|
||||
|
||||
<RepeatingSegment>
|
||||
<Corner CompoundMarkID="3" Rounding="SP"/>
|
||||
<Corner CompoundMarkID="4" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="5" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="2" Rounding="S"/>
|
||||
</RepeatingSegment>
|
||||
|
||||
<ClosingSegment>
|
||||
<Corner CompoundMarkID="5" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="6" Rounding="PS"/>
|
||||
</ClosingSegment>
|
||||
</Course>
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RaceDefinition>
|
||||
|
||||
<CourseName>Madagascar</CourseName>
|
||||
|
||||
<CentralLat>-15.67707</CentralLat>
|
||||
<CentralLng>49.79338</CentralLng>
|
||||
|
||||
<MaxPlayers>10</MaxPlayers>
|
||||
|
||||
<Marks>
|
||||
<CompoundMark CompoundMarkID="1">
|
||||
<Mark Lat="-15.67466" Lng="49.79104"/>
|
||||
<Mark Lat="-15.67408" Lng="49.79224"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="2">
|
||||
<Mark Lat="-15.67548" Lng="49.79271"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="3">
|
||||
<Mark Lat="-15.67744" Lng="49.79235"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="4">
|
||||
<Mark Lat="-15.67691" Lng="49.79501"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="5">
|
||||
<Mark Lat="-15.67775" Lng="49.79619"/>
|
||||
<Mark Lat="-15.67827" Lng="49.79713"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="6">
|
||||
<Mark Lat="-15.67922" Lng="49.79318"/>
|
||||
<Mark Lat="-15.67972" Lng="49.79393"/>
|
||||
</CompoundMark>
|
||||
</Marks>
|
||||
|
||||
<Course>
|
||||
<OpeningSegment>
|
||||
<Corner CompoundMarkID="1" Rounding="PS"/>
|
||||
</OpeningSegment>
|
||||
|
||||
<RepeatingSegment>
|
||||
<Corner CompoundMarkID="2" Rounding="P"/>
|
||||
<Corner CompoundMarkID="3" Rounding="S"/>
|
||||
<Corner CompoundMarkID="4" Rounding="S"/>
|
||||
<Corner CompoundMarkID="3" Rounding="P"/>
|
||||
</RepeatingSegment>
|
||||
|
||||
<ClosingSegment>
|
||||
<Corner CompoundMarkID="5" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="6" Rounding="PS"/>
|
||||
</ClosingSegment>
|
||||
</Course>
|
||||
|
||||
<CourseLimit>
|
||||
<Limit Lat="-15.67571" Lng="49.78984"/>
|
||||
<Limit Lat="-15.6787" Lng="49.79024"/>
|
||||
<Limit Lat="-15.68046" Lng="49.79247"/>
|
||||
<Limit Lat="-15.68073" Lng="49.79599"/>
|
||||
<Limit Lat="-15.67939" Lng="49.79855"/>
|
||||
<Limit Lat="-15.67662" Lng="49.79855"/>
|
||||
<Limit Lat="-15.67474" Lng="49.79694"/>
|
||||
<Limit Lat="-15.67271" Lng="49.79355"/>
|
||||
<Limit Lat="-15.67333" Lng="49.79071"/>
|
||||
</CourseLimit>
|
||||
|
||||
</RaceDefinition>
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RaceDefinition>
|
||||
|
||||
<CourseName>Waiheke</CourseName>
|
||||
|
||||
<CentralLat>-36.80008</CentralLat>
|
||||
<CentralLng>175.012225</CentralLng>
|
||||
|
||||
<MaxPlayers>10</MaxPlayers>
|
||||
|
||||
<Marks>
|
||||
<CompoundMark CompoundMarkID="1">
|
||||
<Mark Lat="-36.79512" Lng="175.0116"/>
|
||||
<Mark Lat="-36.79468" Lng="175.01312"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="2">
|
||||
<Mark Lat="-36.80069" Lng="175.01495"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="3">
|
||||
<Mark Lat="-36.79892" Lng="175.01832"/>
|
||||
<Mark Lat="-36.79988" Lng="175.01913"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="4">
|
||||
<Mark Lat="-36.80064" Lng="175.01171"/>
|
||||
<Mark Lat="-36.80186" Lng="175.0124"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="5">
|
||||
<Mark Lat="-36.79579" Lng="175.01194"/>
|
||||
<Mark Lat="-36.79545" Lng="175.01349"/>
|
||||
</CompoundMark>
|
||||
</Marks>
|
||||
|
||||
<Course>
|
||||
<OpeningSegment>
|
||||
<Corner CompoundMarkID="1" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="2" Rounding="P"/>
|
||||
</OpeningSegment>
|
||||
|
||||
<RepeatingSegment>
|
||||
<Corner CompoundMarkID="3" Rounding="SP"/>
|
||||
<Corner CompoundMarkID="4" Rounding="PS"/>
|
||||
</RepeatingSegment>
|
||||
|
||||
<ClosingSegment>
|
||||
<Corner CompoundMarkID="5" Rounding="PS"/>
|
||||
</ClosingSegment>
|
||||
</Course>
|
||||
|
||||
<CourseLimit>
|
||||
<Limit Lat="-36.7938" Lng="175.01194"/>
|
||||
<Limit Lat="-36.79411" Lng="175.01555"/>
|
||||
<Limit Lat="-36.79765" Lng="175.01898"/>
|
||||
<Limit Lat="-36.79909" Lng="175.02149"/>
|
||||
<Limit Lat="-36.80163" Lng="175.02014"/>
|
||||
<Limit Lat="-36.80292" Lng="175.0175"/>
|
||||
<Limit Lat="-36.80325" Lng="175.01008"/>
|
||||
<Limit Lat="-36.80107" Lng="175.0089"/>
|
||||
<Limit Lat="-36.79567" Lng="175.00961"/>
|
||||
</CourseLimit>
|
||||
|
||||
</RaceDefinition>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<GridPane fx:id="finishScreenGridPane" maxHeight="837.0" maxWidth="837.0" minHeight="837.0" minWidth="837.0" nodeOrientation="LEFT_TO_RIGHT" prefHeight="837.0" prefWidth="837.0" style="-fx-background-color: #2C2c36;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.FinishScreenViewController">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="259.0" minHeight="259.0" prefHeight="259.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="64.0" minHeight="64.0" prefHeight="64.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="257.0" minHeight="257.0" prefHeight="257.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="257.0" minHeight="257.0" prefHeight="257.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label alignment="CENTER" text="Race Finished!" textFill="WHITE" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||
<font>
|
||||
<Font size="40.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label alignment="CENTER" text="Race Result:" textFill="WHITE" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<font>
|
||||
<Font size="28.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<TableView fx:id="finishOrderTable" maxWidth="661.0" prefHeight="324.0" prefWidth="629.0" styleClass="ui-table" GridPane.halignment="CENTER" GridPane.rowIndex="2">
|
||||
<columns>
|
||||
<TableColumn fx:id="posCol" editable="false" maxWidth="74.0" minWidth="74.0" prefWidth="74.0" resizable="false" sortable="false" text="Position" />
|
||||
<TableColumn fx:id="boatNameCol" editable="false" maxWidth="171.0" minWidth="171.0" prefWidth="171.0" resizable="false" sortable="false" text="Boat Name" />
|
||||
<TableColumn fx:id="shortNameCol" editable="false" maxWidth="155.18472290039062" minWidth="107.0" prefWidth="155.18472290039062" resizable="false" sortable="false" text="Short Name" />
|
||||
<TableColumn fx:id="countryCol" editable="false" maxWidth="258.9999694824219" minWidth="147.0" prefWidth="258.9999694824219" resizable="false" sortable="false" text="Country" />
|
||||
</columns>
|
||||
<GridPane.margin>
|
||||
<Insets bottom="50.0" />
|
||||
</GridPane.margin>
|
||||
</TableView>
|
||||
<Button mnemonicParsing="false" onAction="#switchToStartScreenView" onMouseEntered="#playButtonHoverSound" styleClass="blue-ui-btn" text="Return to Start Screen" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="TOP" />
|
||||
</children>
|
||||
</GridPane>
|
||||
@@ -66,6 +66,11 @@
|
||||
<GridPane.margin>
|
||||
<Insets right="20.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<Label fx:id="portNumber" text="Port: 4191" GridPane.columnIndex="2" GridPane.halignment="RIGHT" GridPane.rowIndex="1">
|
||||
<GridPane.margin>
|
||||
<Insets right="20.0" top="-15.0" />
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
</children>
|
||||
<columnConstraints>
|
||||
@@ -80,12 +85,9 @@
|
||||
</GridPane>
|
||||
<GridPane GridPane.rowIndex="1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="NEVER" maxWidth="-Infinity" minWidth="-Infinity"
|
||||
prefWidth="115.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308"
|
||||
minWidth="337.0" prefWidth="430.0"/>
|
||||
<ColumnConstraints hgrow="NEVER" maxWidth="350.0" minWidth="350.0"
|
||||
prefWidth="350.0"/>
|
||||
<ColumnConstraints hgrow="NEVER" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="115.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="337.0" prefWidth="430.0" />
|
||||
<ColumnConstraints hgrow="NEVER" maxWidth="350.0" minWidth="350.0" prefWidth="350.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints vgrow="SOMETIMES" />
|
||||
@@ -110,116 +112,92 @@
|
||||
<Insets bottom="15.0" left="7.0" right="7.0" top="15.0" />
|
||||
</GridPane.margin>
|
||||
</AnchorPane>
|
||||
<GridPane prefHeight="370.0" prefWidth="189.0" styleClass="tokenGridView"
|
||||
vgap="5.0">
|
||||
<GridPane prefHeight="370.0" prefWidth="189.0" styleClass="tokenGridView" vgap="5.0">
|
||||
<children>
|
||||
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Tokens"
|
||||
GridPane.halignment="CENTER">
|
||||
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Tokens" GridPane.halignment="CENTER">
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0"/>
|
||||
<Font name="System Bold" size="18.0" />
|
||||
</font>
|
||||
</Text>
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0"
|
||||
GridPane.rowIndex="1">
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label alignment="BOTTOM_CENTER" text="Speed"
|
||||
StackPane.alignment="BOTTOM_CENTER">
|
||||
<Label alignment="BOTTOM_CENTER" text="Speed" StackPane.alignment="BOTTOM_CENTER">
|
||||
<font>
|
||||
<Font size="12.0"/>
|
||||
<Font size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="5.0"/>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Pane fx:id="speedTokenPane" prefHeight="999.0"
|
||||
prefWidth="200.0" styleClass="tokenView"/>
|
||||
<Pane fx:id="speedTokenPane" prefHeight="999.0" prefWidth="200.0" styleClass="tokenView" />
|
||||
</children>
|
||||
</StackPane>
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0"
|
||||
GridPane.rowIndex="2">
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label alignment="BOTTOM_CENTER" text="Handling"
|
||||
StackPane.alignment="BOTTOM_CENTER">
|
||||
<Label alignment="BOTTOM_CENTER" text="Handling" StackPane.alignment="BOTTOM_CENTER">
|
||||
<font>
|
||||
<Font size="12.0"/>
|
||||
<Font size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="5.0"/>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Pane fx:id="handlingTokenPane" prefHeight="999.0"
|
||||
prefWidth="200.0" styleClass="tokenView"/>
|
||||
<Pane fx:id="handlingTokenPane" prefHeight="999.0" prefWidth="200.0" styleClass="tokenView" />
|
||||
</children>
|
||||
</StackPane>
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0"
|
||||
GridPane.rowIndex="3">
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label alignment="BOTTOM_CENTER" text="Wind Walker"
|
||||
StackPane.alignment="BOTTOM_CENTER">
|
||||
<Label alignment="BOTTOM_CENTER" text="Wind Walker" StackPane.alignment="BOTTOM_CENTER">
|
||||
<font>
|
||||
<Font size="12.0"/>
|
||||
<Font size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="5.0"/>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Pane fx:id="windWalkerTokenPane" prefHeight="999.0"
|
||||
prefWidth="200.0" styleClass="tokenView"/>
|
||||
<Pane fx:id="windWalkerTokenPane" prefHeight="999.0" prefWidth="200.0" styleClass="tokenView" />
|
||||
</children>
|
||||
</StackPane>
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0"
|
||||
GridPane.rowIndex="4">
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Label alignment="BOTTOM_CENTER" text="Bumper"
|
||||
StackPane.alignment="BOTTOM_CENTER">
|
||||
<Label alignment="BOTTOM_CENTER" text="Bumper" StackPane.alignment="BOTTOM_CENTER">
|
||||
<font>
|
||||
<Font size="12.0"/>
|
||||
<Font size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="5.0"/>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Pane fx:id="bumperTokenPane" prefHeight="999.0"
|
||||
prefWidth="200.0" styleClass="tokenView"/>
|
||||
<Pane fx:id="bumperTokenPane" prefHeight="999.0" prefWidth="200.0" styleClass="tokenView" />
|
||||
</children>
|
||||
</StackPane>
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0"
|
||||
GridPane.rowIndex="5">
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0" GridPane.rowIndex="5">
|
||||
<children>
|
||||
<Label alignment="BOTTOM_CENTER" text="Random"
|
||||
StackPane.alignment="BOTTOM_CENTER">
|
||||
<Label alignment="BOTTOM_CENTER" text="Random" StackPane.alignment="BOTTOM_CENTER">
|
||||
<font>
|
||||
<Font size="12.0"/>
|
||||
<Font size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="5.0"/>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Pane fx:id="randomTokenPane" prefHeight="999.0"
|
||||
prefWidth="60.0" styleClass="tokenView"/>
|
||||
<Pane fx:id="randomTokenPane" prefHeight="999.0" prefWidth="60.0" styleClass="tokenView" />
|
||||
</children>
|
||||
</StackPane>
|
||||
</children>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="80.0" minWidth="80.0"
|
||||
prefWidth="80.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="80.0" minWidth="80.0" prefWidth="80.0" />
|
||||
</columnConstraints>
|
||||
<padding>
|
||||
<Insets bottom="15.0" left="15.0" right="7.0" top="15.0"/>
|
||||
<Insets bottom="15.0" left="15.0" right="7.0" top="15.0" />
|
||||
</padding>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="116.0" minHeight="0.0" prefHeight="40.0"
|
||||
vgrow="NEVER"/>
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity"
|
||||
prefHeight="60.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity"
|
||||
prefHeight="60.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="141.0" minHeight="-Infinity"
|
||||
prefHeight="60.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity"
|
||||
prefHeight="60.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity"
|
||||
prefHeight="60.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="116.0" minHeight="0.0" prefHeight="40.0" vgrow="NEVER" />
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="141.0" minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
</GridPane>
|
||||
</children>
|
||||
@@ -236,7 +214,7 @@
|
||||
</GridPane>
|
||||
</children>
|
||||
<stylesheets>
|
||||
<URL value="@../css/Master.css"/>
|
||||
<URL value="@../css/LobbyView.css"/>
|
||||
<URL value="@../css/Master.css" />
|
||||
<URL value="@../css/LobbyView.css" />
|
||||
</stylesheets>
|
||||
</StackPane>
|
||||
|
||||
@@ -2,18 +2,21 @@
|
||||
|
||||
<?import com.jfoenix.controls.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import java.net.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.image.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXSpinner?>
|
||||
<?import com.jfoenix.controls.JFXTextField?>
|
||||
<?import java.lang.String?>
|
||||
<?import java.net.URL?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.image.Image?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
@@ -24,9 +27,9 @@
|
||||
<StackPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1200.0" style="-fx-background-color: skyblue;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.RaceViewController">
|
||||
<children>
|
||||
<StackPane fx:id="contentStackPane" maxHeight="1.7976931348623157E308"
|
||||
maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0"
|
||||
prefWidth="1200.0" style="-fx-background-color: skyblue;" xmlns="http://javafx.com/javafx/8.0.111"
|
||||
xmlns:fx="http://javafx.com/fxml/1">
|
||||
maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity"
|
||||
prefHeight="800.0" prefWidth="1200.0" style="-fx-background-color: skyblue;"
|
||||
xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
|
||||
prefHeight="800.0" prefWidth="1200.0">
|
||||
@@ -34,8 +37,8 @@
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="250.0" minWidth="250.0"
|
||||
prefWidth="250.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="400.0"
|
||||
prefWidth="400.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity"
|
||||
minWidth="400.0" prefWidth="400.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="70.0" minHeight="70.0" prefHeight="70.0"
|
||||
@@ -47,13 +50,14 @@
|
||||
<children>
|
||||
<GridPane id="timerGrid" fx:id="timerGrid" prefWidth="192.0" styleClass="timer">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="50.0" minWidth="50.0"
|
||||
prefWidth="50.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="135.0" minWidth="135.0"
|
||||
prefWidth="135.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="50.0"
|
||||
minWidth="50.0" prefWidth="50.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="135.0"
|
||||
minWidth="135.0" prefWidth="135.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
@@ -72,8 +76,9 @@
|
||||
<Insets/>
|
||||
</GridPane.margin>
|
||||
</ImageView>
|
||||
<Label fx:id="timerLabel" text="00:03:34" GridPane.columnIndex="1"
|
||||
GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||
<Label fx:id="timerLabel" text="00:03:34"
|
||||
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||
GridPane.valignment="CENTER">
|
||||
<font>
|
||||
<Font size="21.0"/>
|
||||
</font>
|
||||
@@ -85,57 +90,68 @@
|
||||
</GridPane>
|
||||
<GridPane GridPane.columnIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
</GridPane>
|
||||
<GridPane fx:id="chatGridPane" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="390.0" minWidth="390.0"
|
||||
prefWidth="390.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="390.0"
|
||||
minWidth="390.0" prefWidth="390.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0"
|
||||
<RowConstraints maxHeight="1.7976931348623157E308"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="60.0" minHeight="60.0"
|
||||
prefHeight="60.0" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Pane fx:id="chatHistoryHolder" prefHeight="200.0" prefWidth="200.0"
|
||||
GridPane.hgrow="ALWAYS" GridPane.valignment="BOTTOM"
|
||||
GridPane.vgrow="ALWAYS">
|
||||
<Pane fx:id="chatHistoryHolder" prefHeight="200.0"
|
||||
prefWidth="200.0" GridPane.hgrow="ALWAYS"
|
||||
GridPane.valignment="BOTTOM" GridPane.vgrow="ALWAYS">
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0"
|
||||
top="10.0"/>
|
||||
</padding>
|
||||
</Pane>
|
||||
<GridPane fx:id="chatInputHolder" GridPane.rowIndex="1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity"
|
||||
minWidth="90.0" prefWidth="90.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES"
|
||||
maxWidth="-Infinity" minWidth="90.0"
|
||||
prefWidth="90.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0"
|
||||
valignment="CENTER" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||
prefHeight="50.0" valignment="CENTER"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<JFXButton fx:id="chatSend" alignment="CENTER" buttonType="RAISED"
|
||||
focusTraversable="false" maxHeight="-Infinity"
|
||||
maxWidth="1.7976931348623157E308" minHeight="-Infinity"
|
||||
minWidth="-Infinity" prefHeight="35.0" text="SEND"
|
||||
<JFXButton fx:id="chatSend" alignment="CENTER"
|
||||
buttonType="RAISED" focusTraversable="false"
|
||||
maxHeight="-Infinity"
|
||||
maxWidth="1.7976931348623157E308"
|
||||
minHeight="-Infinity" minWidth="-Infinity"
|
||||
prefHeight="35.0" text="SEND"
|
||||
GridPane.columnIndex="1">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0"
|
||||
top="10.0"/>
|
||||
</GridPane.margin>
|
||||
</JFXButton>
|
||||
<JFXTextField fx:id="chatInput" focusTraversable="false"
|
||||
maxHeight="35.0" minHeight="-Infinity" prefHeight="35.0">
|
||||
maxHeight="35.0" minHeight="-Infinity"
|
||||
prefHeight="35.0">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="20.0" right="10.0"/>
|
||||
</GridPane.margin>
|
||||
@@ -153,31 +169,33 @@
|
||||
<Insets bottom="10.0" right="10.0"/>
|
||||
</GridPane.margin>
|
||||
</GridPane>
|
||||
<GridPane fx:id="windGridPane" maxHeight="-Infinity" maxWidth="-Infinity"
|
||||
prefHeight="150.0" prefWidth="240.0" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="2" GridPane.valignment="BOTTOM">
|
||||
<GridPane fx:id="windGridPane" maxHeight="-Infinity"
|
||||
maxWidth="-Infinity" prefHeight="150.0" prefWidth="240.0"
|
||||
GridPane.halignment="CENTER" GridPane.rowIndex="2"
|
||||
GridPane.valignment="BOTTOM">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="110.0" minWidth="110.0"
|
||||
prefWidth="110.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="132.0" minWidth="10.0"
|
||||
prefWidth="132.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="110.0"
|
||||
minWidth="110.0" prefWidth="110.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="132.0"
|
||||
minWidth="10.0" prefWidth="132.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="120.0" minHeight="120.0" prefHeight="120.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="120.0" minHeight="120.0"
|
||||
prefHeight="120.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0"
|
||||
prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label fx:id="positionLabel" text="Position:" GridPane.columnIndex="1"
|
||||
GridPane.halignment="LEFT" GridPane.rowSpan="2" GridPane.valignment="TOP">
|
||||
<Label fx:id="positionLabel" text="Position:"
|
||||
GridPane.columnIndex="1" GridPane.halignment="LEFT"
|
||||
GridPane.rowSpan="2" GridPane.valignment="TOP">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="boatSpeedLabel" text="Boat Speed:" GridPane.columnIndex="1"
|
||||
GridPane.halignment="LEFT" GridPane.rowSpan="2"
|
||||
GridPane.valignment="CENTER">
|
||||
<Label fx:id="boatSpeedLabel" text="Boat Speed:"
|
||||
GridPane.columnIndex="1" GridPane.halignment="LEFT"
|
||||
GridPane.rowSpan="2" GridPane.valignment="CENTER">
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
</opaqueInsets>
|
||||
@@ -186,8 +204,8 @@
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="boatHeadingLabel" text="Boat Heading:"
|
||||
GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowSpan="2"
|
||||
GridPane.valignment="BOTTOM">
|
||||
GridPane.columnIndex="1" GridPane.halignment="LEFT"
|
||||
GridPane.rowSpan="2" GridPane.valignment="BOTTOM">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
@@ -200,14 +218,14 @@
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="120.0" minHeight="120.0"
|
||||
prefHeight="120.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0"
|
||||
prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<ImageView fx:id="windImageView" fitHeight="92.0" fitWidth="109.0"
|
||||
pickOnBounds="true" preserveRatio="true"
|
||||
GridPane.halignment="CENTER" GridPane.rowSpan="2"
|
||||
GridPane.valignment="CENTER"/>
|
||||
<ImageView fx:id="windImageView" fitHeight="92.0"
|
||||
fitWidth="109.0" pickOnBounds="true"
|
||||
preserveRatio="true" GridPane.halignment="CENTER"
|
||||
GridPane.rowSpan="2" GridPane.valignment="CENTER"/>
|
||||
<Label fx:id="windSpeedLabel" text="0.0 Knots"
|
||||
GridPane.halignment="RIGHT" GridPane.rowIndex="1"
|
||||
GridPane.valignment="CENTER">
|
||||
@@ -234,22 +252,28 @@
|
||||
</GridPane>
|
||||
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="152.0" minHeight="10.0" prefHeight="152.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="118.0" minHeight="10.0" prefHeight="98.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="152.0" minHeight="10.0"
|
||||
prefHeight="152.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="118.0" minHeight="10.0"
|
||||
prefHeight="98.0" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<ImageView fx:id="velocityIcon" fitHeight="88.0" fitWidth="106.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.halignment="CENTER" GridPane.rowIndex="1">
|
||||
<ImageView fx:id="velocityIcon" fitHeight="88.0"
|
||||
fitWidth="106.0" pickOnBounds="true" preserveRatio="true"
|
||||
visible="false" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/velocity.png"/>
|
||||
</image>
|
||||
@@ -262,10 +286,10 @@
|
||||
<Image url="@../icons/handlingIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="windWalkerIcon" fitHeight="83.0" fitWidth="100.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="2" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1">
|
||||
<ImageView fx:id="windWalkerIcon" fitHeight="83.0"
|
||||
fitWidth="100.0" pickOnBounds="true" preserveRatio="true"
|
||||
visible="false" GridPane.columnIndex="2"
|
||||
GridPane.halignment="CENTER" GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/windWalkerIcon.png"/>
|
||||
</image>
|
||||
@@ -278,10 +302,11 @@
|
||||
<Image url="@../icons/bumperIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="badRandomIcon" fitHeight="69.0" fitWidth="103.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="4" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<ImageView fx:id="badRandomIcon" fitHeight="69.0"
|
||||
fitWidth="103.0" pickOnBounds="true" preserveRatio="true"
|
||||
visible="false" GridPane.columnIndex="4"
|
||||
GridPane.halignment="CENTER" GridPane.rowIndex="1"
|
||||
GridPane.valignment="CENTER">
|
||||
<image>
|
||||
<Image url="@../icons/slowedIcon.png"/>
|
||||
</image>
|
||||
@@ -292,12 +317,13 @@
|
||||
</GridPane>
|
||||
</children>
|
||||
</StackPane>
|
||||
<Pane fx:id="miniMapPane" maxHeight="200.0" maxWidth="200.0" minHeight="200.0" minWidth="200.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white; -fx-opacity: 0.45; -fx-background-radius: 10;" StackPane.alignment="TOP_RIGHT">
|
||||
<Pane fx:id="miniMapPane" maxHeight="200.0" maxWidth="200.0" minHeight="200.0"
|
||||
minWidth="200.0" prefHeight="200.0" prefWidth="200.0" StackPane.alignment="TOP_RIGHT">
|
||||
<StackPane.margin>
|
||||
<Insets right="15.0" top="15.0" />
|
||||
</StackPane.margin>
|
||||
</Pane>
|
||||
<JFXButton fx:id="miniMapButton" style="-fx-background-color: white; -fx-opacity: 0.45; -fx-background-radius: 10;" text="✕" StackPane.alignment="TOP_RIGHT">
|
||||
<JFXButton fx:id="miniMapButton" text="—" StackPane.alignment="TOP_RIGHT">
|
||||
<font>
|
||||
<Font size="15.0" />
|
||||
</font>
|
||||
@@ -306,12 +332,23 @@
|
||||
</StackPane.margin>
|
||||
</JFXButton>
|
||||
<AnchorPane fx:id="loadingScreenPane">
|
||||
<ImageView fx:id="loadingScreen" fitHeight="672.0" fitWidth="1200.0" pickOnBounds="true" preserveRatio="true" />
|
||||
<JFXSpinner layoutX="566.0" layoutY="692.0" radius="30.0" />
|
||||
<children>
|
||||
<ImageView fx:id="loadingScreen" fitHeight="672.0" fitWidth="1200.0"
|
||||
pickOnBounds="true" preserveRatio="true"/>
|
||||
<JFXSpinner layoutX="566.0" layoutY="692.0" radius="30.0"/>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<JFXButton fx:id="chatToggleButton" text="—" StackPane.alignment="BOTTOM_RIGHT">
|
||||
<font>
|
||||
<Font size="15.0"/>
|
||||
</font>
|
||||
<StackPane.margin>
|
||||
<Insets bottom="70.0" right="10.0"/>
|
||||
</StackPane.margin>
|
||||
</JFXButton>
|
||||
</children>
|
||||
<stylesheets>
|
||||
<String fx:value="/css/Master.css" />
|
||||
<String fx:value="/css/RaceView.css" />
|
||||
<URL value="@../css/Master.css"/>
|
||||
<URL value="@../css/RaceView.css"/>
|
||||
</stylesheets>
|
||||
</StackPane>
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.String?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<AnchorPane fx:id="annotationSelectWindow" maxHeight="270.0" maxWidth="469.0" minHeight="270.0" minWidth="469.0" prefHeight="270.0" prefWidth="469.0" styleClass="background-blue" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Text fill="WHITE" layoutX="26.0" layoutY="52.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Select important annotations">
|
||||
<font>
|
||||
<Font size="24.0" />
|
||||
</font>
|
||||
</Text>
|
||||
<CheckBox fx:id="boatWakeSelect" layoutX="26.0" layoutY="80.0" mnemonicParsing="false" style="-fx-border-width: 0; -fx-background-insets: 0;" text="Boat Wakes" textFill="#e7e7e7" />
|
||||
<CheckBox fx:id="boatSpeedSelect" layoutX="26.0" layoutY="111.0" mnemonicParsing="false" text="Boat Speed" textFill="#e7e7e7" />
|
||||
<CheckBox fx:id="boatTrackSelect" layoutX="26.0" layoutY="142.0" mnemonicParsing="false" text="Boat Tracks" textFill="#e7e7e7" />
|
||||
<CheckBox fx:id="boatNameSelect" layoutX="26.0" layoutY="173.0" mnemonicParsing="false" text="Boat Name" textFill="#e7e7e7" />
|
||||
<CheckBox fx:id="boatEstTimeToNextMarkSelect" layoutX="26.0" layoutY="204.0" mnemonicParsing="false" text="Boat Estimated Time To Next Mark" textFill="#e7e7e7" />
|
||||
<Button fx:id="closeButton" layoutX="424.0" layoutY="-1.0" mnemonicParsing="false" prefHeight="11.0" prefWidth="49.0" style=": 0;" text="X" textFill="#ffffff4e">
|
||||
<font>
|
||||
<Font size="24.0" />
|
||||
</font>
|
||||
<styleClass>
|
||||
<String fx:value="background-blue" />
|
||||
<String fx:value="clearExitButton" />
|
||||
</styleClass>
|
||||
</Button>
|
||||
<CheckBox fx:id="boatElapsedTimeSelect" layoutX="26.0" layoutY="235.0" mnemonicParsing="false" text="Boat Elapsed Time Since Last Mark" textFill="#e7e7e7" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
@@ -48,9 +48,10 @@ public class ServerTableTest {
|
||||
|
||||
serverTable.addServer(listing);
|
||||
|
||||
listing.decrementTtl();
|
||||
listing.decrementTtl();
|
||||
|
||||
Thread.sleep(1000);
|
||||
Thread.sleep(1500);
|
||||
|
||||
assertTrue(!serverTable.getAllServers().contains(listing));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package seng302.utilities;
|
||||
|
||||
/**
|
||||
* Created by cir27 on 28/09/17.
|
||||
*/
|
||||
public class MapMakerTest {
|
||||
// @Test
|
||||
|
||||
}
|
||||
@@ -12,7 +12,7 @@ public class DisconnectionTest {
|
||||
@Test
|
||||
public void testServerDisconnection () throws Exception {
|
||||
MainServerThread serverThread = new MainServerThread();
|
||||
ClientToServerThread clientThread = new ClientToServerThread("localhost", 4942);
|
||||
ClientToServerThread clientThread = new ClientToServerThread("localhost", serverThread.getPortNumber());
|
||||
Thread.sleep(1000);
|
||||
clientThread.addDisconnectionListener(message -> Assert.assertTrue(message != null));
|
||||
serverThread.terminate();
|
||||
|
||||
@@ -20,7 +20,7 @@ public class RegularPacketsTest {
|
||||
public void setup() throws Exception {
|
||||
new GameState();
|
||||
serverThread = new MainServerThread();
|
||||
clientThread = new ClientToServerThread("localhost", 4942);
|
||||
clientThread = new ClientToServerThread("localhost", serverThread.getPortNumber());
|
||||
GameState.setCurrentStage(GameStages.RACING);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package seng302.visualiser.map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import seng302.model.GeoPoint;
|
||||
|
||||
/**
|
||||
* Unit test for Mercator Project class.
|
||||
* Created by hyi25 on 15/05/17.
|
||||
*/
|
||||
public class MercatorProjectionTest {
|
||||
@Test
|
||||
public void toMapPoint() throws Exception {
|
||||
GeoPoint geo1 = new GeoPoint(12.485394, 19.38947);
|
||||
javafx.geometry.Point2D actualPoint1 = MercatorProjection.toMapPoint(geo1);
|
||||
javafx.geometry.Point2D expectedPoint1 = new javafx.geometry.Point2D(141.78806755555556, 119.0503853635612);
|
||||
assertEquals(expectedPoint1.getX(), actualPoint1.getX(), 0.0001);
|
||||
assertEquals(expectedPoint1.getY(), actualPoint1.getY(), 0.0001);
|
||||
|
||||
GeoPoint geo2 = new GeoPoint(77.456432, -23.456462);
|
||||
javafx.geometry.Point2D actualPoint2 = MercatorProjection.toMapPoint(geo2);
|
||||
javafx.geometry.Point2D expectedPoint2 = new javafx.geometry.Point2D(111.31984924444444, 38.03143323746788);
|
||||
assertEquals(expectedPoint2.getX(), actualPoint2.getX(), 0.0001);
|
||||
assertEquals(expectedPoint2.getY(), actualPoint2.getY(), 0.0001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toMapGeo() throws Exception {
|
||||
javafx.geometry.Point2D point1 = new javafx.geometry.Point2D(123.1234, 25.4565);
|
||||
GeoPoint actualGeo1 = MercatorProjection.toMapGeo(point1);
|
||||
GeoPoint expectedGeo1 = new GeoPoint(80.77043127275441, -6.857718749999995);
|
||||
assertEquals(expectedGeo1.getLat(), actualGeo1.getLat(), 0.0001);
|
||||
assertEquals(expectedGeo1.getLng(), actualGeo1.getLng(), 0.0001);
|
||||
|
||||
javafx.geometry.Point2D point2 = new javafx.geometry.Point2D(1.235, 255.4565);
|
||||
GeoPoint actualGeo2 = MercatorProjection.toMapGeo(point2);
|
||||
GeoPoint expectedGeo2 = new GeoPoint(-84.98475532898011, -178.26328125);
|
||||
assertEquals(expectedGeo2.getLat(), actualGeo2.getLat(), 0.0001);
|
||||
assertEquals(expectedGeo2.getLng(), actualGeo2.getLng(), 0.0001);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,9 @@ package steps;
|
||||
import cucumber.api.java.en.Given;
|
||||
import cucumber.api.java.en.Then;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import org.junit.Assert;
|
||||
import seng302.visualiser.MapMaker;
|
||||
|
||||
@@ -16,26 +19,26 @@ public class CustomMapsSteps {
|
||||
|
||||
@Given("^that the game has multiple race xml files$")
|
||||
public void that_the_game_has_multiple_race_xml_files() throws Throwable {
|
||||
// mapMaker = MapMaker.getInstance();
|
||||
// String firstMap = mapMaker.getCurrentRacePath();
|
||||
// int numMaps = 0;
|
||||
// do {
|
||||
// mapMaker.next();
|
||||
// numMaps++;
|
||||
// } while (!mapMaker.getCurrentRacePath().equals(firstMap));
|
||||
// Assert.assertTrue(numMaps >= 2);
|
||||
mapMaker = MapMaker.getInstance();
|
||||
String firstMap = mapMaker.getCurrentRacePath();
|
||||
int numMaps = 0;
|
||||
do {
|
||||
mapMaker.next();
|
||||
numMaps++;
|
||||
} while (!mapMaker.getCurrentRacePath().equals(firstMap));
|
||||
Assert.assertTrue(numMaps >= 2);
|
||||
}
|
||||
|
||||
@Then("^all of them can be seen$")
|
||||
public void all_of_them_can_be_seen() throws Throwable {
|
||||
// File[] files = new File(this.getClass().getResource("/maps/").getPath()).listFiles();
|
||||
// for (File file : files) {
|
||||
// if (file.isFile()) {
|
||||
// Assert.assertTrue(file.getAbsolutePath().equals(mapMaker.getCurrentRacePath()));
|
||||
// mapMaker.next();
|
||||
// System.out.println(file.getAbsolutePath());
|
||||
// }
|
||||
// }
|
||||
File[] files = new File(this.getClass().getResource("/maps/").getPath()).listFiles();
|
||||
Arrays.sort(files);
|
||||
for (File file : files) {
|
||||
if (file.isFile()) {
|
||||
Assert.assertTrue(file.getAbsolutePath().endsWith(mapMaker.getCurrentRacePath()));
|
||||
mapMaker.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Given("^that I choose a race$")
|
||||
|
||||
@@ -45,7 +45,7 @@ public class SendChatSteps {
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
host = new ClientToServerThread("localhost", 4942);
|
||||
host = new ClientToServerThread("localhost", mst.getPortNumber());
|
||||
host.addStreamObserver(() -> {
|
||||
while (host.getPacketQueue().peek() != null) {
|
||||
StreamPacket packet = host.getPacketQueue().poll();
|
||||
@@ -68,7 +68,7 @@ public class SendChatSteps {
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
client = new ClientToServerThread("localhost", 4942);
|
||||
client = new ClientToServerThread("localhost", mst.getPortNumber());
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ie) {
|
||||
|
||||
@@ -44,7 +44,7 @@ public class ToggleSailSteps {
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
client = new ClientToServerThread("localhost", 4942);
|
||||
client = new ClientToServerThread("localhost", mst.getPortNumber());
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ie) {
|
||||
|
||||
Reference in New Issue
Block a user