The following schema fragment specifies the expected content contained within this class.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
boat;
+
+ /**
+ * Gets the value of the boat property.
+ *
+ *
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a set method for the boat property.
+ *
+ *
+ * For example, to add a new item, do as follows:
+ *
+ * getBoat().add(newItem);
+ *
+ *
+ *
+ *
+ * Objects of the following type(s) are allowed in the list
+ * {@link BoatConfig.Boats.Boat }
+ *
+ *
+ */
+ public List getBoat() {
+ if (boat == null) {
+ boat = new ArrayList();
+ }
+ return this.boat;
+ }
+
+
+ /**
+ * Java class for anonymous complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType>
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="GPSposition">
+ * <complexType>
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <attribute name="X" type="{http://www.w3.org/2001/XMLSchema}double" />
+ * <attribute name="Y" use="required" type="{http://www.w3.org/2001/XMLSchema}double" />
+ * <attribute name="Z" use="required" type="{http://www.w3.org/2001/XMLSchema}double" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </element>
+ * </sequence>
+ * <attribute name="Type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="BoatName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="SourceID" use="required" type="{http://www.w3.org/2001/XMLSchema}int" />
+ * <attribute name="HullNum" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="ShortName" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="ShapeID" type="{http://www.w3.org/2001/XMLSchema}int" />
+ * <attribute name="StoweName" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+ @XmlAccessorType(XmlAccessType.FIELD)
+ @XmlType(name = "", propOrder = {
+ "gpSposition"
+ })
+ public static class Boat {
+
+ @XmlElement(name = "GPSposition", required = true)
+ protected BoatConfig.Boats.Boat.GPSposition gpSposition;
+ @XmlAttribute(name = "Type", required = true)
+ protected String type;
+ @XmlAttribute(name = "BoatName", required = true)
+ protected String boatName;
+ @XmlAttribute(name = "SourceID", required = true)
+ protected int sourceID;
+ @XmlAttribute(name = "HullNum")
+ protected String hullNum;
+ @XmlAttribute(name = "ShortName")
+ protected String shortName;
+ @XmlAttribute(name = "ShapeID")
+ protected Integer shapeID;
+ @XmlAttribute(name = "StoweName")
+ protected String stoweName;
+
+ /**
+ * Gets the value of the gpSposition property.
+ *
+ * @return
+ * possible object is
+ * {@link BoatConfig.Boats.Boat.GPSposition }
+ *
+ */
+ public BoatConfig.Boats.Boat.GPSposition getGPSposition() {
+ return gpSposition;
+ }
+
+ /**
+ * Sets the value of the gpSposition property.
+ *
+ * @param value
+ * allowed object is
+ * {@link BoatConfig.Boats.Boat.GPSposition }
+ *
+ */
+ public void setGPSposition(BoatConfig.Boats.Boat.GPSposition value) {
+ this.gpSposition = value;
+ }
+
+ /**
+ * Gets the value of the type property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Sets the value of the type property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setType(String value) {
+ this.type = value;
+ }
+
+ /**
+ * Gets the value of the boatName property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getBoatName() {
+ return boatName;
+ }
+
+ /**
+ * Sets the value of the boatName property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setBoatName(String value) {
+ this.boatName = value;
+ }
+
+ /**
+ * Gets the value of the sourceID property.
+ *
+ */
+ public int getSourceID() {
+ return sourceID;
+ }
+
+ /**
+ * Sets the value of the sourceID property.
+ *
+ */
+ public void setSourceID(int value) {
+ this.sourceID = value;
+ }
+
+ /**
+ * Gets the value of the hullNum property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getHullNum() {
+ return hullNum;
+ }
+
+ /**
+ * Sets the value of the hullNum property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setHullNum(String value) {
+ this.hullNum = value;
+ }
+
+ /**
+ * Gets the value of the shortName property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getShortName() {
+ return shortName;
+ }
+
+ /**
+ * Sets the value of the shortName property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setShortName(String value) {
+ this.shortName = value;
+ }
+
+ /**
+ * Gets the value of the shapeID property.
+ *
+ * @return
+ * possible object is
+ * {@link Integer }
+ *
+ */
+ public Integer getShapeID() {
+ return shapeID;
+ }
+
+ /**
+ * Sets the value of the shapeID property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Integer }
+ *
+ */
+ public void setShapeID(Integer value) {
+ this.shapeID = value;
+ }
+
+ /**
+ * Gets the value of the stoweName property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getStoweName() {
+ return stoweName;
+ }
+
+ /**
+ * Sets the value of the stoweName property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setStoweName(String value) {
+ this.stoweName = value;
+ }
+
+
+ /**
+ * Java class for anonymous complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType>
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <attribute name="X" type="{http://www.w3.org/2001/XMLSchema}double" />
+ * <attribute name="Y" use="required" type="{http://www.w3.org/2001/XMLSchema}double" />
+ * <attribute name="Z" use="required" type="{http://www.w3.org/2001/XMLSchema}double" />
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+ @XmlAccessorType(XmlAccessType.FIELD)
+ @XmlType(name = "")
+ public static class GPSposition {
+
+ @XmlAttribute(name = "X", required = true)
+ protected Double x;
+ @XmlAttribute(name = "Y", required = true)
+ protected double y;
+ @XmlAttribute(name = "Z", required = true)
+ protected double z;
+
+ /**
+ * Gets the value of the x property.
+ *
+ * @return
+ * possible object is
+ * {@link Double }
+ *
+ */
+ public Double getX() {
+ return x;
+ }
+
+ /**
+ * Sets the value of the x property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Double }
+ *
+ */
+ public void setX(Double value) {
+ this.x = value;
+ }
+
+ /**
+ * Gets the value of the y property.
+ *
+ */
+ public double getY() {
+ return y;
+ }
+
+ /**
+ * Sets the value of the y property.
+ *
+ */
+ public void setY(double value) {
+ this.y = value;
+ }
+
+ /**
+ * Gets the value of the z property.
+ *
+ */
+ public double getZ() {
+ return z;
+ }
+
+ /**
+ * Sets the value of the z property.
+ *
+ */
+ public void setZ(double value) {
+ this.z = value;
+ }
+
+ }
+
+ }
+
+ }
+
+}
diff --git a/racevisionGame/src/main/java/shared/xml/boats/BoatDataSourceToXML.java b/racevisionGame/src/main/java/shared/xml/boats/BoatDataSourceToXML.java
new file mode 100644
index 00000000..d24bee56
--- /dev/null
+++ b/racevisionGame/src/main/java/shared/xml/boats/BoatDataSourceToXML.java
@@ -0,0 +1,86 @@
+package shared.xml.boats;
+
+import shared.dataInput.BoatDataSource;
+import shared.dataInput.RaceDataSource;
+import shared.enums.RoundingType;
+import shared.model.Boat;
+import shared.model.CompoundMark;
+import shared.model.Leg;
+import shared.model.Mark;
+import shared.xml.Race.*;
+import shared.xml.XMLUtilities;
+
+import javax.xml.bind.JAXBException;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+
+/**
+ * Has functions to convert a {@link shared.dataInput.BoatDataSource} to an {@link BoatConfig} object.
+ */
+public class BoatDataSourceToXML {
+
+
+ /**
+ * Converts a boat data source to an XMLRace object.
+ * @param boatDataSource The data source to convert.
+ * @return The XMLRace file.
+ */
+ public static BoatConfig toXML(BoatDataSource boatDataSource) {
+ BoatConfig boatConfig = new BoatConfig();
+
+ boatConfig.boats = new BoatConfig.Boats();
+ boatConfig.boats.boat = new ArrayList<>();
+
+
+ for (Boat boat : boatDataSource.getBoats().values()) {
+ BoatConfig.Boats.Boat xmlBoat = new BoatConfig.Boats.Boat();
+
+ xmlBoat.setType("Yacht");
+ xmlBoat.setBoatName(boat.getName());
+ xmlBoat.setSourceID(boat.getSourceID());
+ xmlBoat.setStoweName(boat.getCountry());
+ xmlBoat.setShortName(boat.getCountry());
+
+ BoatConfig.Boats.Boat.GPSposition position = new BoatConfig.Boats.Boat.GPSposition();
+ position.setX(boat.getPosition().getLongitude());
+ position.setY(boat.getPosition().getLatitude());
+ position.setZ(0);
+ xmlBoat.setGPSposition(position);
+
+ boatConfig.boats.boat.add(xmlBoat);
+ }
+
+
+ for (Mark mark : boatDataSource.getMarkerBoats().values()) {
+ BoatConfig.Boats.Boat xmlBoat = new BoatConfig.Boats.Boat();
+
+ xmlBoat.setType("Mark");
+ xmlBoat.setBoatName(mark.getName());
+ xmlBoat.setSourceID(mark.getSourceID());
+
+ BoatConfig.Boats.Boat.GPSposition position = new BoatConfig.Boats.Boat.GPSposition();
+ position.setX(mark.getPosition().getLongitude());
+ position.setY(mark.getPosition().getLatitude());
+ position.setZ(0);
+ xmlBoat.setGPSposition(position);
+
+ boatConfig.boats.boat.add(xmlBoat);
+ }
+
+ return boatConfig;
+ }
+
+
+ /**
+ * Converts a boat data source to an xml string.
+ * @param boatDataSource Data source to convert.
+ * @return String containing xml file.
+ * @throws JAXBException Thrown if it cannot be converted.
+ */
+ public static String toString(BoatDataSource boatDataSource) throws JAXBException {
+ BoatConfig boats = toXML(boatDataSource);
+ return XMLUtilities.classToXML(boats);
+ }
+
+
+}
diff --git a/racevisionGame/src/main/java/shared/xml/boats/ObjectFactory.java b/racevisionGame/src/main/java/shared/xml/boats/ObjectFactory.java
new file mode 100644
index 00000000..0319de9a
--- /dev/null
+++ b/racevisionGame/src/main/java/shared/xml/boats/ObjectFactory.java
@@ -0,0 +1,71 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2017.09.01 at 11:12:43 PM NZST
+//
+
+
+package shared.xml.boats;
+
+import javax.xml.bind.annotation.XmlRegistry;
+
+
+/**
+ * This object contains factory methods for each
+ * Java content interface and Java element interface
+ * generated in the aaa package.
+ * An ObjectFactory allows you to programatically
+ * construct new instances of the Java representation
+ * for XML content. The Java representation of XML
+ * content can consist of schema derived interfaces
+ * and classes representing the binding of schema
+ * type definitions, element declarations and model
+ * groups. Factory methods for each of these are
+ * provided in this class.
+ *
+ */
+@XmlRegistry
+public class ObjectFactory {
+
+
+ /**
+ * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: aaa
+ *
+ */
+ public ObjectFactory() {
+ }
+
+ /**
+ * Create an instance of {@link BoatConfig }
+ *
+ */
+ public BoatConfig createBoatConfig() {
+ return new BoatConfig();
+ }
+
+ /**
+ * Create an instance of {@link BoatConfig.Boats }
+ *
+ */
+ public BoatConfig.Boats createBoatConfigBoats() {
+ return new BoatConfig.Boats();
+ }
+
+ /**
+ * Create an instance of {@link BoatConfig.Boats.Boat }
+ *
+ */
+ public BoatConfig.Boats.Boat createBoatConfigBoatsBoat() {
+ return new BoatConfig.Boats.Boat();
+ }
+
+ /**
+ * Create an instance of {@link BoatConfig.Boats.Boat.GPSposition }
+ *
+ */
+ public BoatConfig.Boats.Boat.GPSposition createBoatConfigBoatsBoatGPSposition() {
+ return new BoatConfig.Boats.Boat.GPSposition();
+ }
+
+}
diff --git a/racevisionGame/src/main/java/shared/xml/regatta/ObjectFactory.java b/racevisionGame/src/main/java/shared/xml/regatta/ObjectFactory.java
new file mode 100644
index 00000000..7fc72202
--- /dev/null
+++ b/racevisionGame/src/main/java/shared/xml/regatta/ObjectFactory.java
@@ -0,0 +1,47 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2017.09.01 at 10:37:23 PM NZST
+//
+
+
+package shared.xml.regatta;
+
+import javax.xml.bind.annotation.XmlRegistry;
+
+
+/**
+ * This object contains factory methods for each
+ * Java content interface and Java element interface
+ * generated in the aaa package.
+ *
An ObjectFactory allows you to programatically
+ * construct new instances of the Java representation
+ * for XML content. The Java representation of XML
+ * content can consist of schema derived interfaces
+ * and classes representing the binding of schema
+ * type definitions, element declarations and model
+ * groups. Factory methods for each of these are
+ * provided in this class.
+ *
+ */
+@XmlRegistry
+public class ObjectFactory {
+
+
+ /**
+ * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: aaa
+ *
+ */
+ public ObjectFactory() {
+ }
+
+ /**
+ * Create an instance of {@link RegattaConfig }
+ *
+ */
+ public RegattaConfig createRegattaConfig() {
+ return new RegattaConfig();
+ }
+
+}
diff --git a/racevisionGame/src/main/java/shared/xml/regatta/RegattaConfig.java b/racevisionGame/src/main/java/shared/xml/regatta/RegattaConfig.java
new file mode 100644
index 00000000..d8cc1613
--- /dev/null
+++ b/racevisionGame/src/main/java/shared/xml/regatta/RegattaConfig.java
@@ -0,0 +1,219 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See http://java.sun.com/xml/jaxb
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2017.09.01 at 10:37:23 PM NZST
+//
+
+
+package shared.xml.regatta;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ *
Java class for anonymous complex type.
+ *
+ *
The following schema fragment specifies the expected content contained within this class.
+ *
+ *
+ * <complexType>
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="RegattaID" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ * <element name="RegattaName" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ * <element name="CourseName" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ * <element name="CentralLatitude" type="{http://www.w3.org/2001/XMLSchema}double"/>
+ * <element name="CentralLongitude" type="{http://www.w3.org/2001/XMLSchema}double"/>
+ * <element name="CentralAltitude" type="{http://www.w3.org/2001/XMLSchema}double"/>
+ * <element name="UtcOffset" type="{http://www.w3.org/2001/XMLSchema}double"/>
+ * <element name="MagneticVariation" type="{http://www.w3.org/2001/XMLSchema}double"/>
+ * </sequence>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+ "regattaID",
+ "regattaName",
+ "courseName",
+ "centralLatitude",
+ "centralLongitude",
+ "centralAltitude",
+ "utcOffset",
+ "magneticVariation"
+})
+@XmlRootElement(name = "RegattaConfig")
+public class RegattaConfig {
+
+ @XmlElement(name = "RegattaID")
+ protected int regattaID;
+ @XmlElement(name = "RegattaName", required = true)
+ protected String regattaName;
+ @XmlElement(name = "CourseName", required = true)
+ protected String courseName;
+ @XmlElement(name = "CentralLatitude")
+ protected double centralLatitude;
+ @XmlElement(name = "CentralLongitude")
+ protected double centralLongitude;
+ @XmlElement(name = "CentralAltitude")
+ protected double centralAltitude;
+ @XmlElement(name = "UtcOffset")
+ protected double utcOffset;
+ @XmlElement(name = "MagneticVariation")
+ protected double magneticVariation;
+
+ /**
+ * Gets the value of the regattaID property.
+ *
+ */
+ public int getRegattaID() {
+ return regattaID;
+ }
+
+ /**
+ * Sets the value of the regattaID property.
+ *
+ */
+ public void setRegattaID(int value) {
+ this.regattaID = value;
+ }
+
+ /**
+ * Gets the value of the regattaName property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getRegattaName() {
+ return regattaName;
+ }
+
+ /**
+ * Sets the value of the regattaName property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setRegattaName(String value) {
+ this.regattaName = value;
+ }
+
+ /**
+ * Gets the value of the courseName property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getCourseName() {
+ return courseName;
+ }
+
+ /**
+ * Sets the value of the courseName property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setCourseName(String value) {
+ this.courseName = value;
+ }
+
+ /**
+ * Gets the value of the centralLatitude property.
+ *
+ */
+ public double getCentralLatitude() {
+ return centralLatitude;
+ }
+
+ /**
+ * Sets the value of the centralLatitude property.
+ *
+ */
+ public void setCentralLatitude(double value) {
+ this.centralLatitude = value;
+ }
+
+ /**
+ * Gets the value of the centralLongitude property.
+ *
+ */
+ public double getCentralLongitude() {
+ return centralLongitude;
+ }
+
+ /**
+ * Sets the value of the centralLongitude property.
+ *
+ */
+ public void setCentralLongitude(double value) {
+ this.centralLongitude = value;
+ }
+
+ /**
+ * Gets the value of the centralAltitude property.
+ *
+ */
+ public double getCentralAltitude() {
+ return centralAltitude;
+ }
+
+ /**
+ * Sets the value of the centralAltitude property.
+ *
+ */
+ public void setCentralAltitude(double value) {
+ this.centralAltitude = value;
+ }
+
+ /**
+ * Gets the value of the utcOffset property.
+ *
+ */
+ public double getUtcOffset() {
+ return utcOffset;
+ }
+
+ /**
+ * Sets the value of the utcOffset property.
+ *
+ */
+ public void setUtcOffset(double value) {
+ this.utcOffset = value;
+ }
+
+ /**
+ * Gets the value of the magneticVariation property.
+ *
+ */
+ public double getMagneticVariation() {
+ return magneticVariation;
+ }
+
+ /**
+ * Sets the value of the magneticVariation property.
+ *
+ */
+ public void setMagneticVariation(double value) {
+ this.magneticVariation = value;
+ }
+
+}
diff --git a/racevisionGame/src/main/java/shared/xml/regatta/RegattaDataSourceToXML.java b/racevisionGame/src/main/java/shared/xml/regatta/RegattaDataSourceToXML.java
new file mode 100644
index 00000000..bbe1dce6
--- /dev/null
+++ b/racevisionGame/src/main/java/shared/xml/regatta/RegattaDataSourceToXML.java
@@ -0,0 +1,54 @@
+package shared.xml.regatta;
+
+import shared.dataInput.RegattaDataSource;
+import shared.xml.Race.XMLRace;
+import shared.xml.XMLUtilities;
+
+import javax.xml.bind.JAXBException;
+
+/**
+ * Has functions to convert a {@link shared.dataInput.RegattaDataSource} to an {@link RegattaConfig} object.
+ */
+public class RegattaDataSourceToXML {
+
+
+ /**
+ * Converts a regatta data source to an XMLRace object.
+ * @param regattaDataSource The data source to convert.
+ * @return The XMLRace file.
+ */
+ public static RegattaConfig toXML(RegattaDataSource regattaDataSource) {
+
+ RegattaConfig regatta = new RegattaConfig();
+
+ regatta.setCentralAltitude(regattaDataSource.getCentralAltitude());
+ regatta.setCentralLatitude(regattaDataSource.getCentralLatitude());
+ regatta.setCentralLongitude(regattaDataSource.getCentralLongitude());
+
+ regatta.setCourseName(regattaDataSource.getCourseName());
+
+ regatta.setRegattaName(regattaDataSource.getRegattaName());
+
+ regatta.setMagneticVariation(regattaDataSource.getMagneticVariation());
+
+ regatta.setRegattaID(regattaDataSource.getRegattaID());
+
+ regatta.setUtcOffset(regattaDataSource.getUtcOffset());
+
+ return regatta;
+ }
+
+
+ /**
+ * Converts a regatta data source to an xml string.
+ * @param regattaDataSource Data source to convert.
+ * @return String containing xml file.
+ * @throws JAXBException Thrown if it cannot be converted.
+ */
+ public static String toString(RegattaDataSource regattaDataSource) throws JAXBException {
+ RegattaConfig regatta = toXML(regattaDataSource);
+ return XMLUtilities.classToXML(regatta);
+ }
+
+
+}
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/FinishController.java b/racevisionGame/src/main/java/visualiser/Controllers/FinishController.java
index c5356495..6de6dcdf 100644
--- a/racevisionGame/src/main/java/visualiser/Controllers/FinishController.java
+++ b/racevisionGame/src/main/java/visualiser/Controllers/FinishController.java
@@ -71,8 +71,10 @@ public class FinishController extends Controller {
//Winner label.
- raceWinnerLabel.setText("Winner: "+ boatNameColumn.getCellObservableValue(0).getValue());
- raceWinnerLabel.setWrapText(true);
+ if (boats.size() > 0) {
+ raceWinnerLabel.setText("Winner: " + boatNameColumn.getCellObservableValue(0).getValue());
+ raceWinnerLabel.setWrapText(true);
+ }
}
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java
index 1609e700..008276ef 100644
--- a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java
+++ b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java
@@ -1,21 +1,29 @@
package visualiser.Controllers;
+import com.interactivemesh.jfx.importer.stl.StlMeshImporter;
+import javafx.animation.AnimationTimer;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
import javafx.fxml.FXML;
-import javafx.scene.control.TextField;
+import javafx.scene.control.Alert;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.SplitPane;
+import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.GridPane;
+import javafx.scene.shape.Box;
+import javafx.scene.shape.Mesh;
+import javafx.scene.shape.MeshView;
+import javafx.scene.shape.Shape3D;
+import javafx.scene.transform.Rotate;
import mock.app.Event;
-import org.xml.sax.SAXException;
import mock.exceptions.EventConstructionException;
-import shared.exceptions.InvalidBoatDataException;
-import shared.exceptions.InvalidRaceDataException;
-import shared.exceptions.InvalidRegattaDataException;
-import shared.exceptions.XMLReaderException;
+import visualiser.model.View3D;
-import javax.xml.bind.JAXBException;
-import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.net.Socket;
import java.net.URL;
+import java.util.Optional;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -26,27 +34,70 @@ import java.util.logging.Logger;
public class HostController extends Controller {
- @FXML
- TextField gameNameField;
+// @FXML
+// TextField gameNameField;
+//
+// @FXML
+// TextField hostNameField;
@FXML
- TextField hostNameField;
+ private ImageView imageView;
@FXML
AnchorPane hostWrapper;
+ @FXML
+ AnchorPane imagePane;
+
+ @FXML
+ SplitPane splitPane;
+
+ @FXML
+ AnchorPane specPane;
+
+ @FXML
+ GridPane playerContainer;
+
private Event game;
+ private View3D view3D;
@Override
public void initialize(URL location, ResourceBundle resources) {
+ ObservableList shapes = FXCollections.observableArrayList();
+
+ view3D = new View3D();
+ view3D.setItems(shapes);
+ playerContainer.add(view3D, 0,0);
+
+ URL asset = HostController.class.getClassLoader().getResource("assets/V1.2 Complete Boat.stl");
+
+ StlMeshImporter importer = new StlMeshImporter();
+ importer.read(asset);
+ MeshView mesh = new MeshView(importer.getImport());
+ shapes.add(mesh);
+
+ view3D.setPivot(mesh);
+ view3D.setDistance(50);
+ view3D.setYaw(45);
+ view3D.setPitch(20);
+
+ Rotate rotation = new Rotate(0, Rotate.Y_AXIS);
+ mesh.getTransforms().addAll(rotation, new Rotate(-90, Rotate.X_AXIS));
+
+ AnimationTimer rotate = new AnimationTimer() {
+ @Override
+ public void handle(long now) {
+ rotation.setAngle(rotation.getAngle() + 0.1);
+ }
+ };
+ rotate.start();
}
/**
* Hosts a game
- * @throws IOException if socket cannot be connected to
*/
- public void hostGamePressed() throws IOException{
+ public void hostGamePressed() {
try {
this.game = new Event(false);
connectSocket("localhost", 4942);
@@ -81,12 +132,34 @@ public class HostController extends Controller {
* Hosts a game.
*/
public void hostGame(){
+ splitPane.setResizableWithParent(specPane, false);
+ splitPane.lookupAll(".split-pane-divider").stream().forEach(div -> div.setMouseTransparent(true));
+ imageView.fitWidthProperty().bind(imagePane.widthProperty());
+ imageView.fitHeightProperty().bind(imagePane.heightProperty());
hostWrapper.setVisible(true);
}
+ /**
+ * Menu button pressed. Prompt alert then return to menu
+ */
public void menuBtnPressed(){
- hostWrapper.setVisible(false);
- parent.enterTitle();
+ Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
+ alert.setTitle("Quitting race");
+ alert.setContentText("Do you wish to quit the race?");
+ alert.setHeaderText("You are about to quit the race");
+ Optional result = alert.showAndWait();
+ if(result.get() == ButtonType.OK){
+ hostWrapper.setVisible(false);
+ parent.enterTitle();
+ }
+ }
+
+ /**
+ * Start button pressed. Currently only prints out start
+ */
+ public void startBtnPressed(){
+ //System.out.println("Should start the race. This button is only visible for the host");
+ hostGamePressed();
}
}
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java b/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java
new file mode 100644
index 00000000..84d82e91
--- /dev/null
+++ b/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java
@@ -0,0 +1,247 @@
+package visualiser.Controllers;
+
+import javafx.application.Platform;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.ListView;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.AnchorPane;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.WindowEvent;
+import visualiser.gameController.Keys.ControlKey;
+import visualiser.gameController.Keys.KeyFactory;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import static visualiser.app.App.keyFactory;
+
+/**
+ * Controller for the scene used to display and update current key bindings.
+ */
+public class KeyBindingsController {
+ private @FXML Button btnSave;
+ private @FXML Button btnCancel;
+ private @FXML Button btnReset;
+ private @FXML ListView lstControl;
+ private @FXML ListView lstKey;
+ private @FXML ListView lstDescription;
+ private @FXML AnchorPane anchor;
+ private KeyFactory newKeyFactory;
+ private Boolean changed = false; // keyBindings have been modified
+ private Button currentButton = null; // last button clicked
+
+ public void initialize(){
+ // create new key factory to modify, keeping the existing one safe
+ newKeyFactory = copyExistingFactory();
+ initializeTable();
+ populateTable();
+ setKeyListener();
+ }
+
+ /**
+ * Sets up table before populating it.
+ * Set up includes headings, CSS styling and modifying default properties.
+ */
+ public void initializeTable(){
+ // set the headings for each column
+ lstKey.getItems().add("Key");
+ lstControl.getItems().add("Command");
+ lstDescription.getItems().add("Description");
+ lstKey.getSelectionModel().select(0);
+ lstControl.getSelectionModel().select(0);
+ lstDescription.getSelectionModel().select(0);
+
+ // add CSS stylesheet once the scene has been created
+ lstKey.sceneProperty().addListener((obs, oldScene, newScene) -> {
+ if (newScene != null) {
+ newScene.getStylesheets().add("/css/keyBindings.css");
+ }
+ });
+
+ // stop the columns from being selectable, so only the buttons are
+ lstKey.getSelectionModel().selectedItemProperty()
+ .addListener((observable, oldvalue, newValue) ->
+ Platform.runLater(() ->
+ lstKey.getSelectionModel().select(0)));
+ lstDescription.getSelectionModel().selectedItemProperty()
+ .addListener((observable, oldvalue, newValue) ->
+ Platform.runLater(() ->
+ lstDescription.getSelectionModel().select(0)));
+ lstControl.getSelectionModel().selectedItemProperty()
+ .addListener((observable, oldvalue, newValue) ->
+ Platform.runLater(() ->
+ lstControl.getSelectionModel().select(0)));
+ }
+
+ /**
+ * Populates the table with commands and their key binding details.
+ */
+ public void populateTable(){
+ // add each command to the table
+ for (Map.Entry entry : newKeyFactory.getKeyState().entrySet()) {
+ // create button for command
+ Button button = new Button(entry.getKey());
+ button.setMinWidth(120);
+ button.setId(entry.getValue().toString());
+ button.setOnAction(e -> currentButton = button);
+ // display details for command in table
+ lstControl.getItems().add(entry.getValue());
+ lstKey.getItems().add(button);
+ lstDescription.getItems().add(entry.getValue().getProtocolCode());
+ }
+ }
+
+ /**
+ * Makes a copy of the {@link KeyFactory} that does not modify the original.
+ * @return new keyfactory to be modified
+ */
+ public KeyFactory copyExistingFactory(){
+ newKeyFactory = new KeyFactory();
+ Map oldKeyState = keyFactory.getKeyState();
+ Map newKeyState = new HashMap<>();
+
+ // copy over commands and their keys
+ for (Map.Entry entry : oldKeyState.entrySet()){
+ newKeyState.put(entry.getKey(), entry.getValue());
+ }
+ newKeyFactory.setKeyState(newKeyState);
+ return newKeyFactory;
+ }
+
+ /**
+ * Creates a listener for the base anchorpane for key presses.
+ * It updates the current key bindings of the {@link KeyFactory} if
+ * required.
+ */
+ public void setKeyListener(){
+ anchor.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
+ // if esc, cancel current button click
+ if (event.getCode() == KeyCode.ESCAPE){
+ btnCancel.requestFocus();
+ currentButton = null;
+ }
+ // if a button was clicked
+ else if (currentButton != null) {
+ // check if a button is already mapped to this key
+ for (int i = 1; i < lstKey.getItems().size(); i++) {
+ Button button = (Button)lstKey.getItems().get(i);
+ // update buttons text and remove key binding from command
+ if (button.getText().equals(event.getCode().toString())) {
+ button.setText("");
+ newKeyFactory.updateKey(button.getId(), button.getId());
+ }
+ }
+ // update text on the button
+ currentButton.setText(event.getCode().toString());
+ // update the control key
+ newKeyFactory.updateKey(event.getCode().toString(),
+ currentButton.getId());
+ // remove current button selection
+ currentButton = null;
+ changed = true;
+ btnCancel.requestFocus();
+ }
+ event.consume();
+ });
+ }
+
+ /**
+ * Cancel and exits the key bindings menu. Changes are not forced to be
+ * saved or fixed if invalid, and instead are defaulted back to the last
+ * successful saved state.
+ */
+ public void cancel(){
+ ((Stage)btnCancel.getScene().getWindow()).close();
+ }
+
+ /**
+ * Resets all key bindings to the built-in defaults.
+ */
+ public void reset(){
+ lstKey.getItems().clear();
+ lstControl.getItems().clear();
+ lstDescription.getItems().clear();
+ newKeyFactory = new KeyFactory();
+ initializeTable();
+ populateTable();
+ changed = true;
+ }
+
+ /**
+ * Replace existing {@link KeyFactory} with the modified key bindings.
+ */
+ public void save(){
+ if (isFactoryValid()) {
+ keyFactory = newKeyFactory;
+ newKeyFactory = new KeyFactory();
+ changed = false;
+ keyFactory.save(); // save persistently
+ loadNotification("Key bindings were successfully saved.", false);
+ } else {
+ loadNotification("One or more key bindings are missing. " +
+ "Failed to save.", true);
+ }
+ }
+
+ /**
+ * Checks the {@link KeyFactory} being modified is valid and that no
+ * commands are missing a key binding.
+ * @return True if valid, false if invalid
+ */
+ public Boolean isFactoryValid(){
+ for (Map.Entry entry : newKeyFactory.getKeyState().entrySet
+ ()) {
+ if (entry.getKey().toString()==entry.getValue().toString()){
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Method used to stop a user from exiting key bindings without saving
+ * their changes to the {@link KeyFactory}.
+ * @param we {@link WindowEvent} close request to be consumed if settings
+ * have not been successfully saved.
+ */
+ public void onExit(WindowEvent we){
+ // if modified KeyFactory hasn't been saved
+ if (changed){
+ loadNotification("Please cancel or save your changes before exiting" +
+ ".", true);
+ we.consume();
+ }
+ }
+
+ /**
+ * Loads a popup window giving confirmation/warning of user activity.
+ * @param message the message to be displayed to the user
+ * @param warning true if the message to be displayed is due to user error
+ */
+ public void loadNotification(String message, Boolean warning){
+ Parent root = null;
+ FXMLLoader loader = new FXMLLoader(getClass().getResource
+ ("/visualiser/scenes/notification.fxml"));
+ try {
+ root = loader.load();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ NotificationController controller = loader.getController();
+ Stage stage = new Stage();
+ stage.setScene(new Scene(root));
+ stage.centerOnScreen();
+ stage.initModality(Modality.APPLICATION_MODAL);
+ stage.show();
+ // displays given message in the window
+ controller.setMessage(message, warning);
+ }
+
+}
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/LobbyController.java b/racevisionGame/src/main/java/visualiser/Controllers/LobbyController.java
index 07af2b49..d541c531 100644
--- a/racevisionGame/src/main/java/visualiser/Controllers/LobbyController.java
+++ b/racevisionGame/src/main/java/visualiser/Controllers/LobbyController.java
@@ -21,7 +21,7 @@ import java.util.ResourceBundle;
public class LobbyController extends Controller {
@FXML
- AnchorPane lobbyWrapper;
+ private AnchorPane lobbyWrapper;
@FXML
private TableView lobbyTable;
@FXML
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/MainController.java b/racevisionGame/src/main/java/visualiser/Controllers/MainController.java
index 9e557d38..e1aa1ede 100644
--- a/racevisionGame/src/main/java/visualiser/Controllers/MainController.java
+++ b/racevisionGame/src/main/java/visualiser/Controllers/MainController.java
@@ -3,7 +3,6 @@ package visualiser.Controllers;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.layout.AnchorPane;
-import visualiser.app.App;
import visualiser.gameController.ControllerClient;
import visualiser.model.VisualiserBoat;
import visualiser.model.VisualiserRaceEvent;
@@ -40,7 +39,7 @@ public class MainController extends Controller {
* Transitions from the StartController screen (displays pre-race information) to the RaceController (displays the actual race).
* @param visualiserRace The object modelling the race.
* @param controllerClient Socket Client that manipulates the controller.
- * @param isHost whether this window is the host of the race or not.
+ * @param isHost if the client is the host of a race or not.
*/
public void beginRace(VisualiserRaceEvent visualiserRace, ControllerClient controllerClient, Boolean isHost) {
raceController.startRace(visualiserRace, controllerClient, isHost);
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/NotificationController.java b/racevisionGame/src/main/java/visualiser/Controllers/NotificationController.java
new file mode 100644
index 00000000..d122ec80
--- /dev/null
+++ b/racevisionGame/src/main/java/visualiser/Controllers/NotificationController.java
@@ -0,0 +1,35 @@
+package visualiser.Controllers;
+
+import javafx.fxml.FXML;
+import javafx.scene.control.Label;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Text;
+import javafx.stage.Stage;
+
+/**
+ * Controller for a popup notification regarding user activity.
+ */
+public class NotificationController {
+ private @FXML Label lblDescription;
+ private @FXML Text txtMessage;
+
+ /**
+ * Closes the popup window once clicked.
+ */
+ public void ok(){
+ ((Stage)lblDescription.getScene().getWindow()).close();
+ }
+
+ /**
+ * Displays the appropriate popup notification.
+ * @param message message for the user
+ * @param warning if true warning text shown, if false success text shown
+ */
+ public void setMessage(String message, Boolean warning){
+ lblDescription.setText(message);
+ if (!warning){
+ txtMessage.setText("Success!");
+ txtMessage.setFill(Color.GREEN);
+ }
+ }
+}
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java
index 4fcda581..043726f7 100644
--- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java
+++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java
@@ -10,7 +10,6 @@ import javafx.collections.transformation.SortedList;
import javafx.fxml.FXML;
import javafx.scene.chart.LineChart;
import javafx.scene.control.*;
-import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
@@ -23,7 +22,6 @@ import shared.model.Leg;
import visualiser.app.App;
import visualiser.gameController.ControllerClient;
import visualiser.gameController.Keys.ControlKey;
-import visualiser.gameController.Keys.KeyFactory;
import visualiser.model.*;
import java.io.IOException;
@@ -33,6 +31,7 @@ import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
+import static visualiser.app.App.keyFactory;
/**
@@ -113,7 +112,7 @@ public class RaceController extends Controller {
@Override
public void initialize(URL location, ResourceBundle resources) {
- KeyFactory keyFactory = KeyFactory.getFactory();
+// KeyFactory keyFactory = KeyFactory.getFactory();
infoTableShow = true;
// Initialise keyboard handler
@@ -356,7 +355,7 @@ public class RaceController extends Controller {
private void initialiseRaceCanvas(VisualiserRaceEvent race) {
//Create canvas.
- raceCanvas = new ResizableRaceCanvas(race);
+ raceCanvas = new ResizableRaceCanvas(race.getVisualiserRaceState());
//Set properties.
raceCanvas.setMouseTransparent(true);
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java b/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java
index 32e033c8..aa2edf13 100644
--- a/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java
+++ b/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java
@@ -1,5 +1,6 @@
package visualiser.Controllers;
+import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
@@ -9,6 +10,7 @@ import javafx.scene.control.RadioButton;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
+import javafx.stage.WindowEvent;
import visualiser.app.App;
import java.io.IOException;
@@ -81,25 +83,32 @@ public class TitleController extends Controller {
@Override
public void initialize(URL location, ResourceBundle resources) {
-
}
/**
* Called when control button is pressed. New pop up window displaying controls
*/
public void controlBtnPressed(){
- FXMLLoader loader = new FXMLLoader();
- loader.setLocation(getClass().getResource("/visualiser/scenes/controls.fxml"));
- Parent layout;
try {
- layout = loader.load();
+ FXMLLoader loader = new FXMLLoader();
+ loader.setLocation(getClass().getResource("/visualiser/scenes/keyBindings.fxml"));
+ Parent layout = loader.load();
Scene scene = new Scene(layout);
Stage popupStage = new Stage();
popupStage.setResizable(false);
popupStage.setTitle("Game Controls");
popupStage.initModality(Modality.WINDOW_MODAL);
+ popupStage.centerOnScreen();
popupStage.setScene(scene);
- popupStage.showAndWait();
+ popupStage.show();
+ KeyBindingsController controller = loader.getController();
+ popupStage.setOnCloseRequest(new EventHandler() {
+ public void handle(WindowEvent we) {
+ if (we.getEventType() == WindowEvent.WINDOW_CLOSE_REQUEST) {
+ controller.onExit(we);
+ }
+ }
+ });
} catch (Exception e){
e.printStackTrace();
}
diff --git a/racevisionGame/src/main/java/visualiser/app/App.java b/racevisionGame/src/main/java/visualiser/app/App.java
index eeae5a5d..e095e04e 100644
--- a/racevisionGame/src/main/java/visualiser/app/App.java
+++ b/racevisionGame/src/main/java/visualiser/app/App.java
@@ -3,7 +3,6 @@ package visualiser.app;
import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.application.Platform;
-import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
@@ -15,7 +14,6 @@ import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
-import javafx.scene.control.ListView;
import javafx.scene.control.ProgressBar;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
@@ -29,19 +27,17 @@ import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;
import javafx.util.Duration;
import visualiser.Controllers.MainController;
-
-import java.io.IOException;
+import visualiser.gameController.Keys.KeyFactory;
public class App extends Application {
-
private static Stage stage;
private Pane splashLayout;
private ProgressBar loadProgress;
private Label progressText;
private static final int SPLASH_WIDTH = 676;
private static final int SPLASH_HEIGHT = 227;
-
+ public static KeyFactory keyFactory = new KeyFactory();
public static App app;
/**
@@ -55,6 +51,9 @@ public class App extends Application {
@Override
public void init() {
+ // load the user's personalised key bindings
+ keyFactory.load();
+
ImageView splash = new ImageView(new Image(
getClass().getClassLoader().getResourceAsStream("images/splashScreen.png")
));
@@ -96,15 +95,15 @@ public class App extends Application {
);
updateMessage("Preparing ingredients . . .");
- Thread.sleep(1000);
+ Thread.sleep(200);
for (int i = 0; i < burgerFilling.size(); i++) {
- Thread.sleep(800);
+ Thread.sleep(100);
updateProgress(i + 1, burgerFilling.size());
String nextFilling = burgerFilling.get(i);
addedFilling.add(nextFilling);
updateMessage("Adding the " + nextFilling + " . . .");
}
- Thread.sleep(400);
+ Thread.sleep(100);
updateMessage("Burger's done!");
return addedFilling;
diff --git a/racevisionGame/src/main/java/visualiser/gameController/InputChecker.java b/racevisionGame/src/main/java/visualiser/gameController/InputChecker.java
index 057b5721..b4b3de9b 100644
--- a/racevisionGame/src/main/java/visualiser/gameController/InputChecker.java
+++ b/racevisionGame/src/main/java/visualiser/gameController/InputChecker.java
@@ -3,10 +3,11 @@ package visualiser.gameController;
import javafx.animation.AnimationTimer;
import javafx.scene.Scene;
import visualiser.gameController.Keys.ControlKey;
-import visualiser.gameController.Keys.KeyFactory;
import java.util.HashMap;
+import static visualiser.app.App.keyFactory;
+
/**
* Class for checking what keys are currently being used
*/
@@ -18,7 +19,7 @@ public class InputChecker {
* @param scene Scene the controller is to run in parallel with.
*/
public void runWithScene(Scene scene){
- KeyFactory keyFactory = KeyFactory.getFactory();
+// KeyFactory keyFactory = KeyFactory.getFactory();
scene.setOnKeyPressed(event -> {
String codeString = event.getCode().toString();
diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/DownWindKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/DownWindKey.java
index e4b5455a..6c974972 100644
--- a/racevisionGame/src/main/java/visualiser/gameController/Keys/DownWindKey.java
+++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/DownWindKey.java
@@ -9,11 +9,9 @@ public class DownWindKey extends ControlKey {
/**
* Constructor for Control
- * @param name name of the key
- *
*/
- public DownWindKey(String name) {
- super(name, BoatActionEnum.DOWNWIND);
+ public DownWindKey() {
+ super("Downwind", BoatActionEnum.DOWNWIND);
}
@Override
diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java
index be95abd3..a783f268 100644
--- a/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java
+++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java
@@ -1,5 +1,8 @@
package visualiser.gameController.Keys;
+import java.beans.XMLDecoder;
+import java.beans.XMLEncoder;
+import java.io.*;
import java.util.HashMap;
import java.util.Map;
@@ -13,39 +16,108 @@ public class KeyFactory {
private Map keyState;
/**
- * Singleton instance to enforce consistent key state
+ * Constructor for key state, set up initial state of each action.
*/
- private static KeyFactory theFactory = new KeyFactory();
+ public KeyFactory() {
+ this.keyState = new HashMap<>();
+ keyState.put("Z", new ZoomInKey());
+ keyState.put("X", new ZoomOutKey());
+ keyState.put("SPACE", new VMGKey());
+ keyState.put("SHIFT", new SailsToggleKey());
+ keyState.put("ENTER", new TackGybeKey());
+ keyState.put("UP", new UpWindKey());
+ keyState.put("DOWN", new DownWindKey());
+ }
/**
- * Singleton constructor for key state, set up initial state of each action.
+ * Get the Control Key in charge of a key press
+ * @param key key pressed (String value of KeyCode)
+ * @return the Control Key behaviour of the key pressed.
*/
- private KeyFactory() {
- this.keyState = new HashMap<>();
- keyState.put("Z", new ZoomInKey("Zoom In"));
- keyState.put("X", new ZoomOutKey("Zoom Out"));
- keyState.put("SPACE", new VMGKey("VMG"));
- keyState.put("SHIFT", new SailsToggleKey("Toggle Sails"));
- keyState.put("ENTER", new TackGybeKey("Tack/Gybe"));
- keyState.put("UP", new UpWindKey("Upwind"));
- keyState.put("DOWN", new DownWindKey("Downwind"));
+ public ControlKey getKey(String key){
+ return keyState.get(key);
+ }
+
+ public Map getKeyState() {
+ return keyState;
+ }
+
+ public void setKeyState(Map keyState) {
+ this.keyState = keyState;
}
/**
- * Get singleton instance of KeyFactory to interact with key state
- * @return automatically constructed KeyFactory
+ * Update the key bound to a particular command in the keystate.
+ * @param newKey the new key value for the command
+ * @param command the command to be updated
*/
- public static KeyFactory getFactory() {
- return theFactory;
+ public void updateKey(String newKey, String command){
+ ControlKey controlKey = null;
+ String oldKey = null;
+ for (Map.Entry entry : keyState.entrySet()) {
+ // if this is the correct command
+ if (entry.getValue().toString()==command){
+ controlKey = entry.getValue();
+ oldKey = entry.getKey();
+ }
+ }
+ keyState.remove(oldKey, controlKey);
+ keyState.put(newKey, controlKey);
}
/**
- * Get the Control Key in charge of a key press
- * @param key key pressed (String value of KeyCode)
- * @return the Control Key behaviour of the key pressed.
+ * Persistently saves the keybindings the user has set.
*/
- public ControlKey getKey(String key){
- return keyState.get(key);
+ public void save(){
+ try {
+ // open the filestream and write to it
+ FileOutputStream fos = new FileOutputStream(
+ System.getProperty("user.dir")+
+ "/settings/keyBindings.xml");
+ XMLEncoder xmlEncoder = new XMLEncoder(fos);
+ xmlEncoder.writeObject(this.keyState);
+ xmlEncoder.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Loads the persistently saved keybindings the user has set.
+ */
+ public void load(){
+ try {
+ // access settings folder, create if it doesn't exist
+ File settingsFolder = new File(
+ System.getProperty("user.dir")+"/settings");
+ if (!settingsFolder.exists()){
+ settingsFolder.mkdir();
+ }
+
+ // access keybindings xml file, create if it doesn't exist
+ File savedFile = new File(
+ settingsFolder+"/keyBindings.xml");
+ if (!savedFile.exists()){
+ savedFile.createNewFile();
+ FileOutputStream fos = new FileOutputStream(savedFile);
+ XMLEncoder xmlEncoder = new XMLEncoder(fos);
+ xmlEncoder.writeObject(this.keyState);
+ xmlEncoder.close();
+ }
+
+ // load the saved settings into the game
+ InputStream is = new FileInputStream(savedFile);
+ XMLDecoder xmlDecoder = new XMLDecoder(is);
+ Map savedKeyState
+ = (Map)xmlDecoder.readObject();
+ xmlDecoder.close();
+ this.keyState = savedKeyState;
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
}
diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/SailsToggleKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/SailsToggleKey.java
index f1e4d65b..a04b7d77 100644
--- a/racevisionGame/src/main/java/visualiser/gameController/Keys/SailsToggleKey.java
+++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/SailsToggleKey.java
@@ -10,11 +10,9 @@ public class SailsToggleKey extends ControlKey {
/**
* Constructor for Control
- * @param name name of the key
- *
*/
- public SailsToggleKey(String name) {
- super(name, BoatActionEnum.NOT_A_STATUS);
+ public SailsToggleKey() {
+ super("Toggle Sails", BoatActionEnum.NOT_A_STATUS);
}
/**
diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/TackGybeKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/TackGybeKey.java
index 80252e73..5c164443 100644
--- a/racevisionGame/src/main/java/visualiser/gameController/Keys/TackGybeKey.java
+++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/TackGybeKey.java
@@ -9,11 +9,9 @@ public class TackGybeKey extends ControlKey {
/**
* Constructor for Control
- * @param name name of the key
- *
*/
- public TackGybeKey(String name) {
- super(name, BoatActionEnum.TACK_GYBE);
+ public TackGybeKey() {
+ super("Tack/Gybe", BoatActionEnum.TACK_GYBE);
}
@Override
diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/UpWindKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/UpWindKey.java
index 333e5f1f..b4bbf489 100644
--- a/racevisionGame/src/main/java/visualiser/gameController/Keys/UpWindKey.java
+++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/UpWindKey.java
@@ -9,11 +9,9 @@ public class UpWindKey extends ControlKey {
/**
* Constructor for Control
- * @param name name of the key
- *
*/
- public UpWindKey(String name) {
- super(name, BoatActionEnum.UPWIND);
+ public UpWindKey() {
+ super("Upwind", BoatActionEnum.UPWIND);
}
@Override
diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/VMGKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/VMGKey.java
index c01658bb..2c7237f0 100644
--- a/racevisionGame/src/main/java/visualiser/gameController/Keys/VMGKey.java
+++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/VMGKey.java
@@ -1,6 +1,5 @@
package visualiser.gameController.Keys;
-import javafx.scene.input.KeyCode;
import network.Messages.Enums.BoatActionEnum;
/**
@@ -10,11 +9,9 @@ public class VMGKey extends ControlKey{
/**
* Constructor for Control
- *
- * @param name name of the key
*/
- public VMGKey(String name) {
- super(name, BoatActionEnum.AUTO_PILOT);
+ public VMGKey() {
+ super("VMG", BoatActionEnum.AUTO_PILOT);
}
@Override
diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomInKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomInKey.java
index 51f98a58..e9a8ad7b 100644
--- a/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomInKey.java
+++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomInKey.java
@@ -5,8 +5,8 @@ package visualiser.gameController.Keys;
*/
public class ZoomInKey extends ControlKey {
- public ZoomInKey(String name) {
- super(name);
+ public ZoomInKey() {
+ super("Zoom In");
}
@Override
diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomOutKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomOutKey.java
index 6da2210c..cbba97fc 100644
--- a/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomOutKey.java
+++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomOutKey.java
@@ -7,11 +7,9 @@ public class ZoomOutKey extends ControlKey{
/**
* Constructor for Control
- * @param name name of the key
- *
*/
- public ZoomOutKey(String name) {
- super(name);
+ public ZoomOutKey() {
+ super("Zoom Out");
}
@Override
diff --git a/racevisionGame/src/main/java/visualiser/model/BoatDisplay3D.java b/racevisionGame/src/main/java/visualiser/model/BoatDisplay3D.java
new file mode 100644
index 00000000..9314f5cd
--- /dev/null
+++ b/racevisionGame/src/main/java/visualiser/model/BoatDisplay3D.java
@@ -0,0 +1,18 @@
+package visualiser.model;
+
+import com.interactivemesh.jfx.importer.Importer;
+import javafx.scene.layout.Pane;
+
+/**
+ * Created by fwy13 on 29/08/17.
+ */
+public class BoatDisplay3D extends Pane {
+
+
+ public BoatDisplay3D(String filePath){
+ super();
+// Shape3D
+// this.getChildren().add();
+ }
+
+}
diff --git a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java
index fc6a0858..03e86e27 100644
--- a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java
+++ b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java
@@ -39,9 +39,9 @@ public class ResizableRaceCanvas extends ResizableCanvas {
private Image sailsLuff = new Image("/images/sailsLuff.gif", 25, 10, false, false);
/**
- * The race we read data from and draw.
+ * The race state we read data from and draw.
*/
- private VisualiserRaceEvent visualiserRace;
+ private VisualiserRaceState raceState;
private boolean annoName = true;
@@ -56,14 +56,14 @@ public class ResizableRaceCanvas extends ResizableCanvas {
/**
* Constructs a {@link ResizableRaceCanvas} using a given {@link VisualiserRaceEvent}.
- * @param visualiserRace The race that data is read from in order to be drawn.
+ * @param raceState The race state to be drawn.
*/
- public ResizableRaceCanvas(VisualiserRaceEvent visualiserRace) {
+ public ResizableRaceCanvas(VisualiserRaceState raceState) {
super();
- this.visualiserRace = visualiserRace;
+ this.raceState = raceState;
- RaceDataSource raceData = visualiserRace.getVisualiserRaceState().getRaceDataSource();
+ RaceDataSource raceData = raceState.getRaceDataSource();
double lat1 = raceData.getMapTopLeft().getLatitude();
double long1 = raceData.getMapTopLeft().getLongitude();
@@ -276,8 +276,8 @@ public class ResizableRaceCanvas extends ResizableCanvas {
boat.getCountry(),
boat.getCurrentSpeed(),
this.map.convertGPS(boat.getPosition()),
- boat.getTimeToNextMarkFormatted(this.visualiserRace.getVisualiserRaceState().getRaceClock().getCurrentTime()),
- boat.getTimeSinceLastMarkFormatted(this.visualiserRace.getVisualiserRaceState().getRaceClock().getCurrentTime()),
+ boat.getTimeToNextMarkFormatted(raceState.getRaceClock().getCurrentTime()),
+ boat.getTimeSinceLastMarkFormatted(raceState.getRaceClock().getCurrentTime()),
Color.BLACK,
20 );
@@ -291,7 +291,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
*/
private void drawBoats() {
- List boats = new ArrayList<>(visualiserRace.getVisualiserRaceState().getBoats());
+ List boats = new ArrayList<>(raceState.getBoats());
//Sort to ensure we draw boats in consistent order.
boats.sort(Comparator.comparingInt(Boat::getSourceID));
@@ -510,7 +510,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
*/
private void drawMarks() {
- for (Mark mark : new ArrayList<>(visualiserRace.getVisualiserRaceState().getMarks())) {
+ for (Mark mark : new ArrayList<>(raceState.getMarks())) {
drawMark(mark);
}
}
@@ -574,7 +574,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
//Calculate the screen coordinates of the boundary.
- List boundary = new ArrayList<>(visualiserRace.getVisualiserRaceState().getBoundary());
+ List boundary = new ArrayList<>(raceState.getBoundary());
double[] xpoints = new double[boundary.size()];
double[] ypoints = new double[boundary.size()];
@@ -601,8 +601,8 @@ public class ResizableRaceCanvas extends ResizableCanvas {
public void drawRace() {
//Update RaceMap with new GPS values of race.
- this.map.setGPSTopLeft(visualiserRace.getVisualiserRaceState().getRaceDataSource().getMapTopLeft());
- this.map.setGPSBotRight(visualiserRace.getVisualiserRaceState().getRaceDataSource().getMapBottomRight());
+ this.map.setGPSTopLeft(raceState.getRaceDataSource().getMapTopLeft());
+ this.map.setGPSBotRight(raceState.getRaceDataSource().getMapBottomRight());
clear();
@@ -627,7 +627,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
* draws a transparent line around the course that shows the paths boats must travel
*/
public void drawRaceLine(){
- List legs = this.visualiserRace.getVisualiserRaceState().getLegs();
+ List legs = raceState.getLegs();
GPSCoordinate legStartPoint = legs.get(0).getStartCompoundMark().getAverageGPSCoordinate();
GPSCoordinate nextStartPoint;
for (int i = 0; i < legs.size() -1; i++) {
diff --git a/racevisionGame/src/main/java/visualiser/model/View3D.java b/racevisionGame/src/main/java/visualiser/model/View3D.java
new file mode 100644
index 00000000..6affb906
--- /dev/null
+++ b/racevisionGame/src/main/java/visualiser/model/View3D.java
@@ -0,0 +1,145 @@
+package visualiser.model;
+
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.scene.Group;
+import javafx.scene.PerspectiveCamera;
+import javafx.scene.SubScene;
+import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Shape3D;
+import javafx.scene.transform.Rotate;
+import javafx.scene.transform.Translate;
+
+/**
+ * Control for rendering 3D objects visible through a PerspectiveCamera. Implements Adapter Pattern to
+ * interface with camera, and allows clients to add shapes to the scene. All scenes contain sea plane and
+ * sky box, whose textures are set with special methods.
+ */
+public class View3D extends Pane {
+ /**
+ * Observable list of renderable items
+ */
+ private ObservableList items;
+ /**
+ * Rendering container for shapes
+ */
+ private Group world;
+ /**
+ * Near limit of view frustum
+ */
+ private double nearClip;
+ /**
+ * Far limit of view frustum
+ */
+ private double farClip;
+ /**
+ * Position camera pivots around
+ */
+ private Translate pivot;
+ /**
+ * Distance of camera from pivot point
+ */
+ private Translate distance;
+ /**
+ * Angle along ground between z-axis and camera
+ */
+ private Rotate yaw;
+ /**
+ * Angle between ground plane and camera direction
+ */
+ private Rotate pitch;
+
+ /**
+ * Default constructor for View3D. Sets up Scene and PerspectiveCamera.
+ */
+ public View3D() {
+ world = new Group();
+
+ SubScene scene = new SubScene(world, 300, 300);
+ scene.widthProperty().bind(this.widthProperty());
+ scene.heightProperty().bind(this.heightProperty());
+ scene.setFill(Color.BLACK);
+
+ scene.setCamera(buildCamera());
+
+ this.getChildren().add(scene);
+ }
+
+ /**
+ * Sets up camera view frustum and binds transformations
+ * @return perspective camera
+ */
+ private PerspectiveCamera buildCamera() {
+ PerspectiveCamera camera = new PerspectiveCamera(true);
+
+ // Set up view frustum
+ nearClip = 0.1;
+ farClip = 1000.0;
+ camera.setNearClip(nearClip);
+ camera.setFarClip(farClip);
+
+ // Set up transformations
+ pivot = new Translate();
+ distance = new Translate();
+ yaw = new Rotate(0, Rotate.Y_AXIS);
+ pitch = new Rotate(0, Rotate.X_AXIS);
+ camera.getTransforms().addAll(pivot, yaw, pitch, distance);
+
+ return camera;
+ }
+
+ public void setItems(ObservableList items) {
+ this.items = items;
+ this.items.addListener((ListChangeListener super Shape3D>) c -> {
+ while(c.next()) {
+ if (c.wasRemoved() || c.wasAdded()) {
+ for (Shape3D shape : c.getRemoved()) world.getChildren().remove(shape);
+ for (Shape3D shape : c.getAddedSubList()) world.getChildren().add(shape);
+ }
+ }
+ });
+ }
+
+ public void setNearClip(double nearClip) {
+ this.nearClip = nearClip;
+ }
+
+ public void setFarClip(double farClip) {
+ this.farClip = farClip;
+ }
+
+ /**
+ * Set object to centre on camera
+ * @param pivot centred object
+ */
+ public void setPivot(Shape3D pivot) {
+ this.pivot.setX(pivot.getTranslateX());
+ this.pivot.setY(pivot.getTranslateY());
+ this.pivot.setZ(pivot.getTranslateZ());
+ }
+
+ /**
+ * Set distance of camera from pivot
+ * @param distance in units
+ */
+ public void setDistance(double distance) {
+ this.distance.setZ(-distance);
+ }
+
+ /**
+ * Set angle of camera from z-axis along ground
+ * @param yaw in degrees
+ */
+ public void setYaw(double yaw) {
+ this.yaw.setAngle(yaw);
+ }
+
+ /**
+ * Set elevation of camera
+ * @param pitch in degrees
+ */
+ public void setPitch(double pitch) {
+ this.pitch.setAngle(-pitch);
+ }
+}
diff --git a/racevisionGame/src/main/resources/assets/V1.2 Complete Boat.stl b/racevisionGame/src/main/resources/assets/V1.2 Complete Boat.stl
new file mode 100644
index 00000000..a952ca77
Binary files /dev/null and b/racevisionGame/src/main/resources/assets/V1.2 Complete Boat.stl differ
diff --git a/racevisionGame/src/main/resources/css/keyBindings.css b/racevisionGame/src/main/resources/css/keyBindings.css
new file mode 100644
index 00000000..a572116e
--- /dev/null
+++ b/racevisionGame/src/main/resources/css/keyBindings.css
@@ -0,0 +1,45 @@
+.list-view .list-cell {
+ -fx-cell-size: 40;
+ -fx-font-family: "Tahoma";
+ -fx-background-color: #fffff0;
+ -fx-alignment: center;
+}
+
+.list-view .list-cell:even {
+ -fx-background-color: #ffffdc;
+}
+
+.list-view .list-cell:selected {
+ -fx-background-color: #f9e5c3;
+ -fx-font-family: "Comic Sans MS";
+ -fx-font-weight: bold;
+ -fx-font-size: 18;
+}
+
+.button {
+ -fx-background-color: linear-gradient(#acdeff 50%, #a9c8ff 100%);
+ -fx-background-radius: 4px;
+ -fx-border-radius: 4px;
+ -fx-text-fill: #242d35;
+ -fx-font-size: 12px;
+ -fx-font-family: "Courier New";
+ -fx-border-color: #a9c8ff;
+}
+
+.button:focused {
+ -fx-background-color: white;
+ -fx-border-color: #0056bd;
+}
+
+#anchor {
+ -fx-background-color: #fdfac3;
+}
+#menu{
+ -fx-background-color: linear-gradient(#acdeff 50%, #a9c8ff 100%);
+ -fx-background-radius: 4px;
+ -fx-border-radius: 4px;
+ -fx-text-fill: #242d35;
+ -fx-font-size: 12px;
+ -fx-font-family: "Verdana";
+ -fx-border-color: #a9c8ff;
+}
\ No newline at end of file
diff --git a/racevisionGame/src/main/resources/mock/mockXML/boatTest.xml b/racevisionGame/src/main/resources/mock/mockXML/boatTest.xml
index 9295dc07..59e2f79d 100644
--- a/racevisionGame/src/main/resources/mock/mockXML/boatTest.xml
+++ b/racevisionGame/src/main/resources/mock/mockXML/boatTest.xml
@@ -32,7 +32,6 @@
-
diff --git a/racevisionGame/src/main/resources/mock/mockXML/raceTest.xml b/racevisionGame/src/main/resources/mock/mockXML/raceTest.xml
index ad14d931..6ae04ef8 100644
--- a/racevisionGame/src/main/resources/mock/mockXML/raceTest.xml
+++ b/racevisionGame/src/main/resources/mock/mockXML/raceTest.xml
@@ -5,12 +5,7 @@
RACE_CREATION_TIME
-
-
-
-
-
-
+
diff --git a/racevisionGame/src/main/resources/mock/mockXML/schema/boatsSchema.xsd b/racevisionGame/src/main/resources/mock/mockXML/schema/boatsSchema.xsd
new file mode 100644
index 00000000..6d5af617
--- /dev/null
+++ b/racevisionGame/src/main/resources/mock/mockXML/schema/boatsSchema.xsd
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/racevisionGame/src/main/resources/mock/mockXML/schema/regattaSchema.xsd b/racevisionGame/src/main/resources/mock/mockXML/schema/regattaSchema.xsd
new file mode 100644
index 00000000..5c9fb774
--- /dev/null
+++ b/racevisionGame/src/main/resources/mock/mockXML/schema/regattaSchema.xsd
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/racevisionGame/src/main/resources/visualiser/images/arrow.png b/racevisionGame/src/main/resources/visualiser/images/arrow.png
index fab6e21d..cd7bab10 100644
Binary files a/racevisionGame/src/main/resources/visualiser/images/arrow.png and b/racevisionGame/src/main/resources/visualiser/images/arrow.png differ
diff --git a/racevisionGame/src/main/resources/visualiser/images/lobby.gif b/racevisionGame/src/main/resources/visualiser/images/lobby.gif
new file mode 100644
index 00000000..c70d8df6
Binary files /dev/null and b/racevisionGame/src/main/resources/visualiser/images/lobby.gif differ
diff --git a/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml b/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml
index ced36627..ab14abaf 100644
--- a/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml
+++ b/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml
@@ -1,40 +1,44 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml b/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml
new file mode 100644
index 00000000..c4198bf3
--- /dev/null
+++ b/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/racevisionGame/src/main/resources/visualiser/scenes/keyBindings.fxml b/racevisionGame/src/main/resources/visualiser/scenes/keyBindings.fxml
new file mode 100644
index 00000000..40217567
--- /dev/null
+++ b/racevisionGame/src/main/resources/visualiser/scenes/keyBindings.fxml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/racevisionGame/src/main/resources/visualiser/scenes/main.fxml b/racevisionGame/src/main/resources/visualiser/scenes/main.fxml
index 074a9b31..7aff44c0 100644
--- a/racevisionGame/src/main/resources/visualiser/scenes/main.fxml
+++ b/racevisionGame/src/main/resources/visualiser/scenes/main.fxml
@@ -7,7 +7,7 @@
-
+
diff --git a/racevisionGame/src/main/resources/visualiser/scenes/notification.fxml b/racevisionGame/src/main/resources/visualiser/scenes/notification.fxml
new file mode 100644
index 00000000..0e4a7c5b
--- /dev/null
+++ b/racevisionGame/src/main/resources/visualiser/scenes/notification.fxml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/racevisionGame/src/main/resources/visualiser/scenes/title.fxml b/racevisionGame/src/main/resources/visualiser/scenes/title.fxml
index f448a226..255381af 100644
--- a/racevisionGame/src/main/resources/visualiser/scenes/title.fxml
+++ b/racevisionGame/src/main/resources/visualiser/scenes/title.fxml
@@ -1,61 +1,61 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/racevisionGame/src/test/java/mock/model/ConstantWindGeneratorTest.java b/racevisionGame/src/test/java/mock/model/ConstantWindGeneratorTest.java
index 6f67dc30..f7c69acf 100644
--- a/racevisionGame/src/test/java/mock/model/ConstantWindGeneratorTest.java
+++ b/racevisionGame/src/test/java/mock/model/ConstantWindGeneratorTest.java
@@ -1,5 +1,7 @@
package mock.model;
+import mock.model.wind.ConstantWindGenerator;
+import mock.model.wind.WindGenerator;
import org.junit.Before;
import org.junit.Test;
import shared.model.Bearing;
diff --git a/racevisionGame/src/test/java/mock/model/MockBoatTest.java b/racevisionGame/src/test/java/mock/model/MockBoatTest.java
index 8d1f45ee..98b4ca27 100644
--- a/racevisionGame/src/test/java/mock/model/MockBoatTest.java
+++ b/racevisionGame/src/test/java/mock/model/MockBoatTest.java
@@ -3,6 +3,7 @@ package mock.model;
import org.junit.Before;
import org.junit.Test;
import shared.model.Bearing;
+import shared.model.Boat;
import shared.model.GPSCoordinate;
import shared.model.Mark;
@@ -13,6 +14,13 @@ public class MockBoatTest {
private Mark near;
private Mark far;
+
+ public static MockBoat createMockBoat() {
+ Boat boat = new Boat(121, "Test boat", "TS");
+ MockBoat mockBoat = new MockBoat(boat, null);
+ return mockBoat;
+ }
+
@Before
public void setUp() {
boat = new MockBoat(0, "Bob", "NZ", null);
diff --git a/racevisionGame/src/test/java/mock/model/MockRaceTest.java b/racevisionGame/src/test/java/mock/model/MockRaceTest.java
index 4f3f7705..f53b2970 100644
--- a/racevisionGame/src/test/java/mock/model/MockRaceTest.java
+++ b/racevisionGame/src/test/java/mock/model/MockRaceTest.java
@@ -1,7 +1,8 @@
package mock.model;
import mock.dataInput.PolarParserTest;
-import network.Messages.LatestMessages;
+import mock.model.wind.ConstantWindGenerator;
+import mock.model.wind.WindGenerator;
import shared.dataInput.*;
import shared.exceptions.InvalidBoatDataException;
import shared.exceptions.InvalidRaceDataException;
@@ -9,8 +10,6 @@ import shared.exceptions.InvalidRegattaDataException;
import shared.model.Bearing;
import shared.model.Constants;
-import static org.junit.Assert.*;
-
public class MockRaceTest {
//TODO
diff --git a/racevisionGame/src/test/java/mock/model/RandomWindGeneratorTest.java b/racevisionGame/src/test/java/mock/model/RandomWindGeneratorTest.java
index 76eed977..0f60bcea 100644
--- a/racevisionGame/src/test/java/mock/model/RandomWindGeneratorTest.java
+++ b/racevisionGame/src/test/java/mock/model/RandomWindGeneratorTest.java
@@ -1,5 +1,6 @@
package mock.model;
+import mock.model.wind.RandomWindGenerator;
import org.junit.Before;
import org.junit.Test;
import shared.model.Bearing;
diff --git a/racevisionGame/src/test/java/mock/model/SourceIdAllocatorTest.java b/racevisionGame/src/test/java/mock/model/SourceIdAllocatorTest.java
index 7240e01b..ad310540 100644
--- a/racevisionGame/src/test/java/mock/model/SourceIdAllocatorTest.java
+++ b/racevisionGame/src/test/java/mock/model/SourceIdAllocatorTest.java
@@ -1,6 +1,7 @@
package mock.model;
import mock.exceptions.SourceIDAllocationException;
+import network.Messages.Enums.RaceStatusEnum;
import org.junit.Before;
import org.junit.Test;
@@ -15,30 +16,16 @@ import static org.junit.Assert.*;
*/
public class SourceIdAllocatorTest {
- /**
- * This is the list of source IDs that we start with.
- */
- private List originalSourceIDs;
-
- /**
- * Used to allocate source IDs.
- */
+ private MockRace mockRace;
private SourceIdAllocator sourceIdAllocator;
@Before
public void setUp() throws Exception {
- originalSourceIDs = new ArrayList<>();
- originalSourceIDs.add(120);
- originalSourceIDs.add(121);
- originalSourceIDs.add(122);
- originalSourceIDs.add(123);
- originalSourceIDs.add(124);
- originalSourceIDs.add(125);
-
+ mockRace = MockRaceTest.createMockRace();
- sourceIdAllocator = new SourceIdAllocator(originalSourceIDs);
+ sourceIdAllocator = new SourceIdAllocator(mockRace);
}
@@ -49,11 +36,12 @@ public class SourceIdAllocatorTest {
@Test
public void emptyAllocationTest() {
- SourceIdAllocator allocator = new SourceIdAllocator(new ArrayList<>());
+ mockRace.getRaceDataSource().getParticipants().removeAll(mockRace.getBoatDataSource().getBoats().keySet());
+ mockRace.getRaceDataSource().getParticipants().addAll(mockRace.getBoatDataSource().getBoats().keySet());
try {
- int sourceID = allocator.allocateSourceID();
+ int sourceID = sourceIdAllocator.allocateSourceID();
fail("Exception should have been thrown, but wasn't.");
@@ -73,6 +61,7 @@ public class SourceIdAllocatorTest {
@Test
public void allocationTest() throws Exception {
+ mockRace.setRaceStatusEnum(RaceStatusEnum.PRESTART);
int sourceID = sourceIdAllocator.allocateSourceID();
@@ -108,10 +97,7 @@ public class SourceIdAllocatorTest {
@Test
public void reallocationTest() throws Exception {
- List sourceIDList = new ArrayList<>();
- sourceIDList.add(123);
-
- SourceIdAllocator sourceIdAllocator = new SourceIdAllocator(sourceIDList);
+ mockRace.setRaceStatusEnum(RaceStatusEnum.PRESTART);
//Allocate.
int sourceID = sourceIdAllocator.allocateSourceID();
diff --git a/racevisionGame/src/test/java/mock/model/commandFactory/WindCommandTest.java b/racevisionGame/src/test/java/mock/model/commandFactory/WindCommandTest.java
index 2193eb7a..158c43d6 100644
--- a/racevisionGame/src/test/java/mock/model/commandFactory/WindCommandTest.java
+++ b/racevisionGame/src/test/java/mock/model/commandFactory/WindCommandTest.java
@@ -1,11 +1,11 @@
package mock.model.commandFactory;
import mock.exceptions.CommandConstructionException;
-import mock.model.MockBoat;
-import mock.model.MockRace;
-import mock.model.MockRaceTest;
+import mock.exceptions.SourceIDAllocationException;
+import mock.model.*;
import network.Messages.BoatAction;
import network.Messages.Enums.BoatActionEnum;
+import network.Messages.Enums.RaceStatusEnum;
import org.junit.Before;
import org.junit.Test;
import shared.exceptions.InvalidBoatDataException;
@@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock;
*/
public class WindCommandTest {
private MockRace race;
+ private SourceIdAllocator allocator;
private MockBoat boat;
private Command upwind;
private Command downwind;
@@ -29,12 +30,15 @@ public class WindCommandTest {
private double offset = 3.0;
@Before
- public void setUp() throws CommandConstructionException, InvalidBoatDataException, InvalidRegattaDataException, InvalidRaceDataException {
+ public void setUp() throws CommandConstructionException, InvalidBoatDataException, InvalidRegattaDataException, InvalidRaceDataException, SourceIDAllocationException {
race = MockRaceTest.createMockRace();
-
+ allocator = new SourceIdAllocator(race);
+ race.setRaceStatusEnum(RaceStatusEnum.PRESTART);
+ allocator.allocateSourceID();
boat = race.getBoats().get(0);
+
//when(race.getWindDirection()).thenReturn(Bearing.fromDegrees(0.0));
boat.setBearing(Bearing.fromDegrees(45.0));
diff --git a/racevisionGame/src/test/java/visualiser/network/ConnectionToServerParticipantTest.java b/racevisionGame/src/test/java/visualiser/network/ConnectionToServerParticipantTest.java
index 64fdfcb5..4b6ed5e3 100644
--- a/racevisionGame/src/test/java/visualiser/network/ConnectionToServerParticipantTest.java
+++ b/racevisionGame/src/test/java/visualiser/network/ConnectionToServerParticipantTest.java
@@ -94,7 +94,7 @@ public class ConnectionToServerParticipantTest {
incomingCommands.put(command);
//Need to wait for connection thread to execute commands.
- Thread.sleep(250);
+ Thread.sleep(500);
assertEquals(ConnectionToServerState.CONNECTED, connectionToServer.getConnectionState());
assertTrue(connectionToServer.getJoinAcceptance() != null);
diff --git a/racevisionGame/src/test/resources/mock/mockXML/raceTest.xml b/racevisionGame/src/test/resources/mock/mockXML/raceTest.xml
index 4ad5f88f..b10a0158 100644
--- a/racevisionGame/src/test/resources/mock/mockXML/raceTest.xml
+++ b/racevisionGame/src/test/resources/mock/mockXML/raceTest.xml
@@ -5,12 +5,6 @@
2017-04-19T15:30:00+1200
-
-
-
-
-
-
@@ -54,4 +48,4 @@
-
\ No newline at end of file
+
diff --git a/settings/keyBindings.xml b/settings/keyBindings.xml
new file mode 100644
index 00000000..2b807e17
--- /dev/null
+++ b/settings/keyBindings.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ SPACE
+
+
+
+ SHIFT
+
+
+
+ DOWN
+
+
+
+ X
+
+
+
+ ENTER
+
+
+
+ Z
+
+
+
+ UP
+
+
+
+