Merge branch 'develop' into story61_player_perspective

# Conflicts:
#	src/main/java/seng302/App.java
#	src/main/java/seng302/client/ClientPacketParser.java
#	src/main/java/seng302/controllers/Controller.java
#	src/main/java/seng302/controllers/RaceViewController.java
#	src/main/java/seng302/fxObjects/BoatAnnotations.java
#	src/main/java/seng302/gameServer/GameState.java
#	src/main/java/seng302/gameServer/MainServerThread.java
#	src/main/java/seng302/gameServer/ServerToClientThread.java
#	src/main/java/seng302/model/Boat.java
#	src/main/java/seng302/models/stream/XMLParser.java
#	src/main/java/seng302/visualiser/ClientToServerThread.java
#	src/main/java/seng302/visualiser/GameView.java
#	src/main/java/seng302/visualiser/controllers/FinishScreenViewController.java
#	src/main/java/seng302/visualiser/controllers/StartScreenController.java
#	src/main/java/seng302/visualiser/fxObjects/BoatObject.java
#	src/main/resources/views/LobbyView.fxml
#	src/main/resources/views/MainView.fxml
This commit is contained in:
Calum
2017-07-25 21:05:15 +12:00
48 changed files with 2952 additions and 268 deletions
+169 -7
View File
@@ -6,10 +6,18 @@ import javafx.beans.property.ReadOnlyLongProperty;
import javafx.beans.property.ReadOnlyLongWrapper;
import javafx.scene.paint.Color;
import seng302.model.mark.Mark;
import static seng302.utilities.GeoUtility.getGeoCoordinate;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javafx.scene.paint.Color;
import seng302.client.ClientPacketParser;
import seng302.controllers.RaceViewController;
import seng302.gameServer.GameState;
import seng302.models.mark.Mark;
import seng302.utilities.GeoPoint;
/**
* Yacht class for the racing boat.
*
@@ -18,11 +26,17 @@ import java.text.SimpleDateFormat;
*/
public class Boat {
private final Double TURN_STEP = 5.0;
private Double lastHeading;
private Boolean sailIn;
// Used in boat group
private Color colour = Color.BLACK;
private String boatType;
private Integer sourceID;
private Integer sourceId;
private String hullID; //matches HullNum in the XML spec.
private String shortName;
private String boatName;
@@ -40,30 +54,167 @@ public class Boat {
private ReadOnlyDoubleWrapper velocity = new ReadOnlyDoubleWrapper();
private ReadOnlyLongWrapper timeTillNext = new ReadOnlyLongWrapper();
private ReadOnlyLongWrapper timeSinceLastMark = new ReadOnlyLongWrapper();
private String position;
private GeoPoint location;
private Double heading;
private Double velocity;
private Long timeTillNext;
private Long markRoundTime;
// Mark rounding
private Mark lastMarkRounded;
private Mark nextMark;
/**
* @param location latlon location of the boat stored in a geopoint
* @param heading heading of the boat in degrees from 0 to 365 with 0 being north
*/
public Yacht(GeoPoint location, Double heading) {
this.location = location;
this.heading = heading;
this.velocity = 0.0;
this.sailIn = false;
}
/**
* Used in EventTest and RaceTest.
*
* @param boatName Create a yacht object with name.
*/
public Yacht(String boatName, String shortName, GeoPoint location, Double heading) {
this.boatName = boatName;
this.shortName = shortName;
this.location = location;
this.heading = heading;
this.velocity = 0.0;
this.sailIn = false;
}
/**
* Used in BoatGroupTest.
*
* @param boatName The name of the team sailing the boat
* @param boatVelocity The speed of the boat in meters/second
* @param shortName A shorter version of the teams name
*/
public Yacht(String boatName, double boatVelocity, String shortName, int id) {
this.boatName = boatName;
this.velocity = boatVelocity;
this.shortName = shortName;
this.sourceId = id;
this.sailIn = false;
}
public Yacht(String boatType, Integer sourceId, String hullID, String shortName,
String boatName, String country) {
public Boat(String boatType, Integer sourceID, String hullID, String shortName,
String boatName, String country) {
this.boatType = boatType;
this.sourceID = sourceID;
this.sourceId = sourceId;
this.hullID = hullID;
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;
this.velocity = 50000.0;
}
/**
* @param timeInterval since last update in milliseconds
*/
public void update(Long timeInterval) {
if (sailIn) {
Double secondsElapsed = timeInterval / 1000000.0;
Double thisHeading = ((double) Math.floorMod(heading.longValue(), 360L));
Double windSpeedKnots = 0d;
Double boatSpeedInKnots = PolarTable.getBoatSpeed(windSpeedKnots, thisHeading);
velocity = boatSpeedInKnots / ClientPacketParser.MS_TO_KNOTS * 3000;
//System.out.println("velocity = " + velocity);
Double metersCovered = velocity * secondsElapsed;
location = getGeoCoordinate(location, heading, metersCovered);
}
}
public Double getHeading() {
return heading;
}
public void adjustHeading(Double amount) {
lastHeading = heading;
// TODO: 24/07/17 wmu16 - '%' in java does remainder, we need modulo. All this must be changed here, this is why we have neg values!
heading = (heading + amount) % 360.0;
}
public void tackGybe(Double windDirection) {
adjustHeading(-2 * ((heading - windDirection) % 360));
}
public void toggleSailIn() {
sailIn = !sailIn;
}
public void turnUpwind() {
Double normalizedHeading = (heading - GameState.windDirection) % 360;
if (normalizedHeading == 0) {
if (lastHeading < 180) {
adjustHeading(-TURN_STEP);
} else {
adjustHeading(TURN_STEP);
}
} else if (normalizedHeading == 180) {
if (lastHeading < 180) {
adjustHeading(TURN_STEP);
} else {
adjustHeading(-TURN_STEP);
}
} else if (normalizedHeading < 180) {
adjustHeading(-TURN_STEP);
} else {
adjustHeading(TURN_STEP);
}
}
public void turnDownwind() {
Double normalizedHeading = (heading - GameState.windDirection) % 360;
if (normalizedHeading == 0) {
if (lastHeading < 180) {
adjustHeading(TURN_STEP);
} else {
adjustHeading(-TURN_STEP);
}
} else if (normalizedHeading == 180) {
if (lastHeading < 180) {
adjustHeading(-TURN_STEP);
} else {
adjustHeading(TURN_STEP);
}
} else if (normalizedHeading < 180) {
adjustHeading(TURN_STEP);
} else {
adjustHeading(-TURN_STEP);
}
}
public String getBoatType() {
return boatType;
}
public Integer getSourceID() {
return sourceID;
public Integer getSourceId() {
//@TODO Remove and merge with Creating Game Loop
if (sourceId == null) return 0;
return sourceId;
}
public String getHullID() {
if (hullID == null) return "";
return hullID;
}
@@ -76,6 +227,7 @@ public class Boat {
}
public String getCountry() {
if (country == null) return "";
return country;
}
@@ -92,6 +244,10 @@ public class Boat {
}
public void setLegNumber(Integer legNumber) {
if (colour != null && position != "-" && legNumber != this.legNumber&& RaceViewController.sparkLineStatus(
sourceId)) {
RaceViewController.updateYachtPositionSparkline(this, legNumber);
}
this.legNumber = legNumber;
}
@@ -154,12 +310,12 @@ public class Boat {
}
public void setNextMark(Mark nextMark) {
this.nextMark = nextMark;
}
this.nextMark = nextMark;
}
public Mark getNextMark(){
return nextMark;
}
}
public Double getLat() {
return lat;
@@ -183,6 +339,8 @@ public class Boat {
public void setHeading(Double heading) {
this.heading = heading;
public Boolean getSailIn() {
return sailIn;
}
@Override
@@ -190,6 +348,10 @@ public class Boat {
return boatName;
}
public GeoPoint getLocation() {
return location;
}
public void setTimeSinceLastMark (long timeSinceLastMark) {
this.timeSinceLastMark.set(timeSinceLastMark);
}
+2 -1
View File
@@ -13,8 +13,9 @@ public class Player {
private Integer lastMarkPassed;
public Player(Socket socket) {
public Player(Socket socket, Yacht yacht) {
this.socket = socket;
this.yacht = yacht;
}
public Socket getSocket() {
+36 -15
View File
@@ -1,6 +1,10 @@
package seng302.model;
import java.io.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
@@ -123,7 +127,7 @@ public final class PolarTable {
*/
public static HashMap<Double, Double> getOptimalUpwindVMG(Double thisWindSpeed) {
Double polarWindSpeed = getClosestMatch(thisWindSpeed);
Double polarWindSpeed = getClosestWindSpeedInPolar(thisWindSpeed);
return upwindOptimal.get(polarWindSpeed);
}
@@ -135,30 +139,47 @@ public final class PolarTable {
*/
public static HashMap<Double, Double> getOptimalDownwindVMG(Double thisWindSpeed) {
Double polarWindSpeed = getClosestMatch(thisWindSpeed);
Double polarWindSpeed = getClosestWindSpeedInPolar(thisWindSpeed);
return downwindOptimal.get(polarWindSpeed);
}
private static Double getClosestMatch(Double thisWindSpeed) {
public static Double getBoatSpeed(Double thisWindSpeed, Double thisHeading) {
ArrayList<Double> windValues = new ArrayList<>(polarTable.keySet());
Double polarWindSpeed = getClosestWindSpeedInPolar(thisWindSpeed);
Double polarAngle = getClosestAngleInPolar(polarTable.get(polarWindSpeed), thisHeading);
Double lowerVal = windValues.get(0);
Double upperVal = windValues.get(1);
return polarTable.get(polarWindSpeed).get(polarAngle);
}
for(int i = 0; i < windValues.size() - 1; i++) {
lowerVal = windValues.get(i);
upperVal = windValues.get(i+1);
if (thisWindSpeed <= upperVal) {
break;
public static Double getClosestWindSpeedInPolar(Double thisWindSpeed) {
Double smallestDif = Double.POSITIVE_INFINITY;
Double closestWind = 0d;
for (Double polarWindSpeed : polarTable.keySet()) {
Double difference = Math.abs(polarWindSpeed - thisWindSpeed);
if (difference < smallestDif) {
smallestDif = difference;
closestWind = polarWindSpeed;
}
}
return closestWind;
}
Double lowerDiff = Math.abs(lowerVal - thisWindSpeed);
Double upperDiff = Math.abs(upperVal - thisWindSpeed);
return (lowerDiff <= upperDiff) ? lowerVal : upperVal;
public static Double getClosestAngleInPolar(HashMap<Double, Double> thisWindSpeedPolar, Double thisHeading) {
Double smallestDif = Double.POSITIVE_INFINITY;
Double closestAngle = 0d;
for (Double polarAngle : thisWindSpeedPolar.keySet()) {
Double difference = Math.abs(polarAngle - thisHeading);
if (difference < smallestDif) {
smallestDif = difference;
closestAngle = polarAngle;
}
}
return closestAngle;
}
}