mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Refactored Boat class to better fit the MVC model by moving all GUI parts to BoatPolygon. Changed the way animation works so that it will work with a constantly updated set of lats and lons.
TODO - Change Mark class to no longer store XY pixel data. TODO - Add in a timer force updates boat position if a packet has not been recieved for a while. #story30b #story30c #implement #refactor
This commit is contained in:
@@ -5,42 +5,26 @@ import javafx.scene.shape.Polygon;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import javafx.scene.transform.Translate;
|
||||
import javafx.util.Pair;
|
||||
|
||||
/**
|
||||
* Represents a boat in the race.
|
||||
*/
|
||||
public class Boat {
|
||||
|
||||
private static final double TEAMNAME_X_OFFSET = 15d;
|
||||
private static final double TEAMNAME_Y_OFFSET = -20d;
|
||||
private static final double VELOCITY_X_OFFSET = 15d;
|
||||
private static final double VELOCITY_Y_OFFSET = -10d;
|
||||
private static final double VELOCITY_WAKE_RATIO = 2d; //Ratio for deciding how long the wake will be wrt velocity
|
||||
private static final double BOAT_HEIGHT = 15d;
|
||||
private static final double BOAT_WIDTH = 10d;
|
||||
|
||||
private String teamName; // The name of the team, this is also the name of the boat
|
||||
private double velocity; // In meters/second
|
||||
private double lat; // Boats position
|
||||
private double lon; // -
|
||||
private double distanceToNextMark;
|
||||
private Color color;
|
||||
private int markLastPast;
|
||||
private String teamName;
|
||||
private double velocity;
|
||||
private double lat;
|
||||
private double lon;
|
||||
private double heading;
|
||||
private int markLastPast;
|
||||
private String shortName;
|
||||
|
||||
//Graphical
|
||||
private Polygon boatObject;
|
||||
private Polygon wake;
|
||||
private Text teamNameObject;
|
||||
private Text velocityObject;
|
||||
|
||||
public Boat(String teamName) {
|
||||
this.teamName = teamName;
|
||||
this.velocity = 10; // Default velocity
|
||||
this.lat = 0.0;
|
||||
this.lon = 0.0;
|
||||
this.distanceToNextMark = 0.0;
|
||||
this.shortName = "";
|
||||
}
|
||||
|
||||
@@ -54,16 +38,7 @@ public class Boat {
|
||||
public Boat(String teamName, double boatVelocity, String shortName) {
|
||||
this.teamName = teamName;
|
||||
this.velocity = boatVelocity;
|
||||
this.distanceToNextMark = 0.0;
|
||||
this.color = Colors.getColor();
|
||||
this.shortName = shortName;
|
||||
this.boatObject = new Polygon();
|
||||
this.boatObject.getPoints().addAll(BOAT_WIDTH /2,0.0,
|
||||
BOAT_WIDTH, BOAT_HEIGHT,
|
||||
0.0, BOAT_HEIGHT);
|
||||
createWake();
|
||||
this.teamNameObject = new Text(shortName);
|
||||
this.velocityObject = new Text(Double.toString(boatVelocity) + "ms");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,8 +88,9 @@ public class Boat {
|
||||
this.lon = lon;
|
||||
}
|
||||
|
||||
public void setDistanceToNextMark(double distance){
|
||||
this.distanceToNextMark = distance;
|
||||
public Pair<Double, Double> getLocation ()
|
||||
{
|
||||
return new Pair<>(this.lat, this.lon);
|
||||
}
|
||||
|
||||
public double getLatitude(){
|
||||
@@ -125,8 +101,12 @@ public class Boat {
|
||||
return this.lon;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
public void setLatitude (double latitude) {
|
||||
this.lat = latitude;
|
||||
}
|
||||
|
||||
public void setlongitude (double longitude) {
|
||||
this.lon =longitude;
|
||||
}
|
||||
|
||||
public double getSpeedInKnots(){
|
||||
@@ -141,92 +121,16 @@ public class Boat {
|
||||
return markLastPast;
|
||||
}
|
||||
|
||||
public void setHeading(double heading){
|
||||
boatObject.getTransforms().clear();
|
||||
wake.getTransforms().clear();
|
||||
wake.getTransforms().add(new Translate(0, BOAT_HEIGHT));
|
||||
wake.getTransforms().add(new Rotate(heading, BOAT_WIDTH/2, -BOAT_HEIGHT));
|
||||
boatObject.getTransforms().add(new Rotate(heading, BOAT_WIDTH/2, 0));
|
||||
this.heading = heading;
|
||||
}
|
||||
|
||||
public double getHeading(){
|
||||
return this.heading;
|
||||
}
|
||||
|
||||
public void setHeading(double heading) {
|
||||
this.heading = heading;
|
||||
}
|
||||
|
||||
public String getShortName(){
|
||||
return this.shortName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Moves the boat and its children annotations from its current coordinates by specified amounts.
|
||||
* @param x The amount to move the X coordinate by
|
||||
* @param y The amount to move the Y coordinate by
|
||||
*/
|
||||
void moveBoatBy(Double x, Double y) {
|
||||
boatObject.setLayoutX(boatObject.getLayoutX() + x);
|
||||
boatObject.setLayoutY(boatObject.getLayoutY() + y);
|
||||
boatObject.relocate(boatObject.getLayoutX(), boatObject.getLayoutY());
|
||||
|
||||
teamNameObject.setX(teamNameObject.getX() + x);
|
||||
teamNameObject.setY(teamNameObject.getY() + y);
|
||||
teamNameObject.relocate(teamNameObject.getX(), teamNameObject.getY());
|
||||
|
||||
velocityObject.setX(velocityObject.getX() + x);
|
||||
velocityObject.setY(velocityObject.getY() + y);
|
||||
velocityObject.relocate(velocityObject.getX(), velocityObject.getY());
|
||||
|
||||
|
||||
wake.setLayoutX(wake.getLayoutX() + x);
|
||||
wake.setLayoutY(wake.getLayoutY() + y);
|
||||
wake.relocate(wake.getLayoutX(), wake.getLayoutY());
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the boat and its children annotations to coordinates specified
|
||||
* @param x The X coordinate to move the boat to
|
||||
* @param y The Y coordinate to move the boat to
|
||||
*/
|
||||
public void moveBoatTo(Double x, Double y) {
|
||||
boatObject.setLayoutX(x);
|
||||
boatObject.setLayoutY(y);
|
||||
boatObject.relocate(boatObject.getLayoutX(), boatObject.getLayoutY());
|
||||
|
||||
teamNameObject.setX(x + TEAMNAME_X_OFFSET);
|
||||
teamNameObject.setY(y + TEAMNAME_Y_OFFSET);
|
||||
teamNameObject.relocate(teamNameObject.getX(), teamNameObject.getY());
|
||||
|
||||
velocityObject.setX(x + VELOCITY_X_OFFSET);
|
||||
velocityObject.setY(y + VELOCITY_Y_OFFSET);
|
||||
velocityObject.relocate(velocityObject.getX(), velocityObject.getY());
|
||||
|
||||
wake.setLayoutX(x);
|
||||
wake.setLayoutY(y);
|
||||
wake.relocate(wake.getLayoutX(), wake.getLayoutY());
|
||||
}
|
||||
|
||||
private void createWake(){
|
||||
wake = new Polygon();
|
||||
wake.setFill(Color.LIGHTSKYBLUE);
|
||||
wake.getPoints().addAll(5.0,0.0,
|
||||
10.0, velocity * VELOCITY_WAKE_RATIO,
|
||||
0.0, velocity * VELOCITY_WAKE_RATIO);
|
||||
}
|
||||
|
||||
public Polygon getWake() {
|
||||
return wake;
|
||||
}
|
||||
|
||||
public Polygon getBoatObject() {
|
||||
return boatObject;
|
||||
}
|
||||
|
||||
public Text getTeamNameObject() {
|
||||
return teamNameObject;
|
||||
}
|
||||
|
||||
public Text getVelocityObject() {
|
||||
return velocityObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package seng302.models;
|
||||
|
||||
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Polygon;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import javafx.scene.transform.Translate;
|
||||
|
||||
/**
|
||||
* Created by cir27 on 24/04/17.
|
||||
*/
|
||||
public class BoatPolygon extends Polygon {
|
||||
|
||||
private static final double TEAMNAME_X_OFFSET = 15d;
|
||||
private static final double TEAMNAME_Y_OFFSET = -20d;
|
||||
private static final double VELOCITY_X_OFFSET = 15d;
|
||||
private static final double VELOCITY_Y_OFFSET = -10d;
|
||||
private static final double VELOCITY_WAKE_RATIO = 2d;
|
||||
private static final double BOAT_HEIGHT = 15d;
|
||||
private static final double BOAT_WIDTH = 10d;
|
||||
//Time between sections of race - Should be changed to 200 for actual program.
|
||||
private static double expectedUpdateInterval = 5000;
|
||||
|
||||
private Boat boat;
|
||||
private Polygon wake;
|
||||
private Text teamNameObject;
|
||||
private Text velocityObject;
|
||||
|
||||
private double rotation;
|
||||
private double pixelVelocityX;
|
||||
private double pixelVelocityY;
|
||||
//private double destinationX;
|
||||
//private double destinationY;
|
||||
|
||||
public BoatPolygon (Boat boat, Color color){
|
||||
super();
|
||||
super.setFill(color);
|
||||
super.getPoints().addAll(
|
||||
BOAT_WIDTH / 2, 0.0,
|
||||
BOAT_WIDTH , BOAT_HEIGHT,
|
||||
0.0 , BOAT_HEIGHT
|
||||
);
|
||||
this.boat = boat;
|
||||
initAnnotations();
|
||||
}
|
||||
|
||||
public BoatPolygon (Boat boat, Color color, double... points)
|
||||
{
|
||||
super(points);
|
||||
super.setFill(color);
|
||||
this.boat = boat;
|
||||
initAnnotations();
|
||||
}
|
||||
|
||||
private void initAnnotations ()
|
||||
{
|
||||
wake = new Polygon();
|
||||
wake.setFill(Color.DARKBLUE);
|
||||
wake.getPoints().addAll(
|
||||
5.0,0.0,
|
||||
10.0, boat.getVelocity() * VELOCITY_WAKE_RATIO,
|
||||
0.0, boat.getVelocity() * VELOCITY_WAKE_RATIO
|
||||
);
|
||||
teamNameObject = new Text(boat.getShortName());
|
||||
velocityObject = new Text(String.valueOf(boat.getVelocity()));
|
||||
}
|
||||
/**
|
||||
* Moves the boat and its children annotations from its current coordinates by specified amounts.
|
||||
* @param dx The amount to move the X coordinate by
|
||||
* @param dy The amount to move the Y coordinate by
|
||||
*/
|
||||
void moveBy(Double dx, Double dy) {
|
||||
super.setLayoutX(super.getLayoutX() + dx);
|
||||
super.setLayoutY(super.getLayoutY() + dy);
|
||||
super.relocate(super.getLayoutX(), super.getLayoutY());
|
||||
|
||||
teamNameObject.setX(teamNameObject.getX() + dx);
|
||||
teamNameObject.setY(teamNameObject.getY() + dy);
|
||||
teamNameObject.relocate(teamNameObject.getX(), teamNameObject.getY());
|
||||
|
||||
velocityObject.setX(velocityObject.getX() + dx);
|
||||
velocityObject.setY(velocityObject.getY() + dy);
|
||||
velocityObject.relocate(velocityObject.getX(), velocityObject.getY());
|
||||
|
||||
wake.setLayoutX(wake.getLayoutX() + dx);
|
||||
wake.setLayoutY(wake.getLayoutY() + dy);
|
||||
wake.relocate(wake.getLayoutX(), wake.getLayoutY());
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the boat and its children annotations to coordinates specified
|
||||
* @param x The X coordinate to move the boat to
|
||||
* @param y The Y coordinate to move the boat to
|
||||
*/
|
||||
public void moveBoatTo(Double x, Double y) {
|
||||
super.setLayoutX(x);
|
||||
super.setLayoutY(y);
|
||||
super.relocate(super.getLayoutX(), super.getLayoutY());
|
||||
|
||||
teamNameObject.setX(x + TEAMNAME_X_OFFSET);
|
||||
teamNameObject.setY(y + TEAMNAME_Y_OFFSET);
|
||||
teamNameObject.relocate(teamNameObject.getX(), teamNameObject.getY());
|
||||
|
||||
velocityObject.setX(x + VELOCITY_X_OFFSET);
|
||||
velocityObject.setY(y + VELOCITY_Y_OFFSET);
|
||||
velocityObject.relocate(velocityObject.getX(), velocityObject.getY());
|
||||
|
||||
wake.setLayoutX(x);
|
||||
wake.setLayoutY(y);
|
||||
wake.relocate(wake.getLayoutX(), wake.getLayoutY());
|
||||
}
|
||||
|
||||
public void updatePosition (double timeInterval) {
|
||||
double dx = pixelVelocityX * timeInterval;
|
||||
double dy = pixelVelocityY * timeInterval;
|
||||
moveBy(dx, dy);
|
||||
}
|
||||
|
||||
public void setDestination (double newXValue, double newYValue) {
|
||||
this.pixelVelocityX = (newXValue - super.getLayoutX()) / expectedUpdateInterval;
|
||||
this.pixelVelocityY = (newYValue - super.getLayoutY()) / expectedUpdateInterval;
|
||||
//this.destinationX = newXValue;
|
||||
//this.destinationY = newYValue;
|
||||
this.rotation = Math.abs(
|
||||
Math.toDegrees(
|
||||
Math.atan(
|
||||
(newYValue - super.getLayoutY()) / (newXValue - super.getLayoutX())
|
||||
)
|
||||
)
|
||||
);
|
||||
if (super.getLayoutY() >= newYValue && super.getLayoutX() <= newXValue)
|
||||
rotation = 90 - rotation;
|
||||
else if (super.getLayoutY() < newYValue && super.getLayoutX() <= newXValue)
|
||||
rotation = 90 + rotation;
|
||||
else if (super.getLayoutY() >= newYValue && super.getLayoutX() > newXValue)
|
||||
rotation = 270 + rotation;
|
||||
else
|
||||
rotation = 270 - rotation;
|
||||
rotateBoat ();
|
||||
}
|
||||
|
||||
private void rotateBoat () {
|
||||
super.getTransforms().clear();
|
||||
super.getTransforms().add(new Rotate(rotation, BOAT_WIDTH/2, 0));
|
||||
wake.getTransforms().clear();
|
||||
wake.getTransforms().add(new Translate(0, BOAT_HEIGHT));
|
||||
wake.getTransforms().add(new Rotate(rotation, BOAT_WIDTH/2, -BOAT_HEIGHT));
|
||||
}
|
||||
|
||||
public static double getExpectedUpdateInterval() {
|
||||
return expectedUpdateInterval;
|
||||
}
|
||||
|
||||
public static void setExpectedUpdateInterval(double expectedUpdateInterval) {
|
||||
BoatPolygon.expectedUpdateInterval = expectedUpdateInterval;
|
||||
}
|
||||
|
||||
public Polygon getWake() {
|
||||
return wake;
|
||||
}
|
||||
|
||||
public Text getTeamNameObject() {
|
||||
return teamNameObject;
|
||||
}
|
||||
|
||||
public Text getVelocityObject() {
|
||||
return velocityObject;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,10 +11,9 @@ public enum Colors {
|
||||
static Integer index = 0;
|
||||
|
||||
public static Color getColor() {
|
||||
index++;
|
||||
if (index > 6) {
|
||||
index = 1;
|
||||
if (index == 6) {
|
||||
index = 0;
|
||||
}
|
||||
return Color.valueOf(values()[index-1].toString());
|
||||
return Color.valueOf(values()[index++].toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.*;
|
||||
* Created by mra106 on 8/3/2017.
|
||||
*/
|
||||
public class Race {
|
||||
|
||||
private ArrayList<Boat> boats; // The boats in the race
|
||||
private ArrayList<Boat> finishingOrder; // The order in which the boats finish the race
|
||||
private HashMap<Boat, List> events = new HashMap<>(); // The events that occur in the race
|
||||
|
||||
@@ -42,7 +42,7 @@ public abstract class Mark {
|
||||
Double longitude2 = pointTwo.getLongitude();
|
||||
Double latitude1 = pointOne.getLatitude();
|
||||
Double latitude2 = pointTwo.getLatitude();
|
||||
return calculateHeadingRad(longitude1, longitude2, latitude1, latitude2);
|
||||
return calculateHeadingRad(latitude1, longitude1, latitude2, longitude2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +54,7 @@ public abstract class Mark {
|
||||
* @param latitude2 Latitude of first point in degrees
|
||||
* @return Heading in radians
|
||||
*/
|
||||
public static double calculateHeadingRad (Double longitude1, Double longitude2, Double latitude1, Double latitude2) {
|
||||
public static double calculateHeadingRad (Double latitude1, Double longitude1, Double latitude2, Double longitude2) {
|
||||
latitude1 = Math.toRadians(latitude1);
|
||||
latitude2 = Math.toRadians(latitude2);
|
||||
Double longDiff= Math.toRadians(longitude2-longitude1);
|
||||
@@ -75,7 +75,7 @@ public abstract class Mark {
|
||||
Double longitude2 = pointTwo.getLongitude();
|
||||
Double latitude1 = pointOne.getLatitude();
|
||||
Double latitude2 = pointTwo.getLatitude();
|
||||
return calculateDistance(longitude1, longitude2, latitude1, latitude2);
|
||||
return calculateDistance(latitude1, longitude1, latitude2, longitude2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +88,7 @@ public abstract class Mark {
|
||||
* @param latitude2 Latitude of first point in degrees
|
||||
* @return Distance in meters
|
||||
*/
|
||||
public static Double calculateDistance (Double longitude1, Double longitude2, Double latitude1, Double latitude2) {
|
||||
public static Double calculateDistance (Double latitude1, Double longitude1, Double latitude2, Double longitude2) {
|
||||
Double theta = longitude1 - longitude2;
|
||||
Double dist = Math.sin(Math.toRadians(latitude1)) * Math.sin(Math.toRadians(latitude2)) +
|
||||
Math.cos(Math.toRadians(latitude1)) * Math.cos(Math.toRadians(latitude2)) *
|
||||
|
||||
Reference in New Issue
Block a user