mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Fixed connecting to hosts. Fixed issue34 and 35 to the point where they can be developed off of.
#refactor #bug #issue[34, 35]
This commit is contained in:
@@ -9,7 +9,7 @@ import javafx.collections.FXCollections;
|
|||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import seng302.model.Player;
|
import seng302.model.Player;
|
||||||
import seng302.model.Yacht;
|
import seng302.model.Yacht;
|
||||||
import seng302.server.messages.BoatActionType;
|
import seng302.gameServer.server.messages.BoatActionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Static class to hold information about the current state of the game (model)
|
* A Static class to hold information about the current state of the game (model)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import java.util.Stack;
|
|||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import seng302.model.Player;
|
import seng302.model.Player;
|
||||||
import seng302.server.messages.Heartbeat;
|
import seng302.gameServer.server.messages.Heartbeat;
|
||||||
import seng302.server.messages.Message;
|
import seng302.gameServer.server.messages.Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send Heartbeat messages to connected player at a specified interval
|
* Send Heartbeat messages to connected player at a specified interval
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package seng302.gameServer;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import seng302.model.stream.packets.StreamPacket;
|
import seng302.model.stream.packets.StreamPacket;
|
||||||
import seng302.server.messages.BoatActionType;
|
import seng302.gameServer.server.messages.BoatActionType;
|
||||||
|
|
||||||
|
|
||||||
public class ServerPacketParser {
|
public class ServerPacketParser {
|
||||||
|
|||||||
@@ -25,16 +25,16 @@ import seng302.model.stream.packets.StreamPacket;
|
|||||||
import seng302.model.stream.xml.generator.Race;
|
import seng302.model.stream.xml.generator.Race;
|
||||||
import seng302.model.stream.xml.generator.Regatta;
|
import seng302.model.stream.xml.generator.Regatta;
|
||||||
import seng302.utilities.XMLGenerator;
|
import seng302.utilities.XMLGenerator;
|
||||||
import seng302.server.messages.BoatActionType;
|
import seng302.gameServer.server.messages.BoatActionType;
|
||||||
import seng302.server.messages.BoatLocationMessage;
|
import seng302.gameServer.server.messages.BoatLocationMessage;
|
||||||
import seng302.server.messages.BoatStatus;
|
import seng302.gameServer.server.messages.BoatStatus;
|
||||||
import seng302.server.messages.BoatSubMessage;
|
import seng302.gameServer.server.messages.BoatSubMessage;
|
||||||
import seng302.server.messages.Message;
|
import seng302.gameServer.server.messages.Message;
|
||||||
import seng302.server.messages.RaceStatus;
|
import seng302.gameServer.server.messages.RaceStatus;
|
||||||
import seng302.server.messages.RaceStatusMessage;
|
import seng302.gameServer.server.messages.RaceStatusMessage;
|
||||||
import seng302.server.messages.RaceType;
|
import seng302.gameServer.server.messages.RaceType;
|
||||||
import seng302.server.messages.XMLMessage;
|
import seng302.gameServer.server.messages.XMLMessage;
|
||||||
import seng302.server.messages.XMLMessageSubType;
|
import seng302.gameServer.server.messages.XMLMessageSubType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class describing a single connection to a Client for the purposes of sending and receiving on
|
* A class describing a single connection to a Client for the purposes of sending and receiving on
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by kre39 on 12/07/17.
|
* Created by kre39 on 12/07/17.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
public class BoatLocationMessage extends Message {
|
public class BoatLocationMessage extends Message {
|
||||||
private final int MESSAGE_SIZE = 56;
|
private final int MESSAGE_SIZE = 56;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current status of a boat
|
* The current status of a boat
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by kre39 on 20/07/17.
|
* Created by kre39 on 20/07/17.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
public enum DeviceType {
|
public enum DeviceType {
|
||||||
UNKNOWN(0),
|
UNKNOWN(0),
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
public class Heartbeat extends Message {
|
public class Heartbeat extends Message {
|
||||||
private final int MESSAGE_SIZE = 4;
|
private final int MESSAGE_SIZE = 4;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
public class MarkRoundingMessage extends Message{
|
public class MarkRoundingMessage extends Message{
|
||||||
private final long MESSAGE_VERSION_NUMBER = 1;
|
private final long MESSAGE_VERSION_NUMBER = 1;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types of marks boats can round
|
* Types of marks boats can round
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum containing the types of messages
|
* Enum containing the types of messages
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The types of race start status messages
|
* The types of race start status messages
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
public class RaceStartStatusMessage extends Message {
|
public class RaceStartStatusMessage extends Message {
|
||||||
private final int MESSAGE_SIZE = 20;
|
private final int MESSAGE_SIZE = 20;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current status of the race
|
* The current status of the race
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum containing the types of races
|
* Enum containing the types of races
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The status of a boat rounding a mark
|
* The status of a boat rounding a mark
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The side the boat rounded the mark
|
* The side the boat rounded the mark
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
public class XMLMessage extends Message{
|
public class XMLMessage extends Message{
|
||||||
private final MessageType MESSAGE_TYPE = MessageType.XML_MESSAGE;
|
private final MessageType MESSAGE_TYPE = MessageType.XML_MESSAGE;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.messages;
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum containing the types of XML messages
|
* Enum containing the types of XML messages
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.simulator;
|
package seng302.gameServer.server.simulator;
|
||||||
|
|
||||||
import seng302.model.GeoPoint;
|
import seng302.model.GeoPoint;
|
||||||
import seng302.utilities.GeoUtility;
|
import seng302.utilities.GeoUtility;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.simulator;
|
package seng302.gameServer.server.simulator;
|
||||||
|
|
||||||
import seng302.model.mark.CompoundMark;
|
import seng302.model.mark.CompoundMark;
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.simulator;
|
package seng302.gameServer.server.simulator;
|
||||||
|
|
||||||
public enum RoundingType {
|
public enum RoundingType {
|
||||||
|
|
||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
package seng302.server.simulator;
|
package seng302.gameServer.server.simulator;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import seng302.model.mark.Mark;
|
import seng302.model.mark.Mark;
|
||||||
import seng302.server.simulator.parsers.RaceParser;
|
import seng302.gameServer.server.simulator.parsers.RaceParser;
|
||||||
import seng302.model.GeoPoint;
|
import seng302.model.GeoPoint;
|
||||||
import seng302.utilities.GeoUtility;
|
import seng302.utilities.GeoUtility;
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.simulator.parsers;
|
package seng302.gameServer.server.simulator.parsers;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.simulator.parsers;
|
package seng302.gameServer.server.simulator.parsers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -9,9 +9,9 @@ import org.w3c.dom.Element;
|
|||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import seng302.model.mark.CompoundMark;
|
import seng302.model.mark.CompoundMark;
|
||||||
import seng302.server.simulator.Corner;
|
import seng302.gameServer.server.simulator.Corner;
|
||||||
import seng302.model.mark.Mark;
|
import seng302.model.mark.Mark;
|
||||||
import seng302.server.simulator.RoundingType;
|
import seng302.gameServer.server.simulator.RoundingType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the race xml file to get course details
|
* Parses the race xml file to get course details
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.simulator.parsers;
|
package seng302.gameServer.server.simulator.parsers;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.simulator.parsers;
|
package seng302.gameServer.server.simulator.parsers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -6,8 +6,8 @@ import org.w3c.dom.Document;
|
|||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import seng302.server.simulator.Boat;
|
import seng302.gameServer.server.simulator.Boat;
|
||||||
import seng302.server.simulator.Corner;
|
import seng302.gameServer.server.simulator.Corner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the race xml file to get course details
|
* Parses the race xml file to get course details
|
||||||
@@ -9,7 +9,7 @@ import java.io.OutputStreamWriter;
|
|||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import seng302.model.stream.xml.generator.Race;
|
import seng302.model.stream.xml.generator.Race;
|
||||||
import seng302.model.stream.xml.generator.Regatta;
|
import seng302.model.stream.xml.generator.Regatta;
|
||||||
import seng302.server.messages.XMLMessageSubType;
|
import seng302.gameServer.server.messages.XMLMessageSubType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An XML generator to generate the Race, Boat, and Regatta XML dynamically
|
* An XML generator to generate the Race, Boat, and Regatta XML dynamically
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ import javafx.application.Platform;
|
|||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.Alert.AlertType;
|
import javafx.scene.control.Alert.AlertType;
|
||||||
import seng302.model.stream.packets.StreamPacket;
|
import seng302.model.stream.packets.StreamPacket;
|
||||||
import seng302.server.messages.BoatActionMessage;
|
import seng302.gameServer.server.messages.BoatActionMessage;
|
||||||
import seng302.server.messages.Message;
|
import seng302.gameServer.server.messages.Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class describing a single connection to a Server for the purposes of sending and receiving on
|
* A class describing a single connection to a Server for the purposes of sending and receiving on
|
||||||
@@ -130,7 +130,7 @@ public class ClientToServerThread implements Runnable {
|
|||||||
} else {
|
} else {
|
||||||
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
|
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||||
for (ClientSocketListener csl : listeners)
|
for (ClientSocketListener csl : listeners)
|
||||||
Platform.runLater(csl::newPacket);
|
csl.newPacket();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clientLog("Packet has been dropped", 1);
|
clientLog("Packet has been dropped", 1);
|
||||||
@@ -147,6 +147,7 @@ public class ClientToServerThread implements Runnable {
|
|||||||
clientLog(e.getMessage(), 1);
|
clientLog(e.getMessage(), 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// System.out.println("streamPackets = " + streamPackets.size());
|
||||||
}
|
}
|
||||||
closeSocket();
|
closeSocket();
|
||||||
clientLog("Closed connection to Server", 0);
|
clientLog("Closed connection to Server", 0);
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import java.time.ZoneId;
|
|||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import seng302.gameServer.GameState;
|
|
||||||
import seng302.gameServer.MainServerThread;
|
import seng302.gameServer.MainServerThread;
|
||||||
import seng302.model.RaceState;
|
import seng302.model.RaceState;
|
||||||
import seng302.model.Yacht;
|
import seng302.model.Yacht;
|
||||||
@@ -22,8 +22,8 @@ import seng302.model.stream.parser.PositionUpdateData.DeviceType;
|
|||||||
import seng302.model.stream.parser.RaceStatusData;
|
import seng302.model.stream.parser.RaceStatusData;
|
||||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||||
import seng302.server.messages.BoatActionMessage;
|
import seng302.gameServer.server.messages.BoatActionMessage;
|
||||||
import seng302.server.messages.BoatActionType;
|
import seng302.gameServer.server.messages.BoatActionType;
|
||||||
import seng302.utilities.StreamParser;
|
import seng302.utilities.StreamParser;
|
||||||
import seng302.utilities.XMLParser;
|
import seng302.utilities.XMLParser;
|
||||||
import seng302.visualiser.controllers.LobbyController;
|
import seng302.visualiser.controllers.LobbyController;
|
||||||
@@ -62,12 +62,12 @@ public class GameClient {
|
|||||||
ioe.printStackTrace();
|
ioe.printStackTrace();
|
||||||
System.out.println("Unable to connect to host...");
|
System.out.println("Unable to connect to host...");
|
||||||
}
|
}
|
||||||
LobbyController lobbyController = loadLobby("/views/LobbyView.fxml");
|
socketThread.addStreamObserver(this::parsePackets);
|
||||||
|
LobbyController lobbyController = loadLobby();
|
||||||
lobbyController.setPlayerListSource(clientLobbyList);
|
lobbyController.setPlayerListSource(clientLobbyList);
|
||||||
lobbyController.disableReadyButton();
|
lobbyController.disableReadyButton();
|
||||||
lobbyController.setTitle("Connected to host - IP : " + ipAddress + " Port : " + portNumber);
|
lobbyController.setTitle("Connected to host - IP : " + ipAddress + " Port : " + portNumber);
|
||||||
lobbyController.addCloseListener((exitCause) -> this.loadStartScreen());
|
lobbyController.addCloseListener((exitCause) -> this.loadStartScreen());
|
||||||
socketThread.addStreamObserver(this::parsePackets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runAsHost(String ipAddress, Integer portNumber) {
|
public void runAsHost(String ipAddress, Integer portNumber) {
|
||||||
@@ -79,8 +79,8 @@ public class GameClient {
|
|||||||
System.out.println("Unable to make local connection to host...");
|
System.out.println("Unable to make local connection to host...");
|
||||||
}
|
}
|
||||||
socketThread.addStreamObserver(this::parsePackets);
|
socketThread.addStreamObserver(this::parsePackets);
|
||||||
LobbyController lobbyController = loadLobby("/views/LobbyView.fxml");
|
LobbyController lobbyController = loadLobby();
|
||||||
lobbyController.setPlayerListSource(GameState.getObservablePlayers());
|
lobbyController.setPlayerListSource(clientLobbyList);
|
||||||
lobbyController.setTitle("Hosting Lobby - IP : " + ipAddress + " Port : " + portNumber);
|
lobbyController.setTitle("Hosting Lobby - IP : " + ipAddress + " Port : " + portNumber);
|
||||||
lobbyController.addCloseListener(exitCause -> {
|
lobbyController.addCloseListener(exitCause -> {
|
||||||
if (exitCause == CloseStatus.READY) {
|
if (exitCause == CloseStatus.READY) {
|
||||||
@@ -112,11 +112,10 @@ public class GameClient {
|
|||||||
/**
|
/**
|
||||||
* Loads a view of the lobby into the clients pane
|
* Loads a view of the lobby into the clients pane
|
||||||
*
|
*
|
||||||
* @param lobbyView fxml file for the desired lobby
|
|
||||||
* @return the lobby controller.
|
* @return the lobby controller.
|
||||||
*/
|
*/
|
||||||
private LobbyController loadLobby(String lobbyView) {
|
private LobbyController loadLobby() {
|
||||||
FXMLLoader fxmlLoader = new FXMLLoader(GameClient.class.getResource(lobbyView));
|
FXMLLoader fxmlLoader = new FXMLLoader(GameClient.class.getResource("/views/LobbyView.fxml"));
|
||||||
try {
|
try {
|
||||||
holderPane.getChildren().clear();
|
holderPane.getChildren().clear();
|
||||||
holderPane.getChildren().add(fxmlLoader.load());
|
holderPane.getChildren().add(fxmlLoader.load());
|
||||||
@@ -130,9 +129,11 @@ public class GameClient {
|
|||||||
FXMLLoader fxmlLoader = new FXMLLoader(
|
FXMLLoader fxmlLoader = new FXMLLoader(
|
||||||
RaceViewController.class.getResource("/views/RaceView.fxml"));
|
RaceViewController.class.getResource("/views/RaceView.fxml"));
|
||||||
try {
|
try {
|
||||||
Node node = fxmlLoader.load();
|
final Node node = fxmlLoader.load();
|
||||||
holderPane.getChildren().clear();
|
Platform.runLater(() -> {
|
||||||
holderPane.getChildren().add(node);
|
holderPane.getChildren().clear();
|
||||||
|
holderPane.getChildren().add(node);
|
||||||
|
});
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -173,13 +174,14 @@ public class GameClient {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BOAT_XML:
|
case BOAT_XML:
|
||||||
|
System.out.println("GOT SUM BOATS YAY :)");
|
||||||
allBoatsMap = XMLParser.parseBoats(
|
allBoatsMap = XMLParser.parseBoats(
|
||||||
StreamParser.extractXmlMessage(packet)
|
StreamParser.extractXmlMessage(packet)
|
||||||
);
|
);
|
||||||
clientLobbyList.clear();
|
clientLobbyList.clear();
|
||||||
allBoatsMap.forEach((id, boat) -> {
|
allBoatsMap.forEach((id, boat) -> {
|
||||||
clientLobbyList.add(id + " " + boat.getBoatName());
|
clientLobbyList.add(id + " " + boat.getBoatName());
|
||||||
System.out.println(id + " " + boat.getBoatName());
|
// System.out.println(id + " " + boat.getBoatName());
|
||||||
|
|
||||||
});
|
});
|
||||||
// startRaceIfAllDataReceived();
|
// startRaceIfAllDataReceived();
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package seng302.visualiser;
|
package seng302.visualiser;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javafx.animation.AnimationTimer;
|
import javafx.animation.AnimationTimer;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.geometry.Point2D;
|
import javafx.geometry.Point2D;
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
@@ -70,12 +72,13 @@ public class GameView extends Pane {
|
|||||||
private ImageView mapImage = new ImageView();
|
private ImageView mapImage = new ImageView();
|
||||||
|
|
||||||
//FRAME RATE
|
//FRAME RATE
|
||||||
private Double frameRate = 60.0;
|
|
||||||
private final long[] frameTimes = new long[30];
|
|
||||||
private int frameTimeIndex = 0;
|
|
||||||
private boolean arrayFilled = false;
|
|
||||||
|
|
||||||
private AnimationTimer timer;
|
private AnimationTimer timer;
|
||||||
|
private int NUM_SAMPLES = 10;
|
||||||
|
private final long[] frameTimes = new long[NUM_SAMPLES];
|
||||||
|
private Double frameRate = 60.0;
|
||||||
|
private int frameTimeIndex = 0;
|
||||||
|
private boolean arrayFilled = false;
|
||||||
|
|
||||||
private enum ScaleDirection {
|
private enum ScaleDirection {
|
||||||
HORIZONTAL,
|
HORIZONTAL,
|
||||||
@@ -98,9 +101,14 @@ public class GameView extends Pane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializeTimer () {
|
private void initializeTimer () {
|
||||||
|
Arrays.fill(frameTimes, 1_000_000_000 / 60);
|
||||||
timer = new AnimationTimer() {
|
timer = new AnimationTimer() {
|
||||||
private long lastTime = 0;
|
private long lastTime = 0;
|
||||||
private int FPSCount = 30;
|
private int FPSCount = 30;
|
||||||
|
private Double frameRate = 60.0;
|
||||||
|
private int index = 0;
|
||||||
|
private boolean arrayFilled = false;
|
||||||
|
private long sum = 1_000_000_000 / 3;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(long now) {
|
public void handle(long now) {
|
||||||
@@ -121,13 +129,15 @@ public class GameView extends Pane {
|
|||||||
frameRate = 1_000_000_000.0 / elapsedNanosPerFrame;
|
frameRate = 1_000_000_000.0 / elapsedNanosPerFrame;
|
||||||
if (FPSCount-- == 0) {
|
if (FPSCount-- == 0) {
|
||||||
FPSCount = 30;
|
FPSCount = 30;
|
||||||
drawFps(frameRate.intValue());
|
drawFps(frameRate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
boatObjects.forEach((boat, boatObject) -> boatObject.updateLocation());
|
|
||||||
lastTime = now;
|
lastTime = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Platform.runLater(() ->
|
||||||
|
// boatObjects.forEach((boat, boatObject) -> boatObject.updateLocation())
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -175,10 +185,9 @@ public class GameView extends Pane {
|
|||||||
*/
|
*/
|
||||||
public void updateCourse(List<CompoundMark> newCourse, List<Corner> sequence) {
|
public void updateCourse(List<CompoundMark> newCourse, List<Corner> sequence) {
|
||||||
markerObjects = new HashMap<>();
|
markerObjects = new HashMap<>();
|
||||||
|
final List<Gate> gates = new ArrayList<>();
|
||||||
Paint colour = Color.BLACK;
|
Paint colour = Color.BLACK;
|
||||||
markers.getChildren().clear();
|
|
||||||
//Creates new markers
|
//Creates new markers
|
||||||
System.out.println(newCourse.size());
|
|
||||||
for (CompoundMark cMark : newCourse) {
|
for (CompoundMark cMark : newCourse) {
|
||||||
//Set start and end colour
|
//Set start and end colour
|
||||||
if (cMark.getId() == sequence.get(0).getCompoundMarkID()) {
|
if (cMark.getId() == sequence.get(0).getCompoundMarkID()) {
|
||||||
@@ -189,26 +198,24 @@ public class GameView extends Pane {
|
|||||||
//Create mark dots
|
//Create mark dots
|
||||||
for (Mark mark : cMark.getMarks()) {
|
for (Mark mark : cMark.getMarks()) {
|
||||||
makeAndBindMarker(mark, colour);
|
makeAndBindMarker(mark, colour);
|
||||||
System.out.println("hi" + mark.getName());
|
|
||||||
}
|
}
|
||||||
//Create gate line
|
//Create gate line
|
||||||
if (cMark.isGate()) {
|
if (cMark.isGate()) {
|
||||||
for (int i = 1; i < cMark.getMarks().size(); i++) {
|
for (int i = 1; i < cMark.getMarks().size(); i++) {
|
||||||
makeAndBindGate(
|
gates.add(
|
||||||
markerObjects.get(cMark.getSubMark(i)),
|
makeAndBindGate(
|
||||||
markerObjects.get(cMark.getSubMark(i+1)),
|
markerObjects.get(cMark.getSubMark(i)),
|
||||||
colour
|
markerObjects.get(cMark.getSubMark(i+1)),
|
||||||
|
colour
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
colour = Color.BLACK;
|
colour = Color.BLACK;
|
||||||
System.out.println("cMark.toString() = " + cMark.toString());
|
|
||||||
}
|
}
|
||||||
//Set X,Y co-ordinates
|
//Scale race to markers if there is no border.
|
||||||
if (borderPoints == null) {
|
if (borderPoints == null) {
|
||||||
rescaleRace(new ArrayList<>(markerObjects.keySet()));
|
rescaleRace(new ArrayList<>(markerObjects.keySet()));
|
||||||
} else {
|
|
||||||
rescaleRace(new ArrayList<>(borderPoints));
|
|
||||||
}
|
}
|
||||||
//Move the Markers to initial position.
|
//Move the Markers to initial position.
|
||||||
markerObjects.forEach(((mark, marker) -> {
|
markerObjects.forEach(((mark, marker) -> {
|
||||||
@@ -216,7 +223,11 @@ public class GameView extends Pane {
|
|||||||
marker.setCenterX(p2d.getX());
|
marker.setCenterX(p2d.getX());
|
||||||
marker.setCenterY(p2d.getY());
|
marker.setCenterY(p2d.getY());
|
||||||
}));
|
}));
|
||||||
markers.getChildren().addAll(markerObjects.values());
|
Platform.runLater(() -> {
|
||||||
|
markers.getChildren().clear();
|
||||||
|
markers.getChildren().addAll(gates);
|
||||||
|
markers.getChildren().addAll(markerObjects.values());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -241,8 +252,9 @@ public class GameView extends Pane {
|
|||||||
* @param m1 The first Mark of the gate.
|
* @param m1 The first Mark of the gate.
|
||||||
* @param m2 The second Mark of the gate.
|
* @param m2 The second Mark of the gate.
|
||||||
* @param colour The desired colour of the gate.
|
* @param colour The desired colour of the gate.
|
||||||
|
* @return the new gate.
|
||||||
*/
|
*/
|
||||||
private void makeAndBindGate(Marker m1, Marker m2, Paint colour) {
|
private Gate makeAndBindGate(Marker m1, Marker m2, Paint colour) {
|
||||||
Gate gate = new Gate(colour);
|
Gate gate = new Gate(colour);
|
||||||
gate.startXProperty().bind(
|
gate.startXProperty().bind(
|
||||||
m1.centerXProperty()
|
m1.centerXProperty()
|
||||||
@@ -256,7 +268,7 @@ public class GameView extends Pane {
|
|||||||
gate.endYProperty().bind(
|
gate.endYProperty().bind(
|
||||||
m2.centerYProperty()
|
m2.centerYProperty()
|
||||||
);
|
);
|
||||||
markers.getChildren().addAll(gate);
|
return gate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -297,20 +309,22 @@ public class GameView extends Pane {
|
|||||||
*/
|
*/
|
||||||
public void setBoats(List<Yacht> yachts) {
|
public void setBoats(List<Yacht> yachts) {
|
||||||
BoatObject newBoat;
|
BoatObject newBoat;
|
||||||
|
final List<Group> wakes = new ArrayList<>();
|
||||||
for (Yacht yacht : yachts) {
|
for (Yacht yacht : yachts) {
|
||||||
Paint colour = Colors.getColor();
|
Paint colour = Colors.getColor();
|
||||||
newBoat = new BoatObject();
|
newBoat = new BoatObject();
|
||||||
newBoat.setFill(colour);
|
newBoat.setFill(colour);
|
||||||
boatObjects.put(yacht, newBoat);
|
boatObjects.put(yacht, newBoat);
|
||||||
createAndBindAnnotationBox(yacht, colour);
|
createAndBindAnnotationBox(yacht, colour);
|
||||||
wakesGroup.getChildren().add(newBoat.getWake());
|
// wakesGroup.getChildren().add(newBoat.getWake());
|
||||||
|
wakes.add(newBoat.getWake());
|
||||||
boatObjectGroup.getChildren().add(newBoat);
|
boatObjectGroup.getChildren().add(newBoat);
|
||||||
trails.getChildren().add(newBoat.getTrail());
|
trails.getChildren().add(newBoat.getTrail());
|
||||||
// TODO: 1/08/17 Make this less vile to look at.
|
// TODO: 1/08/17 Make this less vile to look at.
|
||||||
yacht.addLocationListener((boat, lat, lon, heading, velocity) ->{
|
yacht.addLocationListener((boat, lat, lon, heading, velocity) ->{
|
||||||
BoatObject bo = boatObjects.get(boat);
|
BoatObject bo = boatObjects.get(boat);
|
||||||
Point2D p2d = findScaledXY(lat, lon);
|
Point2D p2d = findScaledXY(lat, lon);
|
||||||
bo.moveTo(p2d.getX(), p2d.getY(), heading);
|
bo.moveTo(p2d.getX(), p2d.getY(), heading, velocity);
|
||||||
// annotations.get(boat).setLayoutX(p2d.getX());
|
// annotations.get(boat).setLayoutX(p2d.getX());
|
||||||
// annotations.get(boat).setLayoutY(p2d.getY());
|
// annotations.get(boat).setLayoutY(p2d.getY());
|
||||||
// annotations.get(boat).setLocation(100d, 100d);
|
// annotations.get(boat).setLocation(100d, 100d);
|
||||||
@@ -323,24 +337,14 @@ public class GameView extends Pane {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
annotationsGroup.getChildren().addAll(annotations.values());
|
annotationsGroup.getChildren().addAll(annotations.values());
|
||||||
gameObjects.addAll(trails);
|
Platform.runLater(() -> {
|
||||||
gameObjects.add(wakesGroup);
|
gameObjects.addAll(trails);
|
||||||
gameObjects.addAll(annotationsGroup);
|
gameObjects.addAll(wakes);
|
||||||
gameObjects.addAll(boatObjectGroup);
|
gameObjects.addAll(annotationsGroup);
|
||||||
|
gameObjects.addAll(boatObjectGroup);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void updateBoatObject (Yacht correspondingYacht) {
|
|
||||||
// BoatObject bo = boatObjects.get(correspondingYacht);
|
|
||||||
// Point2D p2d = findScaledXY(lat, lon);
|
|
||||||
// bo.moveTo(p2d.getX(), p2d.getY(), heading);
|
|
||||||
// annotations.get(boat).moveTo(p2d.getX(), p2d.getY());
|
|
||||||
// bo.setTrajectory(
|
|
||||||
// heading,
|
|
||||||
// velocity,
|
|
||||||
// metersPerPixelX,
|
|
||||||
// metersPerPixelY);
|
|
||||||
// }
|
|
||||||
|
|
||||||
private void createAndBindAnnotationBox (Yacht yacht, Paint colour) {
|
private void createAndBindAnnotationBox (Yacht yacht, Paint colour) {
|
||||||
AnnotationBox newAnnotation = new AnnotationBox();
|
AnnotationBox newAnnotation = new AnnotationBox();
|
||||||
newAnnotation.setFill(colour);
|
newAnnotation.setFill(colour);
|
||||||
@@ -371,8 +375,8 @@ public class GameView extends Pane {
|
|||||||
annotations.put(yacht, newAnnotation);
|
annotations.put(yacht, newAnnotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawFps(int fps){
|
private void drawFps(Double fps){
|
||||||
fpsDisplay.setText(String.format("%d FPS", fps));
|
Platform.runLater(() -> fpsDisplay.setText(String.format("%d FPS", Math.round(fps))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -383,9 +387,6 @@ public class GameView extends Pane {
|
|||||||
private void findMinMaxPoint(List<GeoPoint> points) {
|
private void findMinMaxPoint(List<GeoPoint> points) {
|
||||||
List<GeoPoint> sortedPoints = new ArrayList<>(points);
|
List<GeoPoint> sortedPoints = new ArrayList<>(points);
|
||||||
sortedPoints.sort(Comparator.comparingDouble(GeoPoint::getLat));
|
sortedPoints.sort(Comparator.comparingDouble(GeoPoint::getLat));
|
||||||
for (GeoPoint gp : sortedPoints) {
|
|
||||||
System.out.println(gp.getLat());
|
|
||||||
}
|
|
||||||
minLatPoint = new GeoPoint(sortedPoints.get(0).getLat(), sortedPoints.get(0).getLng());
|
minLatPoint = new GeoPoint(sortedPoints.get(0).getLat(), sortedPoints.get(0).getLng());
|
||||||
GeoPoint maxLat = sortedPoints.get(sortedPoints.size()-1);
|
GeoPoint maxLat = sortedPoints.get(sortedPoints.size()-1);
|
||||||
maxLatPoint = new GeoPoint(maxLat.getLat(), maxLat.getLng());
|
maxLatPoint = new GeoPoint(maxLat.getLat(), maxLat.getLng());
|
||||||
@@ -572,5 +573,11 @@ public class GameView extends Pane {
|
|||||||
playerYacht.getVelocityProperty(),
|
playerYacht.getVelocityProperty(),
|
||||||
(velocity) -> String.format("Speed: %.2f ms", velocity.doubleValue())
|
(velocity) -> String.format("Speed: %.2f ms", velocity.doubleValue())
|
||||||
);
|
);
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
boatObjectGroup.getChildren().remove(boatObjects.get(playerYacht));
|
||||||
|
gameObjects.add(boatObjects.get(playerYacht));
|
||||||
|
annotationsGroup.getChildren().remove(annotations.get(playerYacht));
|
||||||
|
gameObjects.add(annotations.get(playerYacht));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package seng302.visualiser.controllers;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
@@ -187,13 +188,12 @@ public class LobbyController {
|
|||||||
lobbyListeners.add(listener);
|
lobbyListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 1/08/17 could definitely do this in a cleaner way.
|
|
||||||
public void setPlayerListSource (ObservableList<String> players) {
|
public void setPlayerListSource (ObservableList<String> players) {
|
||||||
this.players = players;
|
this.players = players;
|
||||||
players.addListener((ListChangeListener<? super String>) (lcl) ->
|
players.addListener((ListChangeListener<? super String>) (lcl) ->
|
||||||
initialiseListView()
|
Platform.runLater(this::initialiseListView)
|
||||||
);
|
);
|
||||||
initialiseListView();
|
Platform.runLater(this::initialiseListView);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disableReadyButton () {
|
public void disableReadyButton () {
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ package seng302.visualiser.controllers;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javafx.animation.KeyFrame;
|
|
||||||
import javafx.animation.Timeline;
|
import javafx.animation.Timeline;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.geometry.Point2D;
|
import javafx.geometry.Point2D;
|
||||||
@@ -33,7 +33,6 @@ import javafx.scene.shape.Line;
|
|||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import javafx.stage.StageStyle;
|
import javafx.stage.StageStyle;
|
||||||
import javafx.util.Duration;
|
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
import seng302.model.RaceState;
|
import seng302.model.RaceState;
|
||||||
import seng302.model.Yacht;
|
import seng302.model.Yacht;
|
||||||
@@ -81,7 +80,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
private RaceState raceState;
|
private RaceState raceState;
|
||||||
|
|
||||||
private Timeline timerTimeline;
|
private Timeline timerTimeline;
|
||||||
private HashMap<Integer, Series<String, Double>> sparkLineData = new HashMap<>();
|
private Timer timer = new Timer();
|
||||||
|
private List<Series<String, Double>> sparkLineData = new ArrayList<>();
|
||||||
private ImportantAnnotationsState importantAnnotations;
|
private ImportantAnnotationsState importantAnnotations;
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
@@ -112,9 +112,10 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
initialiseFPSCheckBox();
|
initialiseFPSCheckBox();
|
||||||
initialiseAnnotationSlider();
|
initialiseAnnotationSlider();
|
||||||
initialiseBoatSelectionComboBox();
|
initialiseBoatSelectionComboBox();
|
||||||
|
initialiseSparkLine();
|
||||||
|
|
||||||
gameView = new GameView();
|
gameView = new GameView();
|
||||||
contentAnchorPane.getChildren().add(gameView);
|
Platform.runLater(() -> contentAnchorPane.getChildren().add(gameView));
|
||||||
gameView.setBoats(new ArrayList<>(participants.values()));
|
gameView.setBoats(new ArrayList<>(participants.values()));
|
||||||
gameView.updateBorder(raceData.getCourseLimit());
|
gameView.updateBorder(raceData.getCourseLimit());
|
||||||
gameView.updateCourse(
|
gameView.updateCourse(
|
||||||
@@ -210,32 +211,28 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
* Used to add any new yachts into the race that may have started late or not have had data received yet
|
* Used to add any new yachts into the race that may have started late or not have had data received yet
|
||||||
*/
|
*/
|
||||||
private void updateSparkLine(){
|
private void updateSparkLine(){
|
||||||
|
// TODO: 2/08/17 there is about 0 chance of this working. Once we are keeping track of boat positions it can be fixed.
|
||||||
// Collect the racing yachts that aren't already in the chart
|
// Collect the racing yachts that aren't already in the chart
|
||||||
List<Yacht> sparkLineCandidates = new ArrayList<>();
|
sparkLineData.clear();
|
||||||
// participants.forEach((id, yacht) ->{
|
List<Yacht> sparkLineCandidates = new ArrayList<>(participants.values());
|
||||||
// if (!sparkLineData.containsKey(id) && yacht.getPosition() != null && !yacht.getPosition().equals("-"))
|
|
||||||
// sparkLineCandidates.add(yacht);
|
|
||||||
// });
|
|
||||||
participants.forEach((id, yacht) -> sparkLineCandidates.add(yacht));
|
|
||||||
|
|
||||||
sparklineYAxis.setUpperBound(participants.size() + 1);
|
|
||||||
|
|
||||||
// Create a new data series for new yachts
|
// Create a new data series for new yachts
|
||||||
sparkLineCandidates.stream().filter(yacht -> yacht.getPositionInteger() != null).forEach(yacht -> {
|
sparkLineCandidates
|
||||||
Series<String, Double> yachtData = new Series<>();
|
.stream()
|
||||||
yachtData.setName(yacht.getSourceId().toString());
|
.filter(yacht -> yacht.getPositionInteger() != null)
|
||||||
yachtData.getData().add(
|
.forEach(yacht -> {
|
||||||
new XYChart.Data<>(
|
Series<String, Double> yachtData = new Series<>();
|
||||||
Integer.toString(yacht.getLegNumber()),
|
yachtData.setName(yacht.getSourceId().toString());
|
||||||
1.0 + participants.size() - yacht.getPositionInteger()
|
yachtData.getData().add(
|
||||||
)
|
new XYChart.Data<>(
|
||||||
);
|
Integer.toString(yacht.getLegNumber()),
|
||||||
sparkLineData.put(yacht.getSourceId(), yachtData);
|
1.0 + participants.size() - yacht.getPositionInteger()
|
||||||
});
|
)
|
||||||
|
);
|
||||||
|
sparkLineData.add(yachtData);
|
||||||
|
});
|
||||||
|
|
||||||
// Lambda function to sort the series in order of leg (later legs shown more to the right)
|
// Lambda function to sort the series in order of leg (later legs shown more to the right)
|
||||||
List<XYChart.Series<String, Double>> positions = new ArrayList<>(sparkLineData.values());
|
sparkLineData.sort((o1, o2) -> {
|
||||||
positions.sort((o1, o2) -> {
|
|
||||||
Integer leg1 = Integer.parseInt(o1.getData().get(o1.getData().size()-1).getXValue());
|
Integer leg1 = Integer.parseInt(o1.getData().get(o1.getData().size()-1).getXValue());
|
||||||
Integer leg2 = Integer.parseInt(o2.getData().get(o2.getData().size()-1).getXValue());
|
Integer leg2 = Integer.parseInt(o2.getData().get(o2.getData().size()-1).getXValue());
|
||||||
if (leg2 < leg1){
|
if (leg2 < leg1){
|
||||||
@@ -244,26 +241,30 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Adds the new data series to the sparkline (and set the colour of the series)
|
// Adds the new data series to the sparkline (and set the colour of the series)
|
||||||
raceSparkLine.setCreateSymbols(false);
|
Platform.runLater(() -> {
|
||||||
positions
|
sparkLineData
|
||||||
.stream()
|
.stream()
|
||||||
.filter(spark -> !raceSparkLine.getData().contains(spark))
|
.filter(spark -> !raceSparkLine.getData().contains(spark))
|
||||||
.forEach(spark -> {
|
.forEach(spark -> {
|
||||||
raceSparkLine.getData().add(spark);
|
raceSparkLine.getData().add(spark);
|
||||||
spark.getNode().lookup(".chart-series-line").setStyle("-fx-stroke:" + getBoatColorAsRGB(spark.getName()));
|
spark.getNode().lookup(".chart-series-line").setStyle("-fx-stroke:" + getBoatColorAsRGB(spark.getName()));
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initialiseSparkLine() {
|
||||||
|
sparklineYAxis.setUpperBound(participants.size() + 1);
|
||||||
|
raceSparkLine.setCreateSymbols(false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the yachts sparkline of the desired yacht and using the new leg number
|
* Updates the yachts sparkline of the desired yacht and using the new leg number
|
||||||
* @param yacht The yacht to be updated on the sparkline
|
* @param yacht The yacht to be updated on the sparkline
|
||||||
* @param legNumber the leg number that the position will be assigned to
|
* @param legNumber the leg number that the position will be assigned to
|
||||||
*/
|
*/
|
||||||
public void updateYachtPositionSparkline(Yacht yacht, Integer legNumber){
|
void updateYachtPositionSparkline(Yacht yacht, Integer legNumber){
|
||||||
for (XYChart.Series<String, Double> positionData : sparkLineData.values()) {
|
for (XYChart.Series<String, Double> positionData : sparkLineData) {
|
||||||
positionData.getData().add(
|
positionData.getData().add(
|
||||||
new Data<>(
|
new Data<>(
|
||||||
Integer.toString(legNumber),
|
Integer.toString(legNumber),
|
||||||
@@ -305,24 +306,17 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
* Updates of each of these attributes are called ONCE EACH SECOND
|
* Updates of each of these attributes are called ONCE EACH SECOND
|
||||||
*/
|
*/
|
||||||
private void initializeUpdateTimer() {
|
private void initializeUpdateTimer() {
|
||||||
timerTimeline = new Timeline();
|
timer.scheduleAtFixedRate(new TimerTask() {
|
||||||
timerTimeline.setCycleCount(Timeline.INDEFINITE);
|
@Override
|
||||||
// Run timer update every second
|
public void run() {
|
||||||
timerTimeline.getKeyFrames().add(
|
updateRaceTime();
|
||||||
new KeyFrame(Duration.seconds(1),
|
updateWindDirection();
|
||||||
event -> {
|
updateOrder();
|
||||||
updateRaceTime();
|
updateSparkLine();
|
||||||
updateWindDirection();
|
}
|
||||||
updateOrder();
|
}, 0, 1000);
|
||||||
updateBoatSelectionComboBox();
|
|
||||||
updateSparkLine();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
// Start the timer
|
|
||||||
timerTimeline.playFromStart();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterates over all corners until ones SeqID matches with the yachts current leg number.
|
* Iterates over all corners until ones SeqID matches with the yachts current leg number.
|
||||||
* Then it gets the compoundMarkID of that corner and uses it to fetch the appropriate mark
|
* Then it gets the compoundMarkID of that corner and uses it to fetch the appropriate mark
|
||||||
@@ -331,6 +325,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
* @return The next Mark or null if none found
|
* @return The next Mark or null if none found
|
||||||
*/
|
*/
|
||||||
private Mark getNextMark(BoatObject bg) {
|
private Mark getNextMark(BoatObject bg) {
|
||||||
|
// TODO: 1/08/17 Move to GameView
|
||||||
//
|
//
|
||||||
// Integer legNumber = bg.getYacht().getLegNumber();
|
// Integer legNumber = bg.getYacht().getLegNumber();
|
||||||
// List<Corner> markSequence = courseData.getMarkSequence();
|
// List<Corner> markSequence = courseData.getMarkSequence();
|
||||||
@@ -346,6 +341,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
// return courseData.getCompoundMarks().get(corner.getCompoundMarkID());
|
// return courseData.getCompoundMarks().get(corner.getCompoundMarkID());
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
// return null;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,13 +372,13 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
* section
|
* section
|
||||||
*/
|
*/
|
||||||
private void updateOrder() {
|
private void updateOrder() {
|
||||||
positionVbox.getChildren().clear();
|
|
||||||
// positionVbox.getChildren().removeAll();
|
// positionVbox.getChildren().removeAll();
|
||||||
// positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
// positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
||||||
|
|
||||||
// list of racing yacht id
|
// list of racing yacht id
|
||||||
List<Yacht> sorted = new ArrayList<>(participants.values());
|
List<Yacht> sorted = new ArrayList<>(participants.values());
|
||||||
sorted.sort(Comparator.comparingInt(Yacht::getPositionInteger));
|
sorted.sort(Comparator.comparingInt(Yacht::getPositionInteger));
|
||||||
|
List<Text> vboxEntries = new ArrayList<>();
|
||||||
|
|
||||||
for (Yacht yacht : sorted) {
|
for (Yacht yacht : sorted) {
|
||||||
// System.out.println("yacht == null " + String.valueOf(yacht == null));
|
// System.out.println("yacht == null " + String.valueOf(yacht == null));
|
||||||
@@ -390,17 +386,20 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
Text textToAdd = new Text(yacht.getPositionInteger() + ". " +
|
Text textToAdd = new Text(yacht.getPositionInteger() + ". " +
|
||||||
yacht.getShortName() + " (Finished)");
|
yacht.getShortName() + " (Finished)");
|
||||||
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
||||||
positionVbox.getChildren().add(textToAdd);
|
vboxEntries.add(textToAdd);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Text textToAdd = new Text(yacht.getPositionInteger() + ". " +
|
Text textToAdd = new Text(yacht.getPositionInteger() + ". " +
|
||||||
yacht.getShortName() + " ");
|
yacht.getShortName() + " ");
|
||||||
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
||||||
textToAdd.setStyle("");
|
textToAdd.setStyle("");
|
||||||
positionVbox.getChildren().add(textToAdd);
|
vboxEntries.add(textToAdd);
|
||||||
}
|
}
|
||||||
// System.out.println("finished a loop :))))))))))))");
|
// System.out.println("finished a loop :))))))))))))");
|
||||||
}
|
}
|
||||||
|
Platform.runLater(() ->
|
||||||
|
positionVbox.getChildren().setAll(vboxEntries)
|
||||||
|
);
|
||||||
// participants.forEach((id, yacht) ->{
|
// participants.forEach((id, yacht) ->{
|
||||||
// Text textToAdd = new Text(yacht.getPosition() + ". " +
|
// Text textToAdd = new Text(yacht.getPosition() + ". " +
|
||||||
// yacht.getShortName() + " ");
|
// yacht.getShortName() + " ");
|
||||||
@@ -411,7 +410,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// private void updateLaylines(BoatObject bg) {
|
private void updateLaylines(BoatObject bg) {
|
||||||
|
// TODO: 1/08/17 move to GameView
|
||||||
//
|
//
|
||||||
// Mark nextMark = getNextMark(bg);
|
// Mark nextMark = getNextMark(bg);
|
||||||
// Boolean isUpwind = null;
|
// Boolean isUpwind = null;
|
||||||
@@ -472,7 +472,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
private Point2D getPointRotation(Point2D ref, Double distance, Double angle){
|
private Point2D getPointRotation(Point2D ref, Double distance, Double angle){
|
||||||
@@ -517,17 +517,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Grabs the yachts currently in the race as from the StreamParser and sets them to be selectable
|
|
||||||
* in the yacht selection combo box
|
|
||||||
*/
|
|
||||||
private void updateBoatSelectionComboBox() {
|
|
||||||
ObservableList<Yacht> observableYachts = FXCollections.observableArrayList();
|
|
||||||
observableYachts.addAll(participants.values());
|
|
||||||
yachtSelectionComboBox.setItems(observableYachts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the list of yachts in the order they finished the race
|
* Display the list of yachts in the order they finished the race
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package seng302.visualiser.fxObjects;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.scene.CacheHint;
|
import javafx.scene.CacheHint;
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
@@ -13,7 +14,7 @@ import javafx.scene.text.Text;
|
|||||||
/**
|
/**
|
||||||
* Grouping of string objects over a semi transparent background.
|
* Grouping of string objects over a semi transparent background.
|
||||||
*/
|
*/
|
||||||
public class AnnotationBox extends Group{
|
public class AnnotationBox extends Group {
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface AnnotationFormatter<T> {
|
public interface AnnotationFormatter<T> {
|
||||||
@@ -41,7 +42,7 @@ public class AnnotationBox extends Group{
|
|||||||
this.source = source;
|
this.source = source;
|
||||||
this.format = formatter;
|
this.format = formatter;
|
||||||
source.addListener((obs, oldVal, newVal) ->
|
source.addListener((obs, oldVal, newVal) ->
|
||||||
text.setText(format.transformString(newVal))
|
Platform.runLater(() -> text.setText(format.transformString(newVal)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +80,9 @@ public class AnnotationBox extends Group{
|
|||||||
|
|
||||||
private Map<String, Annotation> annotationsByName = new HashMap<>();
|
private Map<String, Annotation> annotationsByName = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty annotation box. The box is offset from (0,0) by (17, -38).
|
||||||
|
*/
|
||||||
public AnnotationBox() {
|
public AnnotationBox() {
|
||||||
this.setCache(true);
|
this.setCache(true);
|
||||||
background.setX(BACKGROUND_X);
|
background.setX(BACKGROUND_X);
|
||||||
@@ -95,34 +99,51 @@ public class AnnotationBox extends Group{
|
|||||||
this.getChildren().add(background);
|
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) {
|
public void addAnnotation (String annotationName, Annotation annotation) {
|
||||||
annotationsByName.put(annotationName, annotation);
|
annotationsByName.put(annotationName, annotation);
|
||||||
this.getChildren().add(annotation.getText());
|
Platform.runLater(() -> {
|
||||||
visibleAnnotations++;
|
this.getChildren().add(annotation.getText());
|
||||||
update();
|
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) {
|
public void addAnnotation (String annotationName, String annotationText) {
|
||||||
Text text = getTextObject();
|
Text text = getTextObject();
|
||||||
annotationsByName.put(annotationName, new Annotation(text, annotationText));
|
addAnnotation(annotationName, new Annotation(text, annotationText));
|
||||||
this.getChildren().add(text);
|
|
||||||
visibleAnnotations++;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
public <E> void addAnnotation (String annotationName, ObservableValue<E> observable) {
|
|
||||||
addAnnotation(annotationName, observable, E::toString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,
|
public <E> void addAnnotation (String annotationName, ObservableValue<E> observable,
|
||||||
AnnotationFormatter<E> formatter) {
|
AnnotationFormatter<E> formatter) {
|
||||||
Text newText = getTextObject();
|
Text newText = getTextObject();
|
||||||
annotationsByName.put(annotationName, new Annotation<>(newText, observable, formatter));
|
addAnnotation(annotationName, new Annotation<>(newText, observable, formatter));
|
||||||
this.getChildren().add(newText);
|
|
||||||
visibleAnnotations++;
|
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
public void setAnnotationVisibility (String annotationName, boolean visibility) {
|
||||||
if (annotationsByName.containsKey(annotationName)) {
|
if (annotationsByName.containsKey(annotationName)) {
|
||||||
Text textField = annotationsByName.get(annotationName).text;
|
Text textField = annotationsByName.get(annotationName).text;
|
||||||
@@ -138,68 +159,54 @@ public class AnnotationBox extends Group{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
public void removeAnnotation (String annotationName) {
|
||||||
this.getChildren().remove(annotationsByName.remove(annotationName).getText());
|
if (annotationName.contains(annotationName)) {
|
||||||
annotationsByName.remove(annotationName);
|
Platform.runLater(() -> {
|
||||||
visibleAnnotations--;
|
this.getChildren().remove(annotationsByName.remove(annotationName).getText());
|
||||||
update();
|
visibleAnnotations--;
|
||||||
|
update();
|
||||||
|
});
|
||||||
|
annotationsByName.remove(annotationName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the annotation.
|
||||||
|
* @param x x location
|
||||||
|
* @param y y location
|
||||||
|
*/
|
||||||
public void setLocation (double x, double y) {
|
public void setLocation (double x, double y) {
|
||||||
// double dx = x - this.getLayoutX();
|
Platform.runLater(()-> this.relocate(x + BACKGROUND_X, y + BACKGROUND_Y));
|
||||||
// double dy = y - this.getLayoutY();
|
|
||||||
// this.relocate(x, y);
|
|
||||||
//// this.relocate(x, y);
|
|
||||||
// for (Node n : this.getChildren()) {
|
|
||||||
// n.relocate(
|
|
||||||
// n.getLayoutX() + dx,
|
|
||||||
// n.getLayoutY() + dy
|
|
||||||
// );
|
|
||||||
//// n.setLayoutX(n.getLayoutX() + dx);
|
|
||||||
//// n.setLayoutY(n.getLayoutY() + dy);
|
|
||||||
// }
|
|
||||||
// update();
|
|
||||||
this.relocate(x + BACKGROUND_X, y + BACKGROUND_Y);
|
|
||||||
// for (int i = 1; i <= visibleAnnotations; i++) {
|
|
||||||
// Text text = (Text) this.getChildren().get(i);
|
|
||||||
// if (text.visibleProperty().get()) {
|
|
||||||
// text.setLayoutX(x + X_OFFSET_TEXT);
|
|
||||||
// text.setLayoutY(y + Y_OFFSET_TEXT_INIT * Y_OFFSET_PER_TEXT * (i + 1));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// moveTexts(x, y);
|
|
||||||
// for (Node n : this.getChildren()) {
|
|
||||||
// n.relocate(x, y);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the width of the annotation box. Default is 145.
|
||||||
|
* @param width new width.
|
||||||
|
*/
|
||||||
public void setWidth (double width) {
|
public void setWidth (double width) {
|
||||||
backgroundWidth = width;
|
backgroundWidth = width;
|
||||||
background.setWidth(backgroundWidth);
|
Platform.runLater(() -> background.setWidth(backgroundWidth));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update () {
|
private void update () {
|
||||||
background.setVisible(visibleAnnotations != 0);
|
background.setVisible(visibleAnnotations != 0);
|
||||||
background.setHeight(Math.abs(BACKGROUND_X) + TEXT_BUFFER + BACKGROUND_H_PER_TEXT * visibleAnnotations);
|
background.setHeight(Math.abs(BACKGROUND_X) + TEXT_BUFFER + BACKGROUND_H_PER_TEXT * visibleAnnotations);
|
||||||
// System.out.println("visibleAnnotations = " + visibleAnnotations);
|
|
||||||
for (int i = 1; i <= visibleAnnotations; i++) {
|
for (int i = 1; i <= visibleAnnotations; i++) {
|
||||||
Text text = (Text) this.getChildren().get(i);
|
Text text = (Text) this.getChildren().get(i);
|
||||||
if (text.visibleProperty().get()) {
|
if (text.visibleProperty().get()) {
|
||||||
// System.out.println("AYY LMAO");
|
text.setX(X_OFFSET_TEXT);
|
||||||
// System.out.println("text.getText() = " + text.getText());
|
text.setY(Y_OFFSET_TEXT_INIT + Y_OFFSET_PER_TEXT * i);
|
||||||
//// System.out
|
// });
|
||||||
//// .println("text.visibleProperty().get() = " + text.visibleProperty().get());
|
|
||||||
// System.out.println(text.getLayoutX());
|
|
||||||
// System.out.println(background.getLayoutX());
|
|
||||||
text.setX(X_OFFSET_TEXT);
|
|
||||||
text.setY(Y_OFFSET_TEXT_INIT + Y_OFFSET_PER_TEXT * i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a text object with caching and a color applied
|
* Returns a text object for an annotation.
|
||||||
*
|
|
||||||
* @return The text object
|
* @return The text object
|
||||||
*/
|
*/
|
||||||
private Text getTextObject() {
|
private Text getTextObject() {
|
||||||
@@ -211,6 +218,10 @@ public class AnnotationBox extends Group{
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the colour of the annotation box's border and text colour.
|
||||||
|
* @param value desired colour.
|
||||||
|
*/
|
||||||
public void setFill (Paint value) {
|
public void setFill (Paint value) {
|
||||||
theme = value;
|
theme = value;
|
||||||
background.setStroke(theme);
|
background.setStroke(theme);
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
package seng302.visualiser.fxObjects;
|
package seng302.visualiser.fxObjects;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.geometry.Point2D;
|
import javafx.geometry.Point2D;
|
||||||
import javafx.scene.CacheHint;
|
import javafx.scene.CacheHint;
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
|
import javafx.scene.Node;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.paint.Paint;
|
import javafx.scene.paint.Paint;
|
||||||
import javafx.scene.shape.Line;
|
import javafx.scene.shape.Line;
|
||||||
import javafx.scene.shape.Polygon;
|
import javafx.scene.shape.Polygon;
|
||||||
|
import javafx.scene.shape.Polyline;
|
||||||
import javafx.scene.transform.Rotate;
|
import javafx.scene.transform.Rotate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,15 +31,16 @@ public class BoatObject extends Group {
|
|||||||
private double yVelocity;
|
private double yVelocity;
|
||||||
private double lastHeading;
|
private double lastHeading;
|
||||||
//Graphical objects
|
//Graphical objects
|
||||||
private Group lineGroup = new Group();
|
private Polyline trail = new Polyline();
|
||||||
private Polygon boatPoly;
|
private Polygon boatPoly;
|
||||||
private Wake wake;
|
private Wake wake;
|
||||||
private Line leftLayLine;
|
private Line leftLayLine;
|
||||||
private Line rightLayline;
|
private Line rightLayline;
|
||||||
private Double distanceTravelled = 0.0;
|
private double distanceTravelled, lastRotation;
|
||||||
private Point2D lastPoint;
|
private Point2D lastPoint;
|
||||||
private Paint colour = Color.BLACK;
|
private Paint colour = Color.BLACK;
|
||||||
private Boolean isSelected = true; //All boats are initialised as selected
|
private Boolean isSelected, destinationSet; //All boats are initialised as selected
|
||||||
|
private boolean isPlayer = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a BoatGroup with the default triangular boat polygon.
|
* Creates a BoatGroup with the default triangular boat polygon.
|
||||||
@@ -55,7 +59,6 @@ public class BoatObject extends Group {
|
|||||||
* polygon.
|
* polygon.
|
||||||
*/
|
*/
|
||||||
public BoatObject(double... points) {
|
public BoatObject(double... points) {
|
||||||
this.colour = colour;
|
|
||||||
initChildren(points);
|
initChildren(points);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +69,6 @@ public class BoatObject extends Group {
|
|||||||
* polygon.
|
* polygon.
|
||||||
*/
|
*/
|
||||||
private void initChildren(double... points) {
|
private void initChildren(double... points) {
|
||||||
// this.colour = color;
|
|
||||||
boatPoly = new Polygon(points);
|
boatPoly = new Polygon(points);
|
||||||
boatPoly.setFill(colour);
|
boatPoly.setFill(colour);
|
||||||
boatPoly.setFill(this.colour);
|
boatPoly.setFill(this.colour);
|
||||||
@@ -88,44 +90,54 @@ public class BoatObject extends Group {
|
|||||||
|
|
||||||
leftLayLine = new Line();
|
leftLayLine = new Line();
|
||||||
rightLayline = new Line();
|
rightLayline = new Line();
|
||||||
|
trail.getStrokeDashArray().setAll(5d, 10d);
|
||||||
|
trail.setCache(true);
|
||||||
wake = new Wake(0, -BOAT_HEIGHT);
|
wake = new Wake(0, -BOAT_HEIGHT);
|
||||||
|
wake.setVisible(true);
|
||||||
super.getChildren().addAll(boatPoly);//, annotationBox);
|
super.getChildren().addAll(boatPoly);//, annotationBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFill (Paint value) {
|
public void setFill (Paint value) {
|
||||||
this.colour = value;
|
this.colour = value;
|
||||||
boatPoly.setFill(colour);
|
boatPoly.setFill(colour);
|
||||||
|
trail.setStroke(colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves the boat and its children annotations from its current coordinates by specified
|
|
||||||
* amounts.
|
|
||||||
*
|
|
||||||
* @param dx The amount to move the X coordinate by
|
|
||||||
* @param dy The amount to move the Y coordinate by
|
|
||||||
*/
|
|
||||||
private void moveGroupBy(double dx, double dy) {
|
|
||||||
boatPoly.setLayoutX(boatPoly.getLayoutX() + dx);
|
|
||||||
boatPoly.setLayoutY(boatPoly.getLayoutY() + dy);
|
|
||||||
wake.setLayoutX(wake.getLayoutX() + dx);
|
|
||||||
wake.setLayoutY(wake.getLayoutY() + dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the boat and its children annotations to coordinates specified
|
* Moves the boat and its children annotations to coordinates specified
|
||||||
*
|
*
|
||||||
* @param x The X coordinate to move the boat to
|
* @param x The X coordinate to move the boat to
|
||||||
* @param y The Y coordinate to move the boat to
|
* @param y The Y coordinate to move the boat to
|
||||||
*/
|
*/
|
||||||
public void moveTo(double x, double y, double rotation) {
|
public void moveTo(double x, double y, double rotation, double velocity) {
|
||||||
rotateTo(rotation);
|
Double dx = Math.abs(boatPoly.getLayoutX() - x);
|
||||||
boatPoly.setLayoutX(x);
|
Double dy = Math.abs(boatPoly.getLayoutY() - y);
|
||||||
boatPoly.setLayoutY(y);
|
Platform.runLater(() -> {
|
||||||
wake.setLayoutX(x);
|
rotateTo(rotation);
|
||||||
wake.setLayoutY(y);
|
boatPoly.setLayoutX(x);
|
||||||
wake.rotate(rotation);
|
boatPoly.setLayoutY(y);
|
||||||
|
wake.setLayoutX(x);
|
||||||
|
wake.setLayoutY(y);
|
||||||
|
});
|
||||||
|
wake.setRotation(rotation, velocity);
|
||||||
|
// rotateTo(rotation);
|
||||||
|
// boatPoly.setLayoutX(x);
|
||||||
|
// boatPoly.setLayoutY(y);
|
||||||
|
// wake.setLayoutX(x);
|
||||||
|
// wake.setLayoutY(y);
|
||||||
|
// wake.rotate(rotation);
|
||||||
|
|
||||||
|
// wake.setRotation(rotation, groundSpeed);
|
||||||
|
// isStopped = false;
|
||||||
|
// destinationSet = true;
|
||||||
|
lastRotation = rotation;
|
||||||
|
|
||||||
|
distanceTravelled += Math.sqrt((dx * dx) + (dy * dy));
|
||||||
|
|
||||||
|
if (distanceTravelled > 15 && isPlayer) {
|
||||||
|
distanceTravelled = 0d;
|
||||||
|
Platform.runLater(() -> trail.getPoints().addAll(x, y));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rotateTo(double rotation) {
|
private void rotateTo(double rotation) {
|
||||||
@@ -133,31 +145,31 @@ public class BoatObject extends Group {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateLocation() {
|
public void updateLocation() {
|
||||||
double dx = xVelocity / 60;
|
// double dx = xVelocity / 60;
|
||||||
double dy = yVelocity / 60;
|
// double dy = yVelocity / 60;
|
||||||
|
//
|
||||||
distanceTravelled += Math.abs(dx) + Math.abs(dy);
|
// distanceTravelled += Math.abs(dx) + Math.abs(dy);
|
||||||
moveGroupBy(dx, dy);
|
// moveGroupBy(dx, dy);
|
||||||
|
//
|
||||||
if (distanceTravelled > 70) {
|
// if (distanceTravelled > 70) {
|
||||||
distanceTravelled = 0d;
|
// distanceTravelled = 0d;
|
||||||
|
//
|
||||||
if (lastPoint != null) {
|
// if (lastPoint != null) {
|
||||||
Line l = new Line(
|
// Line l = new Line(
|
||||||
lastPoint.getX(),
|
// lastPoint.getX(),
|
||||||
lastPoint.getY(),
|
// lastPoint.getY(),
|
||||||
boatPoly.getLayoutX(),
|
// boatPoly.getLayoutX(),
|
||||||
boatPoly.getLayoutY()
|
// boatPoly.getLayoutY()
|
||||||
);
|
// );
|
||||||
l.getStrokeDashArray().setAll(3d, 7d);
|
// l.getStrokeDashArray().setAll(3d, 7d);
|
||||||
l.setStroke(colour);
|
// l.setStroke(colour);
|
||||||
l.setCache(true);
|
// l.setCache(true);
|
||||||
l.setCacheHint(CacheHint.SPEED);
|
// l.setCacheHint(CacheHint.SPEED);
|
||||||
lineGroup.getChildren().add(l);
|
// lineGroup.getChildren().add(l);
|
||||||
}
|
// }
|
||||||
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
|
// lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
|
||||||
}
|
// }
|
||||||
wake.updatePosition();
|
// wake.updatePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
@@ -203,16 +215,16 @@ public class BoatObject extends Group {
|
|||||||
public void setVisibility (boolean teamName, boolean velocity, boolean estTime, boolean legTime,
|
public void setVisibility (boolean teamName, boolean velocity, boolean estTime, boolean legTime,
|
||||||
boolean trail, boolean wake) {
|
boolean trail, boolean wake) {
|
||||||
// boatAnnotations.setVisible(teamName, velocity, estTime, legTime);
|
// boatAnnotations.setVisible(teamName, velocity, estTime, legTime);
|
||||||
this.wake.setVisible(wake);
|
// this.wake.setVisible(wake);
|
||||||
this.lineGroup.setVisible(trail);
|
this.trail.setVisible(trail);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLineGroupVisible(Boolean visible) {
|
public void setLineGroupVisible(Boolean visible) {
|
||||||
lineGroup.setVisible(visible);
|
trail.setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWakeVisible(Boolean visible) {
|
public void setWakeVisible(Boolean visible) {
|
||||||
wake.setVisible(visible);
|
// wake.setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLayLinesVisible(Boolean visible) {
|
public void setLayLinesVisible(Boolean visible) {
|
||||||
@@ -236,8 +248,8 @@ public class BoatObject extends Group {
|
|||||||
return wake;
|
return wake;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Group getTrail() {
|
public Node getTrail() {
|
||||||
return lineGroup;
|
return trail;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getBoatLayoutX() {
|
public Double getBoatLayoutX() {
|
||||||
@@ -260,6 +272,7 @@ public class BoatObject extends Group {
|
|||||||
);
|
);
|
||||||
boatPoly.setStroke(Color.BLACK);
|
boatPoly.setStroke(Color.BLACK);
|
||||||
boatPoly.setStrokeWidth(3);
|
boatPoly.setStrokeWidth(3);
|
||||||
|
isPlayer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTrajectory(double heading, double velocity) {
|
public void setTrajectory(double heading, double velocity) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package seng302.visualiser.fxObjects;
|
package seng302.visualiser.fxObjects;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.scene.CacheHint;
|
import javafx.scene.CacheHint;
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
@@ -41,7 +42,11 @@ public class Wake extends Group {
|
|||||||
arc.setCache(true);
|
arc.setCache(true);
|
||||||
arc.setCacheHint(CacheHint.ROTATE);
|
arc.setCacheHint(CacheHint.ROTATE);
|
||||||
arc.setType(ArcType.OPEN);
|
arc.setType(ArcType.OPEN);
|
||||||
arc.setStroke(new Color(0.18, 0.7, 1.0, 1.0 + (-0.99 / numWakes * i)));
|
arc.setStroke(
|
||||||
|
new Color(
|
||||||
|
0.18, 0.7, 1.0, 1.0 + (-0.99 / numWakes * i)
|
||||||
|
)
|
||||||
|
);
|
||||||
arc.setStrokeWidth(3.0);
|
arc.setStrokeWidth(3.0);
|
||||||
arc.setStrokeLineCap(StrokeLineCap.ROUND);
|
arc.setStrokeLineCap(StrokeLineCap.ROUND);
|
||||||
arc.setFill(new Color(0.0, 0.0, 0.0, 0.0));
|
arc.setFill(new Color(0.0, 0.0, 0.0, 0.0));
|
||||||
@@ -55,7 +60,15 @@ public class Wake extends Group {
|
|||||||
|
|
||||||
void setRotation (double rotation, double velocity) {
|
void setRotation (double rotation, double velocity) {
|
||||||
// if (Math.abs(rotations[0] - rotation) > 20) {
|
// if (Math.abs(rotations[0] - rotation) > 20) {
|
||||||
rotate(rotation);
|
Platform.runLater(() -> {
|
||||||
|
rotate(rotation);
|
||||||
|
double rad = (14 / numWakes) + velocity;
|
||||||
|
for (Arc arc : arcs) {
|
||||||
|
arc.setRadiusX(rad);
|
||||||
|
arc.setRadiusY(rad);
|
||||||
|
rad += (14 / numWakes) + (velocity / 2.5);
|
||||||
|
}
|
||||||
|
});
|
||||||
// } else {
|
// } else {
|
||||||
// rotations[0] = rotation;
|
// rotations[0] = rotation;
|
||||||
// ((Rotate) arcs[0].getTransforms().get(0)).setAngle(rotation);
|
// ((Rotate) arcs[0].getTransforms().get(0)).setAngle(rotation);
|
||||||
@@ -78,12 +91,12 @@ public class Wake extends Group {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
double rad = (14 / numWakes) + velocity;
|
// double rad = (14 / numWakes) + velocity;
|
||||||
for (Arc arc : arcs) {
|
// for (Arc arc : arcs) {
|
||||||
arc.setRadiusX(rad);
|
// arc.setRadiusX(rad);
|
||||||
arc.setRadiusY(rad);
|
// arc.setRadiusY(rad);
|
||||||
rad += (14 / numWakes) + (velocity / 2.5);
|
// rad += (14 / numWakes) + (velocity / 2.5);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
package seng302.server;
|
package seng302.gameServer.server;
|
||||||
|
|
||||||
import static junit.framework.TestCase.assertEquals;
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import seng302.server.messages.BoatLocationMessage;
|
import seng302.gameServer.server.messages.BoatLocationMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test conversions used by the boat location messages
|
* Test conversions used by the boat location messages
|
||||||
+3
-3
@@ -1,10 +1,10 @@
|
|||||||
package seng302.server;
|
package seng302.gameServer.server;
|
||||||
|
|
||||||
import static junit.framework.TestCase.assertTrue;
|
import static junit.framework.TestCase.assertTrue;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import seng302.server.messages.Header;
|
import seng302.gameServer.server.messages.Header;
|
||||||
import seng302.server.messages.MessageType;
|
import seng302.gameServer.server.messages.MessageType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests message header
|
* Tests message header
|
||||||
+4
-4
@@ -1,12 +1,12 @@
|
|||||||
package seng302.server;
|
package seng302.gameServer.server;
|
||||||
|
|
||||||
import static junit.framework.TestCase.assertEquals;
|
import static junit.framework.TestCase.assertEquals;
|
||||||
import static junit.framework.TestCase.assertTrue;
|
import static junit.framework.TestCase.assertTrue;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import seng302.server.messages.Message;
|
import seng302.gameServer.server.messages.Message;
|
||||||
import seng302.server.messages.XMLMessage;
|
import seng302.gameServer.server.messages.XMLMessage;
|
||||||
import seng302.server.messages.XMLMessageSubType;
|
import seng302.gameServer.server.messages.XMLMessageSubType;
|
||||||
|
|
||||||
public class TestMessage {
|
public class TestMessage {
|
||||||
private static int XML_MESSAGE_LEN = 14;
|
private static int XML_MESSAGE_LEN = 14;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.server.simulator;
|
package seng302.gameServer.server.simulator;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
Reference in New Issue
Block a user