Boats and map are now updated using the observer pattern.

#implement
This commit is contained in:
Calum
2017-07-31 05:23:41 +12:00
parent f1ad03e913
commit b82d0d0137
19 changed files with 241 additions and 2210 deletions
-2
View File
@@ -7,7 +7,6 @@ import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import seng302.model.PolarTable;
import seng302.model.stream.StreamReceiver;
public class App extends Application {
@@ -28,7 +27,6 @@ public class App extends Application {
primaryStage.show();
primaryStage.setOnCloseRequest(e -> {
// ClientPacketParser.appClose();
StreamReceiver.noMoreBytes();
// ClientPacketParser.appClose();
System.exit(0);
});
@@ -1,631 +0,0 @@
//package seng302.client;
//
//
//import java.io.IOException;
//import java.io.StringReader;
//import java.text.DateFormat;
//import java.text.SimpleDateFormat;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.Date;
//import java.util.TimeZone;
//import java.util.concurrent.ConcurrentHashMap;
//import java.util.concurrent.ConcurrentSkipListMap;
//import java.util.concurrent.PriorityBlockingQueue;
//import javax.xml.parsers.DocumentBuilder;
//import javax.xml.parsers.DocumentBuilderFactory;
//import javax.xml.parsers.ParserConfigurationException;
//import org.w3c.dom.Document;
//import org.xml.sax.InputSource;
//import org.xml.sax.SAXException;
//
///**
// * The purpose of this class is to take in the stream of divided packets so they can be read
// * and parsed in by turning the byte arrays into useful data. There are two public static hashmaps
// * that are threadsafe so the visualiser can always access the latest speed and position available
// * Created by kre39 on 23/04/17.
// */
//public class ClientPacketParser {
//
// public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> markLocations = new ConcurrentHashMap<>();
// public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> boatLocations = new ConcurrentHashMap<>();
// private static boolean newRaceXmlReceived = false;
// private static boolean raceStarted = false;
// private static XMLParser xmlObject = new XMLParser();
// private static boolean raceFinished = false;
// private static boolean streamStatus = false;
// private static long timeSinceStart = -1;
// private static Map<Integer, Yacht> boats = new ConcurrentHashMap<>();
// private static Map<Integer, Yacht> boatsPos = new ConcurrentSkipListMap<>();
// private static double windDirection = 0;
// private static Double windSpeed = 0d;
// private static Long currentTimeLong;
// private static String currentTimeString;
// private static boolean appRunning;
// private static Map<Integer, Yacht> clientStateBoats = new ConcurrentHashMap<>();
//
// //CONVERSION CONSTANTS
// public static final Double MS_TO_KNOTS = 1.94384;
//
// /**
// * Used to initialise the thread name and stream parser object so a thread can be executed
// */
// public ClientPacketParser() {
// }
//
// /**
// * Looks at the type of the packet then sends it to the appropriate parser to extract the
// * specific data associated with that packet type
// *
// * @param packet the packet to be looked at and processed
// */
// public static void parsePacket(StreamPacket packet) {
// try {
// switch (packet.getType()) {
// case HEARTBEAT:
// extractHeartBeat(packet);
// break;
// case RACE_STATUS:
// extractRaceStatus(packet);
// break;
// case DISPLAY_TEXT_MESSAGE:
// extractDisplayMessage(packet);
// break;
// case XML_MESSAGE:
// extractXmlMessage(packet);
// break;
// case RACE_START_STATUS:
// extractRaceStartStatus(packet);
// break;
// case YACHT_EVENT_CODE:
// extractYachtEventCode(packet);
// break;
// case YACHT_ACTION_CODE:
// extractYachtActionCode(packet);
// break;
// case CHATTER_TEXT:
// extractChatterText(packet);
// break;
// case BOAT_LOCATION:
// extractBoatLocation(packet);
// break;
// case MARK_ROUNDING:
// extractMarkRounding(packet);
// break;
// case COURSE_WIND:
// extractCourseWind(packet);
// break;
// case AVG_WIND:
// extractAvgWind(packet);
// break;
// }
// } catch (NullPointerException e) {
// System.out.println("Error parsing packet");
// }
// }
//
// /**
// * Extracts the seq num used in the heartbeat packet
// *
// * @param packet Packet parsed in to use the payload
// */
// private static void extractHeartBeat(StreamPacket packet) {
// long heartbeat = bytesToLong(packet.getPayload());
// }
//
// private static String getTimeZoneString() {
//
// Integer offset = xmlObject.getRegattaXML().getUtcOffset();
// StringBuilder utcOffset = new StringBuilder();
// utcOffset.append("GMT");
// if (offset > 0) {
// utcOffset.append("+");
// utcOffset.append(offset);
// } else if (offset < 0) {
// utcOffset.append("-");
// utcOffset.append(offset);
// }
// return utcOffset.toString();
//
// }
//
// /**
// * Extracts the useful race status data from race status type packets. This method will also
// * print to the console the current state of the race (if it has started/finished or is about to
// * start), along side this it'll also display the amount of time since the race has started or
// * time till it starts
// *
// * @param packet Packet parsed in to use the payload
// */
// private static void extractRaceStatus(StreamPacket packet) {
// byte[] payload = packet.getPayload();
// int messageVersionNo = payload[0];
// long currentTime = bytesToLong(Arrays.copyOfRange(payload, 1, 7));
// long raceId = bytesToLong(Arrays.copyOfRange(payload, 7, 11));
// int raceStatus = payload[11];
// long expectedStartTime = bytesToLong(Arrays.copyOfRange(payload,12,18));
// long windDir = bytesToLong(Arrays.copyOfRange(payload,18,20));
// long rawWindSpeed = bytesToLong(Arrays.copyOfRange(payload,20,22));
//
// currentTimeLong = currentTime;
// DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
// if (xmlObject.getRegattaXML() != null) {
// format.setTimeZone(TimeZone.getTimeZone(getTimeZoneString()));
// currentTimeString = format.format((new Date(currentTime)).getTime());
// }
// long timeTillStart =
// ((new Date(expectedStartTime)).getTime() - (new Date(currentTime)).getTime()) / 1000;
//
// if (timeTillStart > 0) {
// timeSinceStart = timeTillStart;
// } else {
// if (raceStatus == 4 || raceStatus == 8) {
// raceFinished = true;
// raceStarted = false;
// ClientState.setRaceStarted(false);
// } else if (!raceStarted) {
// raceStarted = true;
// ClientState.setRaceStarted(true);
// raceFinished = false;
// }
// timeSinceStart = timeTillStart;
// }
//
// double windDirFactor = 0x4000 / 90; //0x4000 is 90 degrees, 0x8000 is 180 degrees, etc...
// windDirection = windDir / windDirFactor;
// windSpeed = rawWindSpeed / 1000 * MS_TO_KNOTS;
//
// int noBoats = payload[22];
// int raceType = payload[23];
// for (int i = 0; i < noBoats; i++) {
// long boatStatusSourceID = bytesToLong(
// Arrays.copyOfRange(payload, 24 + (i * 20), 28 + (i * 20)));
// int boatStatus = (int) payload[28 + (i * 20)];
// int boatLegNumber = (int) payload[29 + (i * 20)];
// int boatPenaltyAwarded = (int) payload[30 + (i * 20)];
// int boatPenaltyServed = (int) payload[31 + (i * 20)];
// long estTimeAtNextMark = bytesToLong(
// Arrays.copyOfRange(payload, 32 + (i * 20), 38 + (i * 20)));
// long estTimeAtFinish = bytesToLong(
// Arrays.copyOfRange(payload, 38 + (i * 20), 44 + (i * 20)));
//
// Yacht boat = boats.get((int) boatStatusSourceID);
// boat.setBoatStatus((boatStatus));
// setBoatLegPosition(boat, boatLegNumber);
// boat.setPenaltiesAwarded(boatPenaltyAwarded);
// boat.setPenaltiesServed(boatPenaltyServed);
// boat.setEstimateTimeAtNextMark(estTimeAtNextMark);
// boat.setEstimateTimeAtFinish(estTimeAtFinish);
//
// // Update Client State boats when receive race status packet.
// // Potentially could replace boats in ClientPacketParser.
// Yacht clientBoat = ClientState.getBoats().get((int) boatStatusSourceID);
// clientBoat.setBoatStatus((boatStatus));
// setBoatLegPosition(clientBoat, boatLegNumber);
// clientBoat.setPenaltiesAwarded(boatPenaltyAwarded);
// clientBoat.setPenaltiesServed(boatPenaltyServed);
// clientBoat.setEstimateTimeAtNextMark(estTimeAtNextMark);
// clientBoat.setEstimateTimeAtFinish(estTimeAtFinish);
// }
//
// // 3 is race started.
// // ClientState race started flag will be set to true if race started, else set false.
// if (raceStatus == 3) {
// ClientState.setRaceStarted(true);
// } else {
// ClientState.setRaceStarted(false);
// }
// }
//
// private static void setBoatLegPosition(Yacht updatingBoat, Integer leg){
// Integer placing = 1;
//
// if (/* TODO implement when we are getting this data /TODO leg != updatingBoat.getLegNumber() && */(raceStarted || raceFinished)) {
// for (Yacht boat : boats.values()) {
// placing = boat.getSourceId();
// /* See above to-do
// if (boat.getLegNumber() != null && leg <= boat.getLegNumber()){
// placing += 1;
// }*/
// }
// updatingBoat.setPosition(placing.toString());
// updatingBoat.setLegNumber(leg);
// boatsPos.putIfAbsent(placing, updatingBoat);
// boatsPos.replace(placing, updatingBoat);
// } else if(updatingBoat.getLegNumber() == null){
// updatingBoat.setPosition("-");
// updatingBoat.setLegNumber(leg);
// }
// }
//
// /**
// * Used to extract the messages passed through with the display message packet
// *
// * @param packet Packet parsed in to use the payload
// */
// private static void extractDisplayMessage(StreamPacket packet) {
// byte[] payload = packet.getPayload();
// int messageVersionNo = payload[0];
// int numOfLines = payload[3];
// int totalLen = 0;
// for (int i = 0; i < numOfLines; i++) {
// int lineNum = payload[4 + totalLen];
// int textLength = payload[5 + totalLen];
// byte[] messageTextBytes = Arrays
// .copyOfRange(payload, 6 + totalLen, 6 + textLength + totalLen);
// String messageText = new String(messageTextBytes);
// totalLen += 2 + textLength;
// }
// }
//
// /**
// * Used to read in the xml data. Will call the specific methods to create the course and boats
// *
// * @param packet Packet parsed in to use the payload
// */
// private static void extractXmlMessage(StreamPacket packet) {
// xmlObject = new XMLParser();
// byte[] payload = packet.getPayload();
// int messageType = payload[9];
// long messageLength = bytesToLong(Arrays.copyOfRange(payload, 12, 14));
// String xmlMessage = new String(
// (Arrays.copyOfRange(payload, 14, (int) (14 + messageLength)))).trim();
//
// //Create XML document Object
// DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// DocumentBuilder db = null;
// Document doc = null;
// try {
// db = dbf.newDocumentBuilder();
// doc = db.parse(new InputSource(new StringReader(xmlMessage)));
// } catch (ParserConfigurationException | IOException | SAXException e) {
// System.out.println("[ClientPacketParser] ParserConfigurationException | IOException | SAXException");
// }
//
// xmlObject.constructXML(doc, messageType);
//
// if (messageType == 7) { //7 is the boat XML
// boats = xmlObject.getBoatXML().getCompetingBoats();
// // Set/Update the ClientState boats after receiving new boat xml.
// // Flag boatsUpdated in ClientState to true.
// ClientState.setBoats(xmlObject.getBoatXML().getCompetingBoats());
// ClientState.setBoatsUpdated(true);
// }
// if (messageType == 6) { //6 is race info xml
// newRaceXmlReceived = true;
// }
// }
//
// /**
// * Extracts the race start status from the packet, currently is unused within the app but
// * is here for potential future use
// *
// * @param packet Packet parsed in to use the payload
// */
// private static void extractRaceStartStatus(StreamPacket packet) {
// byte[] payload = packet.getPayload();
// int messageVersionNo = payload[0];
// long timeStamp = bytesToLong(Arrays.copyOfRange(payload, 1, 7));
// long raceStartTime = bytesToLong(Arrays.copyOfRange(payload, 9, 15));
// long raceId = bytesToLong(Arrays.copyOfRange(payload, 15, 19));
// int notificationType = payload[19];
// }
//
// /**
// * When a yacht event occurs this will parse the byte array to retrieve the necessary info,
// * currently unused
// *
// * @param packet Packet parsed in to use the payload
// */
// private static void extractYachtEventCode(StreamPacket packet) {
// byte[] payload = packet.getPayload();
// int messageVersionNo = payload[0];
// long timeStamp = bytesToLong(Arrays.copyOfRange(payload, 1, 7));
// long raceId = bytesToLong(Arrays.copyOfRange(payload, 9, 13));
// long subjectId = bytesToLong(Arrays.copyOfRange(payload, 13, 17));
// long incidentId = bytesToLong(Arrays.copyOfRange(payload, 17, 21));
// int eventId = payload[21];
// }
//
// /**
// * When a yacht action occurs this will parse the parse the byte array to retrieve the necessary
// * info, currently unused
// *
// * @param packet Packet parsed in to use the payload
// */
// private static void extractYachtActionCode(StreamPacket packet) {
// byte[] payload = packet.getPayload();
// int messageVersionNo = payload[0];
// long timeStamp = bytesToLong(Arrays.copyOfRange(payload, 1, 7));
// long subjectId = bytesToLong(Arrays.copyOfRange(payload, 9, 13));
// long incidentId = bytesToLong(Arrays.copyOfRange(payload, 13, 17));
// int eventId = payload[17];
// }
//
// /**
// * Strips the message from the chatter text type packets, currently the message is unused
// *
// * @param packet Packet parsed in to use the payload
// */
// private static void extractChatterText(StreamPacket packet) {
// byte[] payload = packet.getPayload();
// int messageVersionNo = payload[0];
// int messageType = payload[1];
// int length = payload[2];
// String message = new String(Arrays.copyOfRange(payload, 3, 3 + length));
// System.out.println(message);
// }
//
// /**
// * Used to breakdown the boatlocation packets so the boat coordinates, id and groundspeed are
// * all used All the other extra data is still being read and translated however is unused.
// *
// * @param packet Packet parsed in to use the payload
// */
// private static void extractBoatLocation(StreamPacket packet) {
// byte[] payload = packet.getPayload();
//
// int deviceType = (int) payload[15];
// long timeValid = bytesToLong(Arrays.copyOfRange(payload, 1, 7));
// long seq = bytesToLong(Arrays.copyOfRange(payload, 11, 15));
// long boatId = bytesToLong(Arrays.copyOfRange(payload, 7, 11));
// long rawLat = bytesToLong(Arrays.copyOfRange(payload, 16, 20));
// long rawLon = bytesToLong(Arrays.copyOfRange(payload, 20, 24));
// //Converts the double to a usable lat/lon
// double lat = ((180d * (double) rawLat) / Math.pow(2, 31));
// double lon = ((180d * (double) rawLon) / Math.pow(2, 31));
//// System.out.println("[CLIENT] Lat: " + lat + " Lon: " + lon);
// long heading = bytesToLong(Arrays.copyOfRange(payload, 28, 30));
// double groundSpeed = bytesToLong(Arrays.copyOfRange(payload, 38, 40)) / 1000.0;
// //type 1 is a racing yacht and type 3 is a mark, needed for updating positions of the mark and boat
// if (deviceType == 1){
// Yacht boat = boats.get((int) boatId);
// boat.setVelocity(groundSpeed);
// BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon, heading, groundSpeed);
//
// //add a new priority que to the boatLocations HashMap
// if (!boatLocations.containsKey(boatId)) {
// boatLocations.put(boatId,
// new PriorityBlockingQueue<>(256, new Comparator<BoatPositionPacket>() {
// @Override
// public int compare(BoatPositionPacket p1, BoatPositionPacket p2) {
// return (int) (p1.getTimeValid() - p2.getTimeValid());
// }
// }));
// }
// boatLocations.get(boatId).put(boatPacket);
// } else if (deviceType == 3) {
// BoatPositionPacket markPacket = new BoatPositionPacket(boatId, timeValid, lat, lon,
// heading, groundSpeed);
//
// //add a new priority que to the boatLocations HashMap
// if (!markLocations.containsKey(boatId)) {
// markLocations.put(boatId,
// new PriorityBlockingQueue<>(256, new Comparator<BoatPositionPacket>() {
// @Override
// public int compare(BoatPositionPacket p1, BoatPositionPacket p2) {
// return (int) (p1.getTimeValid() - p2.getTimeValid());
// }
// }));
// }
// markLocations.get(boatId).put(markPacket);
// }
// }
//
// /**
// * This packet type is received when a mark or gate is rounded by a boat
// *
// * @param packet The packet containing the payload
// */
// private static void extractMarkRounding(StreamPacket packet) {
// byte[] payload = packet.getPayload();
// int messageVersionNo = payload[0];
// long timeStamp = bytesToLong(Arrays.copyOfRange(payload, 1, 7));
// long raceId = bytesToLong(Arrays.copyOfRange(payload, 9, 13));
// long subjectId = bytesToLong(Arrays.copyOfRange(payload, 13, 17));
// int boatStatus = payload[17];
// int roundingSide = payload[18];
// int markType = payload[19];
// int markId = payload[20];
//
// // assign mark rounding time to boat
// boats.get((int)subjectId).setMarkRoundingTime(timeStamp);
//
// for (Mark mark : xmlObject.getRaceXML().getAllCompoundMarks()) {
// if (mark.getCompoundMarkID() == markId) {
// boats.get((int)subjectId).setLastMarkRounded(mark);
// }
// }
// }
//
// /**
// * This packet type contains periodic data on the state of the wind
// *
// * @param packet The packet containing the payload
// */
// private static void extractCourseWind(StreamPacket packet) {
// byte[] payload = packet.getPayload();
// int messageVersionNo = payload[0];
// int selectedWindId = payload[1];
// int loopCount = payload[2];
// ArrayList<String> windInfo = new ArrayList<>();
// for (int i = 0; i < loopCount; i++) {
// String wind = "WindId: " + payload[3 + (20 * i)];
// wind +=
// "\nTime: " + bytesToLong(Arrays.copyOfRange(payload, 4 + (20 * i), 10 + (20 * i)));
// wind += "\nRaceId: " + bytesToLong(
// Arrays.copyOfRange(payload, 10 + (20 * i), 14 + (20 * i)));
// wind += "\nWindDirection: " + bytesToLong(
// Arrays.copyOfRange(payload, 14 + (20 * i), 16 + (20 * i)));
// wind += "\nWindSpeed: " + bytesToLong(
// Arrays.copyOfRange(payload, 16 + (20 * i), 18 + (20 * i)));
// wind += "\nBestUpWindAngle: " + bytesToLong(
// Arrays.copyOfRange(payload, 18 + (20 * i), 20 + (20 * i)));
// wind += "\nBestDownWindAngle: " + bytesToLong(
// Arrays.copyOfRange(payload, 20 + (20 * i), 22 + (20 * i)));
// wind += "\nFlags: " + String
// .format("%8s", Integer.toBinaryString(payload[22 + (20 * i)] & 0xFF))
// .replace(' ', '0');
// windInfo.add(wind);
// }
// }
//
// /**
// * This packet conatins the average wind to ground speed
// *
// * @param packet The packet containing the paylaod
// */
// private static void extractAvgWind(StreamPacket packet) {
// byte[] payload = packet.getPayload();
// int messageVersionNo = payload[0];
// long timeStamp = bytesToLong(Arrays.copyOfRange(payload, 1, 7));
// long rawPeriod = bytesToLong(Arrays.copyOfRange(payload, 7, 9));
// long rawSamplePeriod = bytesToLong(Arrays.copyOfRange(payload, 9, 11));
// long period2 = bytesToLong(Arrays.copyOfRange(payload, 11, 13));
// long speed2 = bytesToLong(Arrays.copyOfRange(payload, 13, 15));
// long period3 = bytesToLong(Arrays.copyOfRange(payload, 15, 17));
// long speed3 = bytesToLong(Arrays.copyOfRange(payload, 17, 19));
// long period4 = bytesToLong(Arrays.copyOfRange(payload, 19, 21));
// long speed4 = bytesToLong(Arrays.copyOfRange(payload, 21, 23));
// }
//
// /**
// * takes an array of up to 7 bytes and returns a positive
// * long constructed from the input bytes
// *
// * @return a positive long if there is less than 7 bytes -1 otherwise
// */
// private static long bytesToLong(byte[] bytes) {
// long partialLong = 0;
// int index = 0;
// for (byte b : bytes) {
// if (index > 6) {
// return -1;
// }
// partialLong = partialLong | (b & 0xFFL) << (index * 8);
// index++;
// }
// return partialLong;
// }
//
// /**
// * returns false if race not started, true otherwise
// *
// * @return race started status
// */
// public static boolean isRaceStarted() {
// return raceStarted;
// }
//
// /**
// * returns false if stream not connected, true otherwise
// *
// * @return stream started status
// */
// public static boolean isStreamStatus() {
// return streamStatus;
// }
//
// /**
// * returns race timer
// *
// * @return race timer in long
// */
// public static long getTimeSinceStart() {
// return timeSinceStart;
// }
//
// /**
// * return false if race not finished, true otherwise
// *
// * @return race finished status
// */
// public static boolean isRaceFinished() {
// return raceFinished;
// }
//
// /**
// * return a map of boats with sourceID and the boat
// *
// * @return map of boats
// */
// public static Map<Integer, Yacht> getBoats() {
// return boats;
// }
//
//
// /**
// * returns the latest updated object from xml parser
// *
// * @return the latest xml object
// */
// public static XMLParser getXmlObject() {
// return xmlObject;
// }
//
// /**
// * returns the wind direction in degrees
// *
// * @return a double wind direction value
// */
// public static double getWindDirection() {
// return windDirection;
// }
//
//
// /**
// * Returns the wind speed in knots
// * @return A double indicating the wind speed in knots
// */
// public static Double getWindSpeed() {
// return windSpeed;
// }
//
// /**
// * returns stream time in formatted string format
// *
// * @return String of stream time
// */
// public static String getCurrentTimeString() {
// return currentTimeString;
// }
//
// /**
// * used in boat position since tree map can sort position efficiently.
// *
// * @return a map of time to finish and boat.
// */
// public static Map<Integer, Yacht> getBoatsPos() {
//
// return boatsPos;
// }
//
// /**
// * returns current time in stream in long
// *
// * @return a long value of current time
// */
// public static Long getCurrentTimeLong() {
// return currentTimeLong;
// }
//
// public static void appClose() {
// appRunning = false;
// }
//
// /**
// * Used to check if a new un-processed xml has been found, if so will return true before
// * toggling off so that the next check will return false.
// *
// * @return the status of if new xml has been received
// */
// public static boolean isNewRaceXmlReceived() {
// if (newRaceXmlReceived) {
// newRaceXmlReceived = false;
// return true;
// } else {
// return false;
// }
// }
//}
//
@@ -1,77 +0,0 @@
//package seng302.client;
//
//import java.util.Map;
//import java.util.concurrent.ConcurrentHashMap;
//import seng302.model.Yacht;
//import javafx.stage.Stage;
//import seng302.models.Yacht;
//
///**
// * Used by the client to store static variables to be used in game.
// */
//public class ClientState {
//
//// private static String hostIp = "";
//// private static Boolean isHost = false;
//// private static Boolean raceStarted = false;
//// private static Boolean connectedToHost = false;
//// private static Map<Integer, Yacht> boats = new ConcurrentHashMap<>();
//// private static Boolean dirtyState = true;
//// private static String clientSourceId = "";
////
//// public static String getHostIp() {
//// return hostIp;
//// }
////
//// public static void setHostIp(String hostIp) {
//// ClientState.hostIp = hostIp;
//// }
////
//// public static Boolean isHost() {
//// return isHost;
//// }
////
//// public static void setHost(Boolean isHost) {
//// ClientState.isHost = isHost;
//// }
////
//// public static Boolean isRaceStarted() {
//// return raceStarted;
//// }
////
//// public static void setRaceStarted(Boolean raceStarted) {
//// ClientState.raceStarted = raceStarted;
//// }
////
//// public static Boolean isConnectedToHost() {
//// return connectedToHost;
//// }
////
//// public static void setConnectedToHost(Boolean connectedToHost) {
//// ClientState.connectedToHost = connectedToHost;
//// }
////
//// public static Map<Integer, Yacht> getBoats() {
//// return boats;
//// }
////
//// public static Boolean isDirtyState() {
//// return dirtyState;
//// }
////
//// public static void setDirtyState(Boolean dirtyState) {
//// ClientState.dirtyState = dirtyState;
//// }
////
//// public static String getClientSourceId() {
//// return clientSourceId;
//// }
////
//// public static void setClientSourceId(String clientSourceId) {
//// ClientState.clientSourceId = clientSourceId;
//// }
////
//// public static void setBoats(Map<Integer, Yacht> boats) {
//// ClientState.boats = boats;
//// }
//}
@@ -1,43 +0,0 @@
//package seng302.client;
//
//import java.util.Observable;
//
///**
// * Used by LobbyController to run a separate thread-loop
// * updates the controller when change is detected.
// */
//public class ClientStateQueryingRunnable extends Observable implements Runnable {
//
// private Boolean terminate = false;
//
// public ClientStateQueryingRunnable() {}
//
// @Override
// public void run() {
// while(!terminate) {
// // Sleeping the thread so it will respond to the if statement below
// // if you know a better fix, pls tell me :) -ryan
// try {
// Thread.sleep(0);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//
// if (ClientState.isRaceStarted() && ClientState.isConnectedToHost()) {
// setChanged();
// notifyObservers("game started");
// terminate();
// }
//
// if (ClientState.isDirtyState()) {
// setChanged();
// notifyObservers("update players");
// ClientState.setDirtyState(false);
// }
// }
// }
//
// public void terminate() {
// terminate = true;
// }
//}
@@ -1,106 +0,0 @@
//package seng302.controllers;
//
//import java.io.IOException;
//import java.net.URL;
//import java.util.ResourceBundle;
//import javafx.fxml.FXML;
//import javafx.fxml.FXMLLoader;
//import javafx.fxml.Initializable;
//import javafx.scene.Parent;
//import javafx.scene.input.KeyEvent;
//import javafx.scene.layout.AnchorPane;
//import seng302.client.ClientPacketParser;
//import seng302.client.ClientState;
//import seng302.client.ClientToServerThread;
//import seng302.server.messages.BoatActionMessage;
//import seng302.server.messages.BoatActionType;
//
//public class Controller implements Initializable {
//
// @FXML
// private AnchorPane contentPane;
// private ClientToServerThread clientToServerThread;
// private long lastSendingTime;
// private int KEY_STROKE_SENDING_FREQUENCY = 50;
//
// public Object setContentPane(String jfxUrl) {
// try {
// contentPane.getChildren().removeAll();
// contentPane.getChildren().clear();
// contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString());
// FXMLLoader fxmlLoader = new FXMLLoader((getClass().getResource(jfxUrl)));
// Parent view = fxmlLoader.load();
// contentPane.getChildren().addAll(view);
// return fxmlLoader.getController();
// } catch (javafx.fxml.LoadException e) {
// System.err.println(e.getCause());
// } catch (IOException e) {
// System.err.println(e);
// }
// return null;
// }
//
// @Override
// public void initialize(URL location, ResourceBundle resources) {
// setUpStartScreen();
// lastSendingTime = System.currentTimeMillis();
// }
//
// void setUpStartScreen() {
// contentPane.getChildren().removeAll();
// contentPane.getChildren().clear();
// contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString());
// StartScreenController startScreenController = (StartScreenController) setContentPane("/views/StartScreenView.fxml");
// startScreenController.setController(this);
// ClientPacketParser.boatLocations.clear();
// }
//
//
// /** Handle the key-pressed event from the text field. */
// public void keyPressed(KeyEvent e) {
// BoatActionMessage boatActionMessage;
// long currentTime = System.currentTimeMillis();
// if (currentTime - lastSendingTime > KEY_STROKE_SENDING_FREQUENCY && ClientState.isRaceStarted()) {
// lastSendingTime = currentTime;
// switch (e.getCode()) {
// case SPACE: // align with vmg
// boatActionMessage = new BoatActionMessage(BoatActionType.VMG);
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
// break;
// case PAGE_UP: // upwind
// boatActionMessage = new BoatActionMessage(BoatActionType.UPWIND);
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
// break;
// case PAGE_DOWN: // downwind
// boatActionMessage = new BoatActionMessage(BoatActionType.DOWNWIND);
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
// break;
// case ENTER: // tack/gybe
// boatActionMessage = new BoatActionMessage(BoatActionType.TACK_GYBE);
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
// break;
// //TODO Allow a zoom in and zoom out methods
// case Z: // zoom in
// System.out.println("Zoom in");
// break;
// case X: // zoom out
// System.out.println("Zoom out");
// break;
// }
// }
// }
//
// public void keyReleased(KeyEvent e) {
// switch (e.getCode()) {
// //TODO 12/07/17 Determine the sail state and send the appropriate packet (eg. if sails are in, send a sail out packet)
// case SHIFT: // sails in/sails out
// BoatActionMessage boatActionMessage = new BoatActionMessage(BoatActionType.SAILS_IN);
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
// break;
// }
// }
//
// public void setClientToServerThread(ClientToServerThread ctt) {
// clientToServerThread = ctt;
// }
//}
@@ -1,235 +0,0 @@
//package seng302.controllers;
//
//import java.io.IOException;
//import java.net.URL;
//import java.util.*;
//
//import javafx.application.Platform;
//import javafx.collections.FXCollections;
//import javafx.collections.ObservableList;
//import javafx.fxml.FXML;
//import javafx.fxml.FXMLLoader;
//import javafx.fxml.Initializable;
//import javafx.scene.control.Button;
//import javafx.scene.control.ListView;
//import javafx.scene.image.Image;
//import javafx.scene.image.ImageView;
//import javafx.scene.layout.AnchorPane;
//import javafx.scene.layout.GridPane;
//import javafx.scene.layout.Pane;
//import javafx.scene.text.Text;
//import seng302.client.ClientState;
//import seng302.client.ClientStateQueryingRunnable;
//import seng302.gameServer.GameStages;
//import seng302.gameServer.GameState;
//import seng302.gameServer.MainServerThread;
//
///**
// * A class describing the actions of the lobby screen
// * Created by wmu16 on 10/07/17.
// */
//public class LobbyController implements Initializable, Observer{
// @FXML
// private GridPane lobbyScreen;
// @FXML
// private Text lobbyIpText;
// @FXML
// private Button readyButton;
// @FXML
// private ListView firstListView;
// @FXML
// private ListView secondListView;
// @FXML
// private ListView thirdListView;
// @FXML
// private ListView fourthListView;
// @FXML
// private ListView fifthListView;
// @FXML
// private ListView sixthListView;
// @FXML
// private ListView seventhListView;
// @FXML
// private ListView eighthListView;
// @FXML
// private ImageView firstImageView;
// @FXML
// private ImageView secondImageView;
// @FXML
// private ImageView thirdImageView;
// @FXML
// private ImageView fourthImageView;
// @FXML
// private ImageView fifthImageView;
// @FXML
// private ImageView sixthImageView;
// @FXML
// private ImageView seventhImageView;
// @FXML
// private ImageView eighthImageView;
//
// private static List<ObservableList<String>> competitors = new ArrayList<>();
// private static ObservableList<String> firstCompetitor = FXCollections.observableArrayList();
// private static ObservableList<String> secondCompetitor = FXCollections.observableArrayList();
// private static ObservableList<String> thirdCompetitor = FXCollections.observableArrayList();
// private static ObservableList<String> fourthCompetitor = FXCollections.observableArrayList();
// private static ObservableList<String> fifthCompetitor = FXCollections.observableArrayList();
// private static ObservableList<String> sixthCompetitor = FXCollections.observableArrayList();
// private static ObservableList<String> seventhCompetitor = FXCollections.observableArrayList();
// private static ObservableList<String> eighthCompetitor = FXCollections.observableArrayList();
// private ClientStateQueryingRunnable clientStateQueryingRunnable;
// private static List<ImageView> imageViews;
// private static List<ListView> listViews;
//
// private int MAX_NUM_PLAYERS = 8;
//
// private Boolean switchedPane = false;
// private MainServerThread mainServerThread;
// private Controller controller;
//
// private void setContentPane(String jfxUrl) {
// try {
// AnchorPane contentPane = (AnchorPane) lobbyScreen.getParent();
// contentPane.getChildren().removeAll();
// contentPane.getChildren().clear();
// contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString());
// contentPane.getChildren()
// .addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl)));
// } catch (javafx.fxml.LoadException e) {
// System.out.println("[Controller] FXML load exception");
// } catch (IOException e) {
// System.out.println("[Controller] IO exception");
// } catch (NullPointerException e) {
//// System.out.println("[Controller] Null Pointer Exception");
// }
// }
//
// @Override
// public void initialize(URL location, ResourceBundle resources) {
// if (ClientState.isHost()) {
// lobbyIpText.setText("Lobby Host IP: " + ClientState.getHostIp());
// readyButton.setDisable(false);
// }
// else {
// lobbyIpText.setText("Connected to IP: " + ClientState.getHostIp());
// readyButton.setDisable(true);
// }
//
// // put all javafx objects in lists, so we can iterate though conveniently
// imageViews = new ArrayList<>();
// Collections.addAll(imageViews, firstImageView, secondImageView, thirdImageView, fourthImageView,
// fifthImageView, sixthImageView, seventhImageView, eighthImageView);
// listViews = new ArrayList<>();
// Collections.addAll(listViews, firstListView, secondListView, thirdListView, fourthListView, fifthListView,
// sixthListView, seventhListView, eighthListView);
// competitors = new ArrayList<>();
// Collections.addAll(competitors, firstCompetitor, secondCompetitor, thirdCompetitor,
// fourthCompetitor, fifthCompetitor, sixthCompetitor, seventhCompetitor, eighthCompetitor);
//
// initialiseListView();
// initialiseImageView(); // parrot gif init
//
// // set up client state query thread, so that when it receives the race-started packet
// // it can switch to the race view
// ClientStateQueryingRunnable clientStateQueryingRunnable = new ClientStateQueryingRunnable();
// clientStateQueryingRunnable.addObserver(this);
// Thread clientStateQueryingThread = new Thread(clientStateQueryingRunnable, "Client State querying thread");
// clientStateQueryingThread.setDaemon(true);
// clientStateQueryingThread.start();
// }
//
// /**
// * Observers "ClientStateQueryingRunnable".
// * When the clients state has been marked to "race start", the querying thread
// * will notify this lobby to change the view
// * @param o
// * @param arg
// */
// @Override
// public void update(Observable o, Object arg) {
// Platform.runLater(new Runnable() {
// @Override
// public void run() {
// if (arg.equals("game started") && !switchedPane) {
// switchToRaceView();
// }
// if (arg.equals(("update players"))) {
// initialiseListView();
// }
// }
// });
// }
//
// /**
// * Reset all ListViews and ImageViews according to the current competitors
// */
// private void initialiseListView() {
// listViews.forEach(listView -> listView.getItems().clear());
// imageViews.forEach(gif -> gif.setVisible(false));
// competitors.forEach(ol -> ol.removeAll());
//
// List<Integer> ids = new ArrayList<>(ClientState.getBoats().keySet());
// for (int i = 0; i < ids.size(); i++) {
// competitors.get(i).add(ClientState.getBoats().get(ids.get(i)).getBoatName());
// listViews.get(i).setItems(competitors.get(i));
// imageViews.get(i).setVisible(true);
// }
// }
//
// /**
// * Loads preset images into imageViews
// */
// private void initialiseImageView() {
// for (int i = 0; i < MAX_NUM_PLAYERS; i++) {
// imageViews.get(i).setImage(new Image(getClass().getResourceAsStream("/pics/sail.png")));
// }
//// Image image1 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
//// firstImageView.setImage(image1);
//// Image image2 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
//// secondImageView.setImage(image2);
//// Image image3 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
//// thirdImageView.setImage(image3);
//// Image image4 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
//// fourthImageView.setImage(image4);
//// Image image5 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
//// fifthImageView.setImage(image5);
//// Image image6 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
//// sixthImageView.setImage(image6);
//// Image image7 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
//// seventhImageView.setImage(image7);
//// Image image8 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
//// eighthImageView.setImage(image8);
// }
//
// @FXML
// public void leaveLobbyButtonPressed() {
// if (ClientState.isHost()) {
// GameState.setCurrentStage(GameStages.CANCELLED);
// mainServerThread.terminate();
// }
// ClientState.setConnectedToHost(false);
// controller.setUpStartScreen();
// }
//
// @FXML
// public void readyButtonPressed() {
// GameState.setCurrentStage(GameStages.RACING);
// mainServerThread.startGame();
// }
//
//
// private void switchToRaceView() {
// if (!switchedPane) {
// switchedPane = true;
// setContentPane("/views/RaceView.fxml");
// }
// }
//
// public void setMainServerThread(MainServerThread mainServerThread) {
// this.mainServerThread = mainServerThread;
// }
//
// public void setController(Controller controller) {
// this.controller = controller;
// }
//}
@@ -1,668 +0,0 @@
//package seng302.controllers;
//
//import javafx.animation.KeyFrame;
//import javafx.animation.Timeline;
//import javafx.collections.FXCollections;
//import javafx.collections.ObservableList;
//import javafx.fxml.FXML;
//import javafx.fxml.FXMLLoader;
//import javafx.geometry.Point2D;
//import javafx.scene.Scene;
//import javafx.scene.chart.LineChart;
//import javafx.scene.chart.NumberAxis;
//import javafx.scene.chart.XYChart;
//import javafx.scene.chart.XYChart.Series;
//import javafx.scene.control.Button;
//import javafx.scene.control.CheckBox;
//import javafx.scene.control.ComboBox;
//import javafx.scene.control.Slider;
//import javafx.scene.layout.AnchorPane;
//import javafx.scene.layout.Pane;
//import javafx.scene.layout.VBox;
//import javafx.scene.paint.Color;
//import javafx.scene.paint.Paint;
//import javafx.scene.shape.Line;
//import javafx.scene.text.Text;
//import javafx.stage.Stage;
//import javafx.stage.StageStyle;
//import javafx.util.Duration;
//import javafx.util.StringConverter;
//import seng302.client.ClientPacketParser;
//import seng302.utilities.GeoUtility;
//import seng302.controllers.annotations.Annotation;
//import seng302.controllers.annotations.ImportantAnnotationController;
//import seng302.controllers.annotations.ImportantAnnotationDelegate;
//import seng302.controllers.annotations.ImportantAnnotationsState;
//import seng302.fxObjects.BoatGroup;
//import seng302.fxObjects.MarkGroup;
//import seng302.models.*;
//import seng302.models.mark.GateMark;
//import seng302.models.mark.Mark;
//import seng302.models.mark.SingleMark;
//import seng302.models.stream.XMLParser;
//
//import java.io.IOException;
//import java.util.*;
//import seng302.models.stream.XMLParser.RaceXMLObject.Participant;
//import java.util.stream.Collectors;
//
///**
// * Created by ptg19 on 29/03/17.
// */
//public class RaceViewController extends Thread implements ImportantAnnotationDelegate {
//
// @FXML
// private Text windSpeedText;
// @FXML
// private LineChart raceSparkLine;
// @FXML
// private NumberAxis sparklineYAxis;
// @FXML
// private VBox positionVbox;
// @FXML
// private CheckBox toggleFps;
// @FXML
// private Text timerLabel;
// @FXML
// private AnchorPane contentAnchorPane;
// @FXML
// private Text windArrowText, windDirectionText;
// @FXML
// private Slider annotationSlider;
// @FXML
// private Button selectAnnotationBtn;
// @FXML
// private ComboBox boatSelectionComboBox;
// @FXML
// private CanvasController includedCanvasController;
//
// private static ArrayList<Yacht> startingBoats = new ArrayList<>();
// private boolean displayFps;
// private Timeline timerTimeline;
// private Stage stage;
// private static HashMap<Integer, Series<String, Double>> sparkLineData = new HashMap<>();
// private static ArrayList<Yacht> racingBoats = new ArrayList<>();
// private ImportantAnnotationsState importantAnnotations;
// private Yacht selectedBoat;
//
// public void initialize() {
// // Load a default important annotation state
// importantAnnotations = new ImportantAnnotationsState();
//
// //Formatting the y axis of the sparkline
// raceSparkLine.getYAxis().setRotate(180);
// raceSparkLine.getYAxis().setTickLabelRotation(180);
// raceSparkLine.getYAxis().setTranslateX(-5);
// raceSparkLine.getYAxis().setAutoRanging(false);
// sparklineYAxis.setTickMarkVisible(false);
// startingBoats = new ArrayList<>(ClientPacketParser.getBoats().values());
//
// includedCanvasController.setup(this);
// includedCanvasController.initializeCanvas();
// initializeUpdateTimer();
// initialiseFPSCheckBox();
// initialiseAnnotationSlider();
// initialiseBoatSelectionComboBox();
// includedCanvasController.timer.start();
// selectAnnotationBtn.setOnAction(event -> loadSelectAnnotationView());
//
// }
//
//
// /**
// * The important annotations have been changed, update this view
// *
// * @param importantAnnotationsState The current state of the selected annotations
// */
// public void importantAnnotationsChanged(ImportantAnnotationsState importantAnnotationsState) {
// this.importantAnnotations = importantAnnotationsState;
// setAnnotations((int) annotationSlider.getValue()); // Refresh the displayed annotations
// }
//
//
// /**
// * Loads the "select annotations" view in a new window
// */
// private void loadSelectAnnotationView() {
// try {
// FXMLLoader fxmlLoader = new FXMLLoader();
// Stage stage = new Stage();
//
// // Set controller
// ImportantAnnotationController controller = new ImportantAnnotationController(this,
// stage);
// fxmlLoader.setController(controller);
//
// // Load FXML and set CSS
// fxmlLoader
// .setLocation(getClass().getResource("/views/importantAnnotationSelectView.fxml"));
// Scene scene = new Scene(fxmlLoader.load(), 469, 298);
// scene.getStylesheets().add(getClass().getResource("/css/master.css").toString());
// stage.initStyle(StageStyle.UNDECORATED);
// stage.setScene(scene);
// stage.show();
//
// controller.loadState(importantAnnotations);
//
// } catch (IOException e) {
// System.out.println("[RaceViewController] IO exception");
// }
// }
//
//
// private void initialiseFPSCheckBox() {
// displayFps = true;
// toggleFps.selectedProperty().addListener(
// (observable, oldValue, newValue) -> displayFps = !displayFps);
// }
//
// private void initialiseAnnotationSlider() {
// annotationSlider.setLabelFormatter(new StringConverter<Double>() {
// @Override
// public String toString(Double n) {
// if (n == 0) {
// return "None";
// }
// if (n == 1) {
// return "Important";
// }
// if (n == 2) {
// return "All";
// }
//
// return "All";
// }
//
// @Override
// public Double fromString(String s) {
// switch (s) {
// case "None":
// return 0d;
// case "Important":
// return 1d;
// case "All":
// return 2d;
//
// default:
// return 2d;
// }
// }
// });
//
// annotationSlider.valueProperty().addListener((obs, oldval, newVal) ->
// setAnnotations((int) annotationSlider.getValue()));
//
// annotationSlider.setValue(2);
// }
//
//
// /**
// * Used to add any new boats into the race that may have started late or not have had data received yet
// */
// void updateSparkLine(){
// // Collect the racing boats that aren't already in the chart
// ArrayList<Yacht> sparkLineCandidates = startingBoats.stream().filter(yacht -> !sparkLineData.containsKey(yacht.getSourceId())
// && yacht.getPosition() != null & yacht.getPosition() != "-").collect(Collectors.toCollection(ArrayList::new));
//
// // Obtain the qualifying boats to set the max on the Y axis
// racingBoats = startingBoats.stream().filter(yacht ->
// yacht.getPosition() != null & yacht.getPosition() != "-").collect(Collectors.toCollection(ArrayList::new));
// sparklineYAxis.setUpperBound(racingBoats.size() + 1);
//
// // Create a new data series for new boats
// sparkLineCandidates.stream().filter(yacht -> yacht.getPosition() != null).forEach(yacht -> {
// Series<String, Double> yachtData = new Series<>();
// yachtData.setName(yacht.getBoatName());
// yachtData.getData().add(new XYChart.Data<>(Integer.toString(yacht.getLegNumber()), 1 + racingBoats.size() - Double.parseDouble(yacht.getPosition())));
// sparkLineData.put(yacht.getSourceId(), yachtData);
// });
//
// // 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());
// Collections.sort(positions, (o1, o2) -> {
// Integer leg1 = Integer.parseInt(o1.getData().get(o1.getData().size()-1).getXValue());
// Integer leg2 = Integer.parseInt(o2.getData().get(o2.getData().size()-1).getXValue());
// if (leg2 < leg1){
// return 1;
// } else {
// return -1;
// }
// });
//
// // Adds the new data series to the sparkline (and set the colour of the series)
// raceSparkLine.setCreateSymbols(false);
// positions.stream().filter(spark -> !raceSparkLine.getData().contains(spark)).forEach(spark -> {
// raceSparkLine.getData().add(spark);
// spark.getNode().lookup(".chart-series-line").setStyle("-fx-stroke:" + getBoatColorAsRGB(spark.getName()));
// });
// }
//
//
// /**
// * Updates the yachts sparkline of the desired boat and using the new leg number
// * @param yacht The yacht to be updated on the sparkline
// * @param legNumber the leg number that the position will be assigned to
// */
// public static void updateYachtPositionSparkline(Yacht yacht, Integer legNumber){
// XYChart.Series<String, Double> positionData = sparkLineData.get(yacht.getSourceId());
// positionData.getData().add(new XYChart.Data<>(Integer.toString(legNumber), 1 + racingBoats.size() - Double.parseDouble(yacht.getPosition())));
// }
//
//
// /**
// * gets the rgb string of the boats colour to use for the chart via css
// * @param boatName boat passed in to get the boats colour
// * @return the colour as an rgb string
// */
// private String getBoatColorAsRGB(String boatName){
// Color color = Color.WHITE;
// for (Yacht yacht: startingBoats){
// if (Objects.equals(yacht.getBoatName(), boatName)){
// color = yacht.getColour();
// }
// }
// if (color == null){
// return String.format( "#%02X%02X%02X",255,255,255);
// }
// return String.format( "#%02X%02X%02X",
// (int)( color.getRed() * 255 ),
// (int)( color.getGreen() * 255 ),
// (int)( color.getBlue() * 255 ) );
// }
//
//
// /**
// * Initalises a timer which updates elements of the RaceView such as wind direction, boat
// * orderings etc.. which are dependent on the info from the stream parser constantly.
// * Updates of each of these attributes are called ONCE EACH SECOND
// */
// private void initializeUpdateTimer() {
// timerTimeline = new Timeline();
// timerTimeline.setCycleCount(Timeline.INDEFINITE);
// // Run timer update every second
// timerTimeline.getKeyFrames().add(
// new KeyFrame(Duration.seconds(1),
// event -> {
// updateRaceTime();
// updateWindDirection();
//// updateOrder();
// updateBoatSelectionComboBox();
// updateOrder();
// })
// );
//
// // Start the timer
// timerTimeline.playFromStart();
// }
//
//
// /**
// * Iterates over all corners until ones SeqID matches with the boats current leg number.
// * Then it gets the compoundMarkID of that corner and uses it to fetch the appropriate mark
// * Returns null if no next mark found.
// * @param bg The BoatGroup to find the next mark of
// * @return The next Mark or null if none found
// */
// private Mark getNextMark(BoatGroup bg) {
// Integer legNumber = bg.getBoat().getLegNumber();
//
// List<XMLParser.RaceXMLObject.Corner> markSequence = ClientPacketParser.getXmlObject()
// .getRaceXML().getCompoundMarkSequence();
//
// if (legNumber == 0) {
// return null;
// } else if (legNumber == markSequence.size() - 1) {
// return null;
// }
//
// for (XMLParser.RaceXMLObject.Corner corner : markSequence) {
// if (legNumber + 2 == corner.getSeqID()) {
// Integer thisCompoundMarkID = corner.getCompoundMarkID();
//
// for (Mark mark : ClientPacketParser.getXmlObject().getRaceXML()
// .getAllCompoundMarks()) {
// if (mark.getCompoundMarkID() == thisCompoundMarkID) {
// return mark;
// }
// }
// }
// }
//
// return null;
// }
//
//
// /**
// * Updates the wind direction arrow and text as from info from the ClientPacketParser
// */
// private void updateWindDirection() {
// windDirectionText.setText(String.format("%.1f°", ClientPacketParser.getWindDirection()));
// windArrowText.setRotate(ClientPacketParser.getWindDirection());
// windSpeedText.setText(String.format("%.1f Knots", ClientPacketParser.getWindSpeed()));
// }
//
//
// /**
// * Updates the clock for the race
// */
// private void updateRaceTime() {
// if (ClientPacketParser.isRaceFinished()) {
// timerLabel.setFill(Color.RED);
// timerLabel.setText("Race Finished!");
// } else {
// timerLabel.setText(getTimeSinceStartOfRace());
// }
// }
//
//
// /**
// * Grabs the boats currently in the race as from the ClientPacketParser and sets them to be selectable
// * in the boat selection combo box
// */
// private void updateBoatSelectionComboBox() {
// ObservableList<Yacht> observableBoats = FXCollections
// .observableArrayList(ClientPacketParser.getBoatsPos().values());
// boatSelectionComboBox.setItems(observableBoats);
// }
//
//
// /**
// * Updates the order of the boats as from the ClientPacketParser and sets them in the boat order
// * section
// */
// private void updateOrder() {
// positionVbox.getChildren().clear();
// positionVbox.getChildren().removeAll();
// positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString());
//
// // list of racing boat id
// ArrayList<Participant> participants = ClientPacketParser.getXmlObject().getRaceXML()
// .getParticipants();
// ArrayList<Integer> participantIDs = new ArrayList<>();
// for (Participant p : participants) {
// participantIDs.add(p.getsourceID());
// }
//
// if (ClientPacketParser.isRaceStarted()) {
// /*
// for (Yacht boat : ClientPacketParser.getBoatsPos().values()) {
// System.out.println("Hi tjere" + boat.getBoatName());
// if (participantIDs.contains(boat.getSourceId()) || true
// ) { // check if the boat is racing
// if (boat.getBoatStatus() == 69) { // 3 is finish status
// Text textToAdd = new Text(boat.getPosition() + ". " +
// boat.getShortName() + " (Finished)");
// textToAdd.setFill(Paint.valueOf("#d3d3d3"));
// positionVbox.getChildren().add(textToAdd);
//
// } else {
// Text textToAdd = new Text(boat.getPosition() + ". " +
// boat.getShortName() + " ");
// textToAdd.setFill(Paint.valueOf("#d3d3d3"));
// textToAdd.setStyle("");
// positionVbox.getChildren().add(textToAdd);
// System.out.println("Adding " + textToAdd.getText());
// }
// }
// }
// */
// for (Yacht boat : ClientPacketParser.getBoats().values()){
// Text textToAdd = new Text(boat.getSourceId() + ". " + boat.getShortName() + " ");
// textToAdd.setFill(Paint.valueOf("#d3d3d3"));
// textToAdd.setStyle("");
// positionVbox.getChildren().add(textToAdd);
// }
// } else {
// for (Yacht boat : ClientPacketParser.getBoats().values()) {
// if (participantIDs.contains(boat.getSourceId())) { // check if the boat is racing
// Text textToAdd = new Text(boat.getPosition() + ". " +
// boat.getShortName() + " ");
// textToAdd.setFill(Paint.valueOf("#d3d3d3"));
// textToAdd.setStyle("");
// positionVbox.getChildren().add(textToAdd);
// }
// }
// }
// }
//
//
// private void updateLaylines(BoatGroup bg) {
//
// Mark nextMark = getNextMark(bg);
// Boolean isUpwind = null;
// // Can only calc leg direction if there is a next mark and it is a gate mark
// if (nextMark != null) {
// if (nextMark instanceof GateMark) {
// if (bg.isUpwindLeg(includedCanvasController, nextMark)) {
// isUpwind = true;
// } else {
// isUpwind = false;
// }
//
// for(MarkGroup mg : includedCanvasController.getMarkGroups()) {
//
// mg.removeLaylines();
//
// if (mg.getMainMark().getId() == nextMark.getId()) {
//
// SingleMark singleMark1 = ((GateMark) nextMark).getSingleMark1();
// SingleMark singleMark2 = ((GateMark) nextMark).getSingleMark2();
// Point2D markPoint1 = includedCanvasController.findScaledXY(singleMark1.getLatitude(), singleMark1.getLongitude());
// Point2D markPoint2 = includedCanvasController.findScaledXY(singleMark2.getLatitude(), singleMark2.getLongitude());
// HashMap<Double, Double> angleAndSpeed;
// if (isUpwind) {
// angleAndSpeed = PolarTable
// .getOptimalUpwindVMG(ClientPacketParser.getWindSpeed());
// } else {
// angleAndSpeed = PolarTable
// .getOptimalDownwindVMG(ClientPacketParser.getWindSpeed());
// }
//
// Double resultingAngle = angleAndSpeed.keySet().iterator().next();
//
//
// Point2D boatCurrentPos = new Point2D(bg.getBoatLayoutX(), bg.getBoatLayoutY());
// Point2D gateMidPoint = markPoint1.midpoint(markPoint2);
// Integer lineFuncResult = GeoUtility.lineFunction(boatCurrentPos, gateMidPoint, markPoint2);
// Line rightLayline = new Line();
// Line leftLayline = new Line();
// if (lineFuncResult == 1) {
// rightLayline = makeRightLayline(markPoint2, 180 - resultingAngle,
// ClientPacketParser
// .getWindDirection());
// leftLayline = makeLeftLayline(markPoint1, 180 - resultingAngle,
// ClientPacketParser
// .getWindDirection());
// } else if (lineFuncResult == -1) {
// rightLayline = makeRightLayline(markPoint1, 180 - resultingAngle,
// ClientPacketParser
// .getWindDirection());
// leftLayline = makeLeftLayline(markPoint2, 180 - resultingAngle,
// ClientPacketParser
// .getWindDirection());
// }
//
// leftLayline.setStrokeWidth(0.5);
// leftLayline.setStroke(bg.getBoat().getColour());
//
// rightLayline.setStrokeWidth(0.5);
// rightLayline.setStroke(bg.getBoat().getColour());
//
// bg.setLaylines(leftLayline, rightLayline);
// mg.addLaylines(leftLayline, rightLayline);
//
// }
// }
// }
// }
// }
//
//
// private Point2D getPointRotation(Point2D ref, Double distance, Double angle){
// Double newX = ref.getX() + (ref.getX() + distance -ref.getX())*Math.cos(angle) - (ref.getY() + distance -ref.getY())*Math.sin(angle);
// Double newY = ref.getY() + (ref.getX() + distance -ref.getX())*Math.sin(angle) + (ref.getY() + distance -ref.getY())*Math.cos(angle);
//
// return new Point2D(newX, newY);
// }
//
//
// public Line makeLeftLayline(Point2D startPoint, Double layLineAngle, Double baseAngle) {
//
// Point2D ep = getPointRotation(startPoint, 50.0, baseAngle + layLineAngle);
// Line line = new Line(startPoint.getX(), startPoint.getY(), ep.getX(), ep.getY());
// return line;
//
// }
//
//
// public Line makeRightLayline(Point2D startPoint, Double layLineAngle, Double baseAngle) {
//
// Point2D ep = getPointRotation(startPoint, 50.0, baseAngle - layLineAngle);
// Line line = new Line(startPoint.getX(), startPoint.getY(), ep.getX(), ep.getY());
// return line;
//
// }
//
//
// /**
// * Initialised the combo box with any boats currently in the race and adds the required listener
// * for the combobox to take action upon selection
// */
// private void initialiseBoatSelectionComboBox() {
// updateBoatSelectionComboBox();
// boatSelectionComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
// //This listener is fired whenever the combo box changes. This means when the values are updated
// //We dont want to set the selected value if the values are updated but nothing clicked (null)
// if (newValue != null && newValue != selectedBoat) {
// Yacht thisYacht = (Yacht) newValue;
// setSelectedBoat(thisYacht);
// }
// });
// }
//
//
// /**
// * Display the list of boats in the order they finished the race
// */
// private void loadRaceResultView() {
// FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/FinishView.fxml"));
//
// try {
// contentAnchorPane.getChildren().removeAll();
// contentAnchorPane.getChildren().clear();
// contentAnchorPane.getChildren().addAll((Pane) loader.load());
//
// } catch (javafx.fxml.LoadException e) {
// System.err.println(e.getCause());
// } catch (IOException e) {
// System.err.println(e);
// }
// }
//
//
// /**
// * Convert seconds to a string of the format mm:ss
// *
// * @param time the time in seconds
// * @return a formatted string
// */
// public String convertTimeToMinutesSeconds(int time) {
// if (time < 0) {
// return String.format("-%02d:%02d", (time * -1) / 60, (time * -1) % 60);
// }
// return String.format("%02d:%02d", time / 60, time % 60);
// }
//
// private String getTimeSinceStartOfRace() {
// String timerString = "0:00";
// if (ClientPacketParser.getTimeSinceStart() > 0) {
// String timerMinute = Long.toString(ClientPacketParser.getTimeSinceStart() / 60);
// String timerSecond = Long.toString(ClientPacketParser.getTimeSinceStart() % 60);
// if (timerSecond.length() == 1) {
// timerSecond = "0" + timerSecond;
// }
// timerString = "-" + timerMinute + ":" + timerSecond;
// } else {
// String timerMinute = Long.toString(-1 * ClientPacketParser.getTimeSinceStart() / 60);
// String timerSecond = Long.toString(-1 * ClientPacketParser.getTimeSinceStart() % 60);
// if (timerSecond.length() == 1) {
// timerSecond = "0" + timerSecond;
// }
// timerString = timerMinute + ":" + timerSecond;
// }
// return timerString;
// }
//
//
// boolean isDisplayFps() {
// return displayFps;
// }
//
// private void setAnnotations(Integer annotationLevel) {
// switch (annotationLevel) {
// // No Annotations
// case 0:
// for (BoatGroup bg : includedCanvasController.getBoatGroups()) {
// bg.setVisibility(false, false, false, false, false, false);
// }
// break;
// // Important Annotations
// case 1:
// for (BoatGroup bg : includedCanvasController.getBoatGroups()) {
// bg.setVisibility(
// importantAnnotations.getAnnotationState(Annotation.NAME),
// importantAnnotations.getAnnotationState(Annotation.SPEED),
// importantAnnotations.getAnnotationState(Annotation.ESTTIMETONEXTMARK),
// importantAnnotations.getAnnotationState(Annotation.LEGTIME),
// importantAnnotations.getAnnotationState(Annotation.TRACK),
// importantAnnotations.getAnnotationState(Annotation.WAKE)
// );
// }
// break;
// // All Annotations
// case 2:
// for (BoatGroup bg : includedCanvasController.getBoatGroups()) {
// bg.setVisibility(true, true, true, true, true, true);
// }
// break;
// }
// }
//
//
// /**
// * Sets all the annotations of the selected boat to be visible and all others to be hidden
// *
// * @param yacht The yacht for which we want to view all annotations
// */
// private void setSelectedBoat(Yacht yacht) {
// for (BoatGroup bg : includedCanvasController.getBoatGroups()) {
// //We need to iterate over all race groups to get the matching boat group belonging to this boat if we
// //are to toggle its annotations, there is no other backwards knowledge of a yacht to its boatgroup.
// if (bg.getBoat().getHullID().equals(yacht.getHullID())) {
// updateLaylines(bg);
// bg.setIsSelected(true);
// selectedBoat = yacht;
// } else {
// bg.setIsSelected(false);
// }
// }
// }
//
// void setStage(Stage stage) {
// this.stage = stage;
// }
//
// Stage getStage() {
// return stage;
// }
//
// /**
// * Used for when the boat attempts to add data to the sparkline (first checks if the sparkline contains info on it)
// * @param yachtId
// * @return
// */
// public static boolean sparkLineStatus(Integer yachtId) {
// return sparkLineData.containsKey(yachtId);
// }
//
//}
@@ -1,164 +0,0 @@
//package seng302.controllers;
//
//import java.net.Inet4Address;
//import java.net.NetworkInterface;
//import java.util.Enumeration;
//import javafx.fxml.FXML;
//import javafx.fxml.FXMLLoader;
//import javafx.scene.control.Alert;
//import javafx.scene.control.Alert.AlertType;
//import javafx.scene.control.TextField;
//import javafx.scene.layout.AnchorPane;
//import javafx.scene.layout.GridPane;
//import javafx.scene.layout.Pane;
//import seng302.client.ClientState;
//import seng302.client.ClientToServerThread;
//import seng302.gameServer.GameState;
//import seng302.gameServer.MainServerThread;
//
//import java.io.IOException;
//import java.net.InetAddress;
//import java.net.UnknownHostException;
//
///**
// * A Class describing the actions of the start screen controller
// * Created by wmu16 on 10/07/17.
// */
//public class StartScreenController {
//
// @FXML
// private TextField ipTextField;
// @FXML
// private TextField portTextField;
// @FXML
// private GridPane startScreen2;
//
// private Controller controller;
//
// /**
// * Loads the fxml content into the parent pane
// * @param jfxUrl
// * @return the controller of the fxml
// */
// private Object setContentPane(String jfxUrl) {
// try {
// AnchorPane contentPane = (AnchorPane) startScreen2.getParent();
// contentPane.getChildren().removeAll();
// contentPane.getChildren().clear();
// contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString());
// FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(jfxUrl));
// contentPane.getChildren().addAll((Pane) fxmlLoader.load());
//
// return fxmlLoader.getController();
// } catch (javafx.fxml.LoadException e) {
// System.out.println("[Controller] FXML load exception");
// } catch (IOException e) {
// System.out.println("[Controller] IO exception");
// }
// return null;
// }
//
//
// /**
// * ATTEMPTS TO:
// * Sets up a new game state with your IP address as designated as the host.
// * Starts a thread to listen for incoming connections.
// * Starts a client to server thread and connects to own ip.
// * Switches to the lobby screen
// */
// @FXML
// public void hostButtonPressed() {
// try {
// String ipAddress = InetAddress.getLocalHost().getHostAddress();
// // get the lobby controller so that we can pass the game server thread to it
// new GameState(getLocalHostIp());
// MainServerThread mainServerThread = new MainServerThread();
// ClientState.setHost(true);
// // host will connect and handshake to itself after setting up the server
// // TODO: 24/07/17 wmu16 - Make port number some static global type constant?
// ClientToServerThread clientToServerThread = new ClientToServerThread(ClientState.getHostIp(), 4942);
// ClientState.setConnectedToHost(true);
// controller.setClientToServerThread(clientToServerThread);
// LobbyController lobbyController = (LobbyController) setContentPane("/views/LobbyView.fxml");
// lobbyController.setMainServerThread(mainServerThread);
// lobbyController.setController(controller);
// } catch (Exception e) {
// Alert alert = new Alert(AlertType.ERROR);
// alert.setHeaderText("Cannot host");
// alert.setContentText("Oops, failed to host, try to restart.");
// alert.showAndWait();
// }
//
//
// }
//
// /**
// * ATTEMPTS TO:
// * Connect to an ip address and port using the ip and port specified on start screen.
// * Starts a Client To Server Thread to maintain connection to host.
// * Switch view to lobby view.
// */
// @FXML
// public void connectButtonPressed() {
// // TODO: 10/07/17 wmu16 - Finish function
// try {
// String ipAddress = ipTextField.getText().trim().toLowerCase();
// Integer port = Integer.valueOf(portTextField.getText().trim());
//
// ClientToServerThread clientToServerThread = new ClientToServerThread(ipAddress, port);
// ClientState.setHost(false);
// ClientState.setConnectedToHost(true);
//
// ClientState.setHostIp(ipAddress);
// controller.setClientToServerThread(clientToServerThread);
// LobbyController lobbyController = (LobbyController) setContentPane("/views/LobbyView.fxml");
// lobbyController.setController(controller);
// } catch (Exception e) {
// Alert alert = new Alert(AlertType.ERROR);
// alert.setHeaderText("Cannot reach the host");
// alert.setContentText("Please check your host IP address.");
// alert.showAndWait();
// }
// }
//
// public void setController(Controller controller) {
// this.controller = controller;
// }
//
// /**
// * Gets the local host ip address and sets this ip to ClientState.
// * Only runs by the host.
// *
// * @return the localhost ip address
// */
// private String getLocalHostIp() {
// String ipAddress = null;
// try {
// Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
// while (e.hasMoreElements()) {
// NetworkInterface ni = e.nextElement();
// if (ni.isLoopback())
// continue;
// if(ni.isPointToPoint())
// continue;
// if(ni.isVirtual())
// continue;
//
// Enumeration<InetAddress> addresses = ni.getInetAddresses();
// while(addresses.hasMoreElements()) {
// InetAddress address = addresses.nextElement();
// if(address instanceof Inet4Address) { // skip all ipv6
// ipAddress = address.getHostAddress();
// }
// }
// }
// } catch (Exception e) {
// System.out.println("[StartScreenController] Exception");
// }
// if (ipAddress == null) {
// System.out.println("[HOST] Cannot obtain local host ip address.");
// }
// ClientState.setHostIp(ipAddress);
// return ipAddress;
// }
//}
+7 -9
View File
@@ -13,7 +13,7 @@ import javafx.beans.property.ReadOnlyLongProperty;
import javafx.beans.property.ReadOnlyLongWrapper;
import javafx.scene.paint.Color;
import seng302.gameServer.GameState;
import seng302.model.mark.Mark;
import seng302.model.mark.CompoundMark;
/**
* Yacht class for the racing boat.
@@ -53,7 +53,6 @@ public class Yacht {
private final Double TURN_STEP = 5.0;
private Double lastHeading;
private Boolean sailIn;
private String position;
private GeoPoint location;
private Integer boatStatus;
private Double velocity;
@@ -66,8 +65,8 @@ public class Yacht {
// private ReadOnlyDoubleWrapper headingProperty = new ReadOnlyDoubleWrapper();
// private ReadOnlyDoubleWrapper latitudeProperty = new ReadOnlyDoubleWrapper();
// private ReadOnlyDoubleWrapper longitudeProperty = new ReadOnlyDoubleWrapper();
private Mark lastMarkRounded;
private Mark nextMark;
private CompoundMark lastMarkRounded;
private CompoundMark nextMark;
private Integer positionInt = 0;
private Color colour;
@@ -122,7 +121,6 @@ public class Yacht {
this.shortName = shortName;
this.boatName = boatName;
this.country = country;
this.position = "-";
this.sailIn = false;
this.location = new GeoPoint(57.670341, 11.826856);
this.heading = 120.0; //In degrees
@@ -373,19 +371,19 @@ public class Yacht {
return markRoundTime;
}
public Mark getLastMarkRounded() {
public CompoundMark getLastMarkRounded() {
return lastMarkRounded;
}
public void setLastMarkRounded(Mark lastMarkRounded) {
public void setLastMarkRounded(CompoundMark lastMarkRounded) {
this.lastMarkRounded = lastMarkRounded;
}
public void setNextMark(Mark nextMark) {
public void setNextMark(CompoundMark nextMark) {
this.nextMark = nextMark;
}
public Mark getNextMark(){
public CompoundMark getNextMark(){
return nextMark;
}
@@ -29,8 +29,8 @@ public class Simulator extends Observable implements Runnable {
setLegs();
// set start line's coordinate to boats
Double startLat = course.get(0).getCompoundMark().getMark1().getLat();
Double startLng = course.get(0).getCompoundMark().getMark1().getLng();
Double startLat = course.get(0).getCompoundMark().getSubMark(1).getLat();
Double startLng = course.get(0).getCompoundMark().getSubMark(1).getLng();
for (Boat boat : boats) {
boat.setLat(startLat);
boat.setLng(startLng);
@@ -77,7 +77,7 @@ public class Simulator extends Observable implements Runnable {
boat.move(boat.getLastPassedCorner().getBearingToNextCorner(), duration);
GeoPoint boatPos = new GeoPoint(boat.getLat(), boat.getLng());
GeoPoint lastMarkPos = boat.getLastPassedCorner().getCompoundMark().getMark1();
GeoPoint lastMarkPos = boat.getLastPassedCorner().getCompoundMark().getSubMark(1);
double distanceFromLastMark = GeoUtility.getDistance(boatPos, lastMarkPos);
// if a boat passes its heading mark
@@ -94,13 +94,13 @@ public class Simulator extends Observable implements Runnable {
// move compensate distance for the mark just passed
GeoPoint pos = GeoUtility.getGeoCoordinate(
boat.getLastPassedCorner().getCompoundMark().getMark1(),
boat.getLastPassedCorner().getCompoundMark().getSubMark(1),
boat.getLastPassedCorner().getBearingToNextCorner(),
compensateDistance);
boat.setLat(pos.getLat());
boat.setLng(pos.getLng());
distanceFromLastMark = GeoUtility.getDistance(new GeoPoint(boat.getLat(), boat.getLng()),
boat.getLastPassedCorner().getCompoundMark().getMark1());
boat.getLastPassedCorner().getCompoundMark().getSubMark(1));
}
}
return 0;
@@ -115,15 +115,15 @@ public class Simulator extends Observable implements Runnable {
// get the bearing from one mark to the next heading mark
for (int i = 0; i < course.size() - 1; i++) {
Mark mark1 = course.get(i).getCompoundMark().getMark1();
Mark mark2 = course.get(i + 1).getCompoundMark().getMark1();
Mark mark1 = course.get(i).getCompoundMark().getSubMark(1);
Mark mark2 = course.get(i + 1).getCompoundMark().getSubMark(1);
course.get(i).setDistanceToNextCorner(GeoUtility.getDistance(mark1, mark2));
course.get(i).setNextCorner(course.get(i + 1));
course.get(i).setBearingToNextCorner(
GeoUtility.getBearing(course.get(i).getCompoundMark().getMark1(),
course.get(i + 1).getCompoundMark().getMark1()));
GeoUtility.getBearing(course.get(i).getCompoundMark().getSubMark(1),
course.get(i + 1).getCompoundMark().getSubMark(1)));
}
}
@@ -68,7 +68,7 @@ public class GeoUtility {
double x = Math.cos(Math.toRadians(p1.getLat())) * Math.sin(Math.toRadians(p2.getLat()))
- Math.sin(Math.toRadians(p1.getLat())) * Math.cos(Math.toRadians(p2.getLat())) * Math.cos(dLon);
return Math.toDegrees(Math.atan2(y, x));
return Math.atan2(y, x);
}
/**
@@ -198,7 +198,7 @@ public class XMLParser {
new Limit(
XMLParser.getNodeAttributeInt(limitNode, "SeqID"),
XMLParser.getNodeAttributeDouble(limitNode, "Lat"),
XMLParser.getNodeAttributeDouble(limitNode, "lon")
XMLParser.getNodeAttributeDouble(limitNode, "Lon")
)
);
}
@@ -107,19 +107,8 @@ public class ClientToServerThread implements Runnable {
int sync1;
int sync2;
// TODO: 14/07/17 wmu16 - Work out how to fix this while loop
while(socketOpen) { /**REMOVED SOMETHING HERE ClientState.isConnectedToHost() */
System.out.println("socket.isConnected() = " + socket.isConnected());
while(socketOpen) {
try {
//Perform a write if it is time to as delegated by the MainServerThread
// if (updateClient) {
// // TODO: 13/07/17 wmu16 - Write out game state - some function that would write all appropriate messages to this output stream
//// try {
//// GameState.outputState(os);
//// } catch (IOException e) {
//// System.out.println("IO error in server thread upon writing to output stream");
//// }
// updateClient = false;
// }
crcBuffer = new ByteArrayOutputStream();
sync1 = readByte();
sync2 = readByte();
@@ -136,9 +125,6 @@ public class ClientToServerThread implements Runnable {
long computedCrc = checksum.getValue();
long packetCrc = Message.bytesToLong(getBytes(4));
if (computedCrc == packetCrc) {
// streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
// for (ClientSocketListener csl : listeners)
// csl.newPacket(new StreamPacket(type, payloadLength, timeStamp, payload));
if (streamPackets.size() > 0) {
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
} else {
@@ -10,20 +10,22 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import seng302.gameServer.GameState;
import seng302.gameServer.MainServerThread;
import seng302.model.RaceState;
import seng302.model.Yacht;
import seng302.model.mark.Mark;
import seng302.model.stream.packets.StreamPacket;
import seng302.model.stream.parser.MarkRoundingData;
import seng302.model.stream.parser.PositionUpdateData;
import seng302.model.stream.parser.PositionUpdateData.DeviceType;
import seng302.model.stream.parser.RaceStatusData;
import seng302.utilities.StreamParser;
import seng302.model.stream.xml.parser.RaceXMLData;
import seng302.model.stream.xml.parser.RegattaXMLData;
import seng302.server.messages.BoatActionMessage;
import seng302.server.messages.BoatActionType;
import seng302.utilities.StreamParser;
import seng302.utilities.XMLParser;
import seng302.visualiser.controllers.LobbyController;
import seng302.visualiser.controllers.LobbyController.CloseStatus;
@@ -47,11 +49,14 @@ public class GameClient {
private ObservableList<String> lobbyList = FXCollections.observableArrayList();
private long lastSendingTime;
private int KEY_STROKE_SENDING_FREQUENCY = 50;
public GameClient(Pane holder) {
this.holderPane = holder;
}
public void runAsClient (String ipAddress, Integer portNumber) {
public void runAsClient(String ipAddress, Integer portNumber) {
try {
socketThread = new ClientToServerThread(ipAddress, portNumber);
} catch (IOException ioe) {
@@ -66,7 +71,7 @@ public class GameClient {
socketThread.addStreamObserver(this::parsePackets);
}
public void runAsHost (String ipAddress, Integer portNumber) {
public void runAsHost(String ipAddress, Integer portNumber) {
server = new MainServerThread();
try {
socketThread = new ClientToServerThread(ipAddress, portNumber);
@@ -87,7 +92,7 @@ public class GameClient {
});
}
private void loadStartScreen () {
private void loadStartScreen() {
socketThread.setSocketToClose();
socketThread = null;
if (server != null) {
@@ -95,7 +100,8 @@ public class GameClient {
// server.shutDown();
server = null;
}
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/views/StartScreenView.fxml"));
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("/views/StartScreenView.fxml"));
try {
holderPane.getChildren().clear();
holderPane.getChildren().add(fxmlLoader.load());
@@ -106,10 +112,11 @@ public class GameClient {
/**
* Loads a view of the lobby into the clients pane
*
* @param lobbyView fxml file for the desired lobby
* @return the lobby controller.
*/
private LobbyController loadLobby (String lobbyView) {
private LobbyController loadLobby(String lobbyView) {
FXMLLoader fxmlLoader = new FXMLLoader(GameClient.class.getResource(lobbyView));
try {
holderPane.getChildren().clear();
@@ -120,12 +127,13 @@ public class GameClient {
return fxmlLoader.getController();
}
private void loadRaceView () {
private void loadRaceView() {
// allBoatsMap.forEach((id, boat) -> {
// if (courseData.getParticipants().contains(id))
// racingBoats.put(id, boat);
// });
FXMLLoader fxmlLoader = new FXMLLoader(RaceViewController.class.getResource("/views/RaceView.fxml"));
FXMLLoader fxmlLoader = new FXMLLoader(
RaceViewController.class.getResource("/views/RaceView.fxml"));
// raceView = fxmlLoader.getController();
try {
Node node = fxmlLoader.load();
@@ -136,6 +144,8 @@ public class GameClient {
} catch (IOException e) {
e.printStackTrace();
}
holderPane.getScene().setOnKeyPressed(this::keyPressed);
holderPane.getScene().setOnKeyReleased(this::keyReleased);
raceView = fxmlLoader.getController();
raceView.loadRace(allBoatsMap, courseData, raceState);
}
@@ -201,33 +211,34 @@ public class GameClient {
}
private void startRaceIfAllDataReceived() {
if (allXMLReceived())
if (allXMLReceived() && raceView == null)
loadRaceView();
}
private boolean allXMLReceived () {
private boolean allXMLReceived() {
return courseData != null && allBoatsMap != null && regattaData != null;
}
/**
* Updates the position of a boat. Boat and position are given in the provided data.
* @param positionData
*/
private void updatePosition(PositionUpdateData positionData) {
if (positionData.getType() == DeviceType.YACHT_TYPE) {
if (allXMLReceived() && allBoatsMap.containsKey(positionData.getDeviceId())) {
Yacht yacht = allBoatsMap.get(positionData.getDeviceId());
yacht.updateLocation(positionData.getLat(),
positionData.getLon(), positionData.getHeading(), positionData.getGroundSpeed());
positionData.getLon(), positionData.getHeading(),
positionData.getGroundSpeed());
}
} else if (positionData.getType() == DeviceType.MARK_TYPE) {
Mark mark = courseData.getCompoundMarks().get(positionData.getDeviceId());
//CompoundMark mark = courseData.getCompoundMarks().get(positionData.getDeviceId());
}
}
/**
* Updates the boat as having passed the mark. Boat and mark are given by the ids in the
* provided data.
*
* @param roundingData Contains data for the rounding of a mark.
*/
private void updateMarkRounding(MarkRoundingData roundingData) {
@@ -244,7 +255,7 @@ public class GameClient {
}
}
private void processRaceStatusUpdate (RaceStatusData data) {
private void processRaceStatusUpdate(RaceStatusData data) {
if (allXMLReceived()) {
raceState.updateState(data);
for (long[] boatData : data.getBoatData()) {
@@ -267,49 +278,55 @@ public class GameClient {
}
}
private void close () {
private void close() {
socketThread.setSocketToClose();
}
// /** Handle the key-pressed event from the text field. */
// public void keyPressed(KeyEvent e) {
// BoatActionMessage boatActionMessage;
// switch (e.getCode()){
// case SPACE: // align with vmg
// boatActionMessage = new BoatActionMessage(BoatActionType.VMG);
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
// break;
// case PAGE_UP: // upwind
// boatActionMessage = new BoatActionMessage(BoatActionType.UPWIND);
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
// break;
// case PAGE_DOWN: // downwind
// boatActionMessage = new BoatActionMessage(BoatActionType.DOWNWIND);
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
// break;
// case ENTER: // tack/gybe
// boatActionMessage = new BoatActionMessage(BoatActionType.TACK_GYBE);
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
// break;
// //TODO Allow a zoom in and zoom out methods
// case Z: // zoom in
// System.out.println("Zoom in");
// break;
// case X: // zoom out
// System.out.println("Zoom out");
// break;
// }
// }
// public void keyReleased(KeyEvent e) {
// switch (e.getCode()) {
// //TODO 12/07/17 Determine the sail state and send the appropriate packet (eg. if sails are in, send a sail out packet)
// case SHIFT: // sails in/sails out
// BoatActionMessage boatActionMessage = new BoatActionMessage(BoatActionType.SAILS_IN);
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
// break;
// }
// }
//
// onKeyPressed="#keyPressed" onKeyReleased="#keyReleased"
/**
* Handle the key-pressed event from the text field.
*/
public void keyPressed(KeyEvent e) {
BoatActionMessage boatActionMessage;
long currentTime = System.currentTimeMillis();
if (currentTime - lastSendingTime > KEY_STROKE_SENDING_FREQUENCY) {
lastSendingTime = currentTime;
switch (e.getCode()) {
case SPACE: // align with vmg
boatActionMessage = new BoatActionMessage(BoatActionType.VMG);
socketThread.sendBoatActionMessage(boatActionMessage);
break;
case PAGE_UP: // upwind
boatActionMessage = new BoatActionMessage(BoatActionType.UPWIND);
socketThread.sendBoatActionMessage(boatActionMessage);
break;
case PAGE_DOWN: // downwind
boatActionMessage = new BoatActionMessage(BoatActionType.DOWNWIND);
socketThread.sendBoatActionMessage(boatActionMessage);
break;
case ENTER: // tack/gybe
boatActionMessage = new BoatActionMessage(BoatActionType.TACK_GYBE);
socketThread.sendBoatActionMessage(boatActionMessage);
break;
//TODO Allow a zoom in and zoom out methods
case Z: // zoom in
System.out.println("Zoom in");
break;
case X: // zoom out
System.out.println("Zoom out");
break;
}
}
}
public void keyReleased(KeyEvent e) {
switch (e.getCode()) {
//TODO 12/07/17 Determine the sail state and send the appropriate packet (eg. if sails are in, send a sail out packet)
case SHIFT: // sails in/sails out
BoatActionMessage boatActionMessage = new BoatActionMessage(
BoatActionType.SAILS_IN);
socketThread.sendBoatActionMessage(boatActionMessage);
break;
}
}
}
+53 -40
View File
@@ -24,10 +24,12 @@ import seng302.model.GeoPoint;
import seng302.model.Limit;
import seng302.model.Yacht;
import seng302.model.mark.CompoundMark;
import seng302.model.mark.Corner;
import seng302.model.mark.Mark;
import seng302.utilities.GeoUtility;
import seng302.visualiser.fxObjects.AnnotationBox;
import seng302.visualiser.fxObjects.BoatObject;
import seng302.visualiser.fxObjects.CourseBoundary;
import seng302.visualiser.fxObjects.Gate;
import seng302.visualiser.fxObjects.Marker;
import seng302.visualiser.map.Boundary;
@@ -52,7 +54,7 @@ public class GameView extends Pane {
private double metersPerPixelX, metersPerPixelY;
private Text fpsDisplay = new Text();
private Polygon raceBorder = new Polygon();
private Polygon raceBorder = new CourseBoundary();
/* Note that if either of these is null then values for it have not been added and the other
should be used as the limits of the map. */
@@ -61,8 +63,8 @@ public class GameView extends Pane {
private Map<Mark, Marker> markerObjects;
private Map<Yacht, BoatObject> boatObjects = new HashMap<>();
private List<AnnotationBox> annotations = new ArrayList<>();
private List<Integer> markSequence;
private Map<Yacht, AnnotationBox> annotations = new HashMap<>();
private List<Corner> markSequence;
private ObservableList<Node> gameObjects;
private ImageView mapImage = new ImageView();
@@ -83,8 +85,8 @@ public class GameView extends Pane {
public GameView () {
gameObjects = this.getChildren();
// create image view for map, bind panel size to image
mapImage.fitWidthProperty().bind(this.widthProperty());
mapImage.fitHeightProperty().bind(this.heightProperty());
// mapImage.fitWidthProperty().bind(this.widthProperty());
// mapImage.fitHeightProperty().bind(this.heightProperty());
gameObjects.add(mapImage);
fpsDisplay.setLayoutX(5);
fpsDisplay.setLayoutY(20);
@@ -92,15 +94,15 @@ public class GameView extends Pane {
gameObjects.add(fpsDisplay);
gameObjects.add(raceBorder);
initializeTimer();
this.widthProperty().addListener(resize -> {
canvasWidth = this.getWidth();
canvasHeight = this.getHeight();
if (borderPoints != null) {
updateBorder(borderPoints);
} else if (course != null) {
updateCourse(course, markSequence);
}
});
// this.widthProperty().addListener(resize -> {
// canvasWidth = this.getWidth();
// canvasHeight = this.getHeight();
// if (borderPoints != null) {
// updateBorder(borderPoints);
// } else if (course != null) {
// updateCourse(course, markSequence);
// }
// });
}
private void initializeTimer () {
@@ -130,7 +132,7 @@ public class GameView extends Pane {
drawFps(frameRate.intValue());
}
}
boatObjects.forEach((boat, boatObject) -> {});
boatObjects.forEach((boat, boatObject) -> boatObject.updateLocation());
lastTime = now;
}
}
@@ -179,7 +181,7 @@ public class GameView extends Pane {
*
* @param newCourse the mark objects that make up the course.
*/
public void updateCourse(List<CompoundMark> newCourse, List<Integer> sequence) {
public void updateCourse(List<CompoundMark> newCourse, List<Corner> sequence) {
course = newCourse;
this.markSequence = sequence;
markerObjects = new HashMap<>();
@@ -187,9 +189,9 @@ public class GameView extends Pane {
//Creates new markers
for (CompoundMark cMark : course) {
//Set start and end colour
if (cMark.getId() == sequence.get(0)) {
if (cMark.getId() == sequence.get(0).getCompoundMarkID()) {
colour = Color.GREEN;
} else if (cMark.getId() == sequence.get(sequence.size() - 1)) {
} else if (cMark.getId() == sequence.get(sequence.size() - 1).getCompoundMarkID()) {
colour = Color.RED;
}
//Create mark dots
@@ -198,7 +200,7 @@ public class GameView extends Pane {
}
//Create gate line
if (cMark.isGate()) {
for (int i = 0; i < cMark.getMarks().size()-1; i++) {
for (int i = 1; i < cMark.getMarks().size(); i++) {
makeAndBindGate(
markerObjects.get(cMark.getSubMark(i)),
markerObjects.get(cMark.getSubMark(i+1)),
@@ -301,34 +303,35 @@ public class GameView extends Pane {
Group annotationsGroup = new Group();
Group wakesGroup = new Group();
Group boatObjectGroup = new Group();
Group trails = new Group();
BoatObject newObject;
BoatObject newBoat;
for (Yacht yacht : yachts) {
newObject = new BoatObject();
newObject.setFill(Colors.getColor());
boatObjects.put(yacht, newObject);
newBoat = new BoatObject();
newBoat.setFill(Colors.getColor());
boatObjects.put(yacht, newBoat);
yacht.addLocationListener((boat, lat, lon, heading, velocity) ->{
BoatObject bo = boatObjects.get(boat);
Point2D p2d = findScaledXY(lat, lon);
bo.setLayoutX(p2d.getX());
bo.setLayoutY(p2d.getY());
// bo.setTrajectory(heading, velocity * (metersPerPixelX + metersPerPixelY) / 2);
bo.moveTo(p2d.getX(), p2d.getY(), heading);
bo.setTrajectory(
heading,
velocity,
metersPerPixelX,
metersPerPixelY);
});
createAnnotationBox(yacht);
createAndBindAnnotationBox(yacht);
wakesGroup.getChildren().add(newBoat.getWake());
boatObjectGroup.getChildren().add(newBoat);
trails.getChildren().add(newBoat.getTrail());
}
// Group wakes = new Group();
// Group trails = new Group();
// Group annotationsGroup = new Group();
//
// gameObjects.addAll(trails);
// gameObjects.addAll(wakes);
annotationsGroup.getChildren().addAll(annotations);
annotationsGroup.getChildren().addAll(annotations.values());
gameObjects.addAll(trails);
gameObjects.addAll(annotationsGroup);
gameObjects.addAll(boatObjects.values());
gameObjects.addAll(boatObjectGroup);
}
private AnnotationBox createAnnotationBox (Yacht yacht) {
private void createAndBindAnnotationBox (Yacht yacht) {
AnnotationBox newAnnotation;
newAnnotation = new AnnotationBox();
newAnnotation.addAnnotation("name", yacht.getShortName());
@@ -354,8 +357,7 @@ public class GameView extends Pane {
return format.format(time);
}
);
annotations.add(newAnnotation);
return newAnnotation;
annotations.put(yacht, newAnnotation);
}
private void drawFps(int fps){
@@ -370,6 +372,9 @@ public class GameView extends Pane {
private void findMinMaxPoint(List<GeoPoint> points) {
List<GeoPoint> sortedPoints = new ArrayList<>(points);
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());
GeoPoint maxLat = sortedPoints.get(sortedPoints.size()-1);
maxLatPoint = new GeoPoint(maxLat.getLat(), maxLat.getLng());
@@ -472,6 +477,7 @@ public class GameView extends Pane {
distanceFromReference = GeoUtility.getDistance(
minLatPoint, new GeoPoint(unscaledLat, unscaledLon)
);
System.out.println("distanceFromReference = " + distanceFromReference);
if (angleFromReference >= 0 && angleFromReference <= Math.PI / 2) {
xAxisLocation += Math.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference);
yAxisLocation -= Math.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference);
@@ -491,6 +497,8 @@ public class GameView extends Pane {
if(horizontalInversion) {
xAxisLocation = canvasWidth - bufferSize - (xAxisLocation - bufferSize);
}
System.out.println("yAxisLocation = " + yAxisLocation + " " + unscaledLat);
System.out.println("xAxisLocation = " + xAxisLocation + " " + unscaledLon);
return new Point2D(xAxisLocation, yAxisLocation);
}
@@ -520,7 +528,7 @@ public class GameView extends Pane {
for (BoatObject boatObject : boatObjects.values()) {
boatObject.setVisibility(teamName, velocity, estTime, legTime, trail, wake);
}
for (AnnotationBox ag : annotations) {
for (AnnotationBox ag : annotations.values()) {
ag.setAnnotationVisibility("name", teamName);
ag.setAnnotationVisibility("velocity", velocity);
ag.setAnnotationVisibility("nextMark", estTime);
@@ -549,4 +557,9 @@ public class GameView extends Pane {
public void startRace () {
timer.start();
}
public void setBoatAsPlayer (Yacht playerYacht) {
boatObjects.get(playerYacht).setAsPlayer();
// annotations.get(playerYacht).setAsPlayer();
}
}
@@ -9,6 +9,7 @@ import java.util.Map;
import java.util.concurrent.TimeUnit;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
@@ -37,6 +38,7 @@ import javafx.util.Duration;
import javafx.util.StringConverter;
import seng302.model.RaceState;
import seng302.model.Yacht;
import seng302.model.mark.CompoundMark;
import seng302.model.mark.Mark;
import seng302.model.stream.xml.parser.RaceXMLData;
import seng302.visualiser.GameView;
@@ -74,7 +76,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
//Race Data
private Map<Integer, Yacht> participants;
private Map<Integer, Mark> markers;
private Map<Integer, CompoundMark> markers;
private RaceXMLData courseData;
private GameView gameView;
private RaceState raceState;
@@ -111,11 +113,19 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
initialiseBoatSelectionComboBox();
gameView = new GameView();
System.out.println("haha");
Platform.runLater(() -> {
contentAnchorPane.getChildren().add(gameView);
// contentAnchorPane.getChildren().add(gameView);
System.out.println("hehe");
gameView.setBoats(new ArrayList<>(participants.values()));
gameView.updateBorder(raceData.getCourseLimit());
gameView.updateCourse(new ArrayList<>(raceData.getCompoundMarks().values()));
gameView.updateCourse(
new ArrayList<>(raceData.getCompoundMarks().values()), raceData.getMarkSequence()
);
gameView.startRace();
});
}
/**
@@ -23,13 +23,10 @@ public class BoatObject extends Group {
//Constants for drawing
private static final double BOAT_HEIGHT = 15d;
private static final double BOAT_WIDTH = 10d;
//Variables for boat logic.
private boolean isStopped = true;
private double xIncrement;
private double yIncrement;
private long lastTimeValid = 0;
private Double lastRotation = 0.0;
private long framesToMove;
private double xVelocity;
private double yVelocity;
private double lastHeading;
//Graphical objects
private Group lineGroup = new Group();
private Polygon boatPoly;
@@ -38,11 +35,7 @@ public class BoatObject extends Group {
private Line rightLayline;
private Double distanceTravelled = 0.0;
private Point2D lastPoint;
private boolean destinationSet;
private AnnotationBox annotationBox;
private Paint colour = Color.BLACK;
private Boolean isSelected = true; //All boats are initialised as selected
/**
@@ -63,7 +56,6 @@ public class BoatObject extends Group {
*/
public BoatObject(double... points) {
this.colour = colour;
destinationSet = false;
initChildren(points);
}
@@ -104,7 +96,6 @@ public class BoatObject extends Group {
public void setFill (Paint value) {
this.colour = value;
boatPoly.setFill(colour);
// annotationBox.setFill(colour);
}
/**
@@ -117,8 +108,6 @@ public class BoatObject extends Group {
private void moveGroupBy(double dx, double dy) {
boatPoly.setLayoutX(boatPoly.getLayoutX() + dx);
boatPoly.setLayoutY(boatPoly.getLayoutY() + dy);
annotationBox.setLayoutX(annotationBox.getLayoutX() + dx);
annotationBox.setLayoutY(annotationBox.getLayoutY() + dy);
wake.setLayoutX(wake.getLayoutX() + dx);
wake.setLayoutY(wake.getLayoutY() + dy);
}
@@ -130,12 +119,10 @@ public class BoatObject extends Group {
* @param x The X coordinate to move the boat to
* @param y The Y coordinate to move the boat to
*/
private void moveTo(double x, double y, double rotation) {
public void moveTo(double x, double y, double rotation) {
rotateTo(rotation);
boatPoly.setLayoutX(x);
boatPoly.setLayoutY(y);
annotationBox.setLayoutX(x);
annotationBox.setLayoutY(y);
wake.setLayoutX(x);
wake.setLayoutY(y);
wake.rotate(rotation);
@@ -145,17 +132,12 @@ public class BoatObject extends Group {
boatPoly.getTransforms().setAll(new Rotate(rotation));
}
public void move() {
double dx = xIncrement * framesToMove;
double dy = yIncrement * framesToMove;
public void updateLocation() {
double dx = xVelocity / 60;
double dy = yVelocity / 60;
distanceTravelled += Math.abs(dx) + Math.abs(dy);
moveGroupBy(xIncrement, yIncrement);
framesToMove = framesToMove - 1;
if (framesToMove <= 0) {
isStopped = true;
}
moveGroupBy(dx, dy);
if (distanceTravelled > 70) {
distanceTravelled = 0d;
@@ -173,65 +155,11 @@ public class BoatObject extends Group {
l.setCacheHint(CacheHint.SPEED);
lineGroup.getChildren().add(l);
}
if (destinationSet) {
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
}
}
wake.updatePosition();
}
/**
* Sets the destination of the boat and the headng it should have once it reaches
*
* @param newXValue The X co-ordinate the boat needs to move to.
* @param newYValue The Y co-ordinate the boat needs to move to.
* @param rotation Rotation to move graphics to.
* @param timeValid the time the position values are valid for
*/
public void setDestination(double newXValue, double newYValue, double rotation,
double groundSpeed, long timeValid, double frameRate) {
destinationSet = true;
Double dx = Math.abs(boatPoly.getLayoutX() - newXValue);
Double dy = Math.abs(boatPoly.getLayoutY() - newYValue);
moveTo(newXValue, newYValue, rotation);
rotateTo(rotation);
wake.setRotation(rotation, groundSpeed);
// yacht.setVelocity(groundSpeed);
lastTimeValid = timeValid;
// boat.setVelocity(groundSpeed);
isStopped = false;
lastRotation = rotation;
// boatAnnotations.update();
distanceTravelled += Math.sqrt((dx * dx) + (dy * dy));
if (distanceTravelled > 10){// && isPlayer) {
distanceTravelled = 0d;
if (lastPoint != null) {
Line l = new Line(
lastPoint.getX(),
lastPoint.getY(),
boatPoly.getLayoutX(),
boatPoly.getLayoutY()
);
l.getStrokeDashArray().setAll(3d, 7d);
l.setStroke(this.colour);
l.setCache(true);
l.setCacheHint(CacheHint.SPEED);
lineGroup.getChildren().add(l);
}
if (destinationSet) {
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
}
}
}
// /**
// * This function works out if a boat is going upwind or down wind. It looks at the boats current position, the next
// * gates position and the current wind
@@ -269,7 +197,6 @@ public class BoatObject extends Group {
this.isSelected = isSelected;
setLineGroupVisible(isSelected);
setWakeVisible(isSelected);
annotationBox.setVisible(isSelected);
setLayLinesVisible(isSelected);
}
@@ -313,10 +240,6 @@ public class BoatObject extends Group {
return lineGroup;
}
public Group getAnnotations() {
return annotationBox;
}
public Double getBoatLayoutX() {
return boatPoly.getLayoutX();
}
@@ -326,24 +249,34 @@ public class BoatObject extends Group {
return boatPoly.getLayoutY();
}
public boolean isStopped() {
return isStopped;
}
/**
* Sets this boat to appear highlighted
*/
public void setAsPlayer() {
// boatPoly.getPoints().setAll(
// -BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75,
// 0.0, -BOAT_HEIGHT / 1.75,
// BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75
// );
// boatPoly.setStroke(Color.BLACK);
// boatPoly.setStrokeWidth(3);
boatPoly.getPoints().setAll(
-BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75,
0.0, -BOAT_HEIGHT / 1.75,
BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75
);
boatPoly.setStroke(Color.BLACK);
boatPoly.setStrokeWidth(3);
// boatAnnotations.setAsPlayer();
// isPlayer = true;
}
public void updateTrajectory(heading, velocity, scaleFactor)
public void setTrajectory(double heading, double velocity) {
wake.setRotation(lastHeading - heading, velocity);
rotateTo(heading);
xVelocity = Math.cos(Math.toRadians(heading)) * velocity;
yVelocity = Math.sin(Math.toRadians(heading)) * velocity;
lastHeading = heading;
}
public void setTrajectory(double heading, double velocity, double scaleFactorX, double scaleFactorY) {
// wake.setRotation(lastHeading - heading, velocity);
// rotateTo(heading);
// xVelocity = Math.cos(Math.toRadians(heading)) * velocity * scaleFactorX;
// yVelocity = Math.sin(Math.toRadians(heading)) * velocity * scaleFactorY;
lastHeading = heading;
}
}
@@ -6,8 +6,8 @@ import javafx.scene.shape.Polygon;
/**
* Polygon with default course border settings.
*/
public class CourseBorder extends Polygon {
public CourseBorder() {
public class CourseBoundary extends Polygon {
public CourseBoundary() {
this.setStroke(new Color(0.0f, 0.0f, 0.74509807f, 1));
this.setStrokeWidth(3);
this.setFill(new Color(0,0,0,0));
+45 -45
View File
@@ -1,45 +1,45 @@
package seng302.model.mark;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
/**
* Created by Haoming on 17/3/17.
*/
public class MarkTest {
private SingleMark singleMark1;
private SingleMark singleMark2;
private GateMark gateMark;
@Before
public void setUp() throws Exception {
this.singleMark1 = new SingleMark("testMark_SM1", 12.23234, -34.342, 1, 0);
this.singleMark2 = new SingleMark("testMark_SM2", 12.23239, -34.352, 2, 1);
this.gateMark = new GateMark("testMark_GM", MarkType.OPEN_GATE, singleMark1, singleMark2, singleMark1.getLatitude(), singleMark2.getLongitude(), 2);
}
@Test
public void getName() throws Exception {
assertEquals("testMark_SM1", this.singleMark1.getName());
assertEquals("testMark_GM", this.gateMark.getName());
}
@Test
public void getMarkType() throws Exception {
assertTrue(this.singleMark2.getMarkType() == MarkType.SINGLE_MARK);
assertTrue(this.gateMark.getMarkType() == MarkType.OPEN_GATE);
}
@Test
public void getMarkContent() throws Exception {
assertEquals(12.23234, this.singleMark1.getLatitude(), 1e-10);
assertEquals(-34.342, this.singleMark1.getLongitude(), 1e-10);
assertEquals("testMark_SM1", this.gateMark.getSingleMark1().getName());
assertEquals(-34.352, this.gateMark.getSingleMark2().getLongitude(), 1e-10);
}
}
//package seng302.model.mark;
//
//import static org.junit.Assert.assertEquals;
//import static org.junit.Assert.assertTrue;
//
//import org.junit.Before;
//import org.junit.Test;
//
///**
// * Created by Haoming on 17/3/17.
// */
//public class MarkTest {
//
// private SingleMark singleMark1;
// private SingleMark singleMark2;
// private GateMark gateMark;
//
// @Before
// public void setUp() throws Exception {
// this.singleMark1 = new SingleMark("testMark_SM1", 12.23234, -34.342, 1, 0);
// this.singleMark2 = new SingleMark("testMark_SM2", 12.23239, -34.352, 2, 1);
// this.gateMark = new GateMark("testMark_GM", MarkType.OPEN_GATE, singleMark1, singleMark2, singleMark1.getLatitude(), singleMark2.getLongitude(), 2);
// }
//
// @Test
// public void getName() throws Exception {
// assertEquals("testMark_SM1", this.singleMark1.getName());
// assertEquals("testMark_GM", this.gateMark.getName());
// }
//
// @Test
// public void getMarkType() throws Exception {
// assertTrue(this.singleMark2.getMarkType() == MarkType.SINGLE_MARK);
// assertTrue(this.gateMark.getMarkType() == MarkType.OPEN_GATE);
// }
//
// @Test
// public void getMarkContent() throws Exception {
// assertEquals(12.23234, this.singleMark1.getLatitude(), 1e-10);
// assertEquals(-34.342, this.singleMark1.getLongitude(), 1e-10);
// assertEquals("testMark_SM1", this.gateMark.getSingleMark1().getName());
// assertEquals(-34.352, this.gateMark.getSingleMark2().getLongitude(), 1e-10);
// }
//
//}