mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Mark drawing moved to MarkGroup class. RaceObject and it's sub classes now describe
all functionality required for a on screen object. Improved wakes. Branch currently untested. #story[812, 820] #refactor #implement.
This commit is contained in:
@@ -6,6 +6,7 @@ import javafx.fxml.FXML;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.geometry.Point3D;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
@@ -15,10 +16,8 @@ import javafx.util.Pair;
|
||||
import seng302.models.Boat;
|
||||
import seng302.models.BoatGroup;
|
||||
import seng302.models.Colors;
|
||||
import seng302.models.mark.GateMark;
|
||||
import seng302.models.mark.Mark;
|
||||
import seng302.models.mark.MarkType;
|
||||
import seng302.models.mark.SingleMark;
|
||||
import seng302.models.RaceObject;
|
||||
import seng302.models.mark.*;
|
||||
import seng302.models.parsers.StreamParser;
|
||||
import seng302.models.parsers.StreamReceiver;
|
||||
|
||||
@@ -59,6 +58,7 @@ public class CanvasController {
|
||||
private double referencePointX;
|
||||
private double referencePointY;
|
||||
private double metersToPixels;
|
||||
private List<RaceObject> raceObjects = new ArrayList<>();
|
||||
|
||||
public AnimationTimer timer;
|
||||
|
||||
@@ -154,39 +154,51 @@ public class CanvasController {
|
||||
|
||||
Mark nextMark;
|
||||
//if (countdown == 0) {
|
||||
for (BoatGroup boatGroup : boatGroups) {
|
||||
for (RaceObject raceObject : raceObjects) {
|
||||
//if (currentRaceMarker[boatIndex] < marks.size()) {
|
||||
//if (currentRaceMarker[boatIndex] == 6) {
|
||||
// int debugLine = 4;
|
||||
//}
|
||||
double xb4 = boatGroup.getLayoutX();
|
||||
double yb4 = boatGroup.getLayoutY();
|
||||
nextMark = marks.get(currentRaceMarker[boatIndex]);
|
||||
//double xb4 = boatGroup.getLayoutX();
|
||||
//double yb4 = boatGroup.getLayoutY();
|
||||
//nextMark = marks.get(currentRaceMarker[boatIndex]);
|
||||
|
||||
//descending = nextMark.getY() > boatGroup.getLayoutY();
|
||||
//leftToRight = nextMark.getX() < boatGroup.getLayoutX();
|
||||
|
||||
boatGroup.updatePosition(1000 / 60);
|
||||
Point3D p = StreamParser.boatPositions.get((long)boatGroup.getBoat().getId());
|
||||
raceObject.updatePosition(1000 / 60);
|
||||
for (int id : raceObject.getRaceIds()) {
|
||||
if (StreamParser.boatPositions.containsKey(id)) {
|
||||
Point3D p = StreamParser.boatPositions.get((long) id);
|
||||
Point2D p2d = latLonToXY(p.getX(), p.getY());
|
||||
//System.out.println("p2d = " + p2d);
|
||||
//System.out.println("p.toString() = " + p.toString());
|
||||
double heading = 360.0 / 0xffff * p.getZ();
|
||||
//System.out.println("heading = " + heading);
|
||||
raceObject.setDestination(p2d.getX(), p2d.getY(), heading, id);
|
||||
}
|
||||
StreamParser.boatPositions.remove((long) id);
|
||||
}
|
||||
//Point3D p = StreamParser.boatPositions.get((long) raceObject.getRaceIds()[0]);
|
||||
//System.out.println("boatGroup = " + boatGroup.getBoat().getId());
|
||||
//System.out.println("StreamParser.boatPositions.toString() = " + StreamParser.boatPositions.toString());
|
||||
if (p != null) {
|
||||
Point2D p2d = latLonToXY(p.getX(), p.getY());
|
||||
//System.out.println("p2d = " + p2d);
|
||||
if (!boatGroup.isSamePos(p2d)) {
|
||||
//System.out.println("p.toString() = " + p.toString());
|
||||
double heading = 360.0 / 0xffff * p.getZ();
|
||||
//System.out.println("heading = " + heading);
|
||||
|
||||
|
||||
|
||||
boatGroup.setDestination(p2d.getX(), p2d.getY(), heading);
|
||||
// if (p != null) {
|
||||
// Point2D p2d = latLonToXY(p.getX(), p.getY());
|
||||
// //System.out.println("p2d = " + p2d);
|
||||
// if (!boatGroup.isSamePos(p2d)) {
|
||||
// //System.out.println("p.toString() = " + p.toString());
|
||||
// double heading = 360.0 / 0xffff * p.getZ();
|
||||
// //System.out.println("heading = " + heading);
|
||||
//
|
||||
//
|
||||
//
|
||||
// boatGroup.setDestination(p2d.getX(), p2d.getY(), heading, boatGroup.getRaceIds()[0]);
|
||||
|
||||
|
||||
|
||||
//boatGroup.setDestination(p2d.getX(), p2d.getY());
|
||||
}
|
||||
}
|
||||
// }
|
||||
//}
|
||||
|
||||
// if (descending && nextMark.getY() < boatGroup.getLayoutY()) {
|
||||
// currentRaceMarker[boatIndex]++;
|
||||
@@ -208,14 +220,14 @@ public class CanvasController {
|
||||
// boatGroup.setDestination(
|
||||
// marks.get(currentRaceMarker[boatIndex]).getX(), marks.get(currentRaceMarker[boatIndex]).getY()
|
||||
// );
|
||||
// }
|
||||
|
||||
double xnew = boatGroup.getLayoutX();
|
||||
double ynew = boatGroup.getLayoutY();
|
||||
double dx = xnew - xb4;
|
||||
double dy = ynew -yb4;
|
||||
raceFinished = false;
|
||||
boatIndex++;
|
||||
|
||||
// double xnew = boatGroup.getLayoutX();
|
||||
// double ynew = boatGroup.getLayoutY();
|
||||
// double dx = xnew - xb4;
|
||||
// double dy = ynew -yb4;
|
||||
// raceFinished = false;
|
||||
// boatIndex++;
|
||||
}
|
||||
//}
|
||||
//if (raceFinished) {
|
||||
@@ -280,11 +292,10 @@ public class CanvasController {
|
||||
private void drawBoats() {
|
||||
// Map<Boat, TimelineInfo> timelineInfos = raceViewController.getTimelineInfos();
|
||||
List<Boat> boats = raceViewController.getStartingBoats();
|
||||
List<Mark> marks = raceViewController.getRace().getCourse();
|
||||
Double startingX = (double) marks.get(0).getX();
|
||||
Double startingY = (double) marks.get(0).getY();
|
||||
Double firstMarkX = (double) marks.get(1).getX();
|
||||
Double firstMarkY = (double) marks.get(1).getY();
|
||||
Double startingX = group.getChildren().get(0).getLayoutX();
|
||||
Double startingY = group.getChildren().get(0).getLayoutY();
|
||||
Double firstMarkX = group.getChildren().get(1).getLayoutX();
|
||||
Double firstMarkY = group.getChildren().get(1).getLayoutY();
|
||||
|
||||
for (Boat boat : boats) {
|
||||
BoatGroup boatGroup = new BoatGroup(boat, Colors.getColor());
|
||||
@@ -324,67 +335,67 @@ public class CanvasController {
|
||||
*/
|
||||
private void drawCourse() {
|
||||
fitToCanvas();
|
||||
for (Mark mark : raceViewController.getRace().getCourse()) {
|
||||
if (mark.getMarkType() == MarkType.SINGLE_MARK) {
|
||||
drawSingleMark((SingleMark) mark, Color.BLACK);
|
||||
} else {
|
||||
drawGateMark((GateMark) mark);
|
||||
}
|
||||
}
|
||||
System.out.println("MIN/MAX POINTS");
|
||||
System.out.println(minLatPoint.getName() + " " + minLatPoint.getX() + " " + minLatPoint.getY());
|
||||
System.out.println(maxLatPoint.getName() + " " + maxLatPoint.getX() + " " + maxLatPoint.getY());
|
||||
System.out.println(minLonPoint.getName() + " " + minLonPoint.getX() + " " + minLonPoint.getY());
|
||||
System.out.println(maxLonPoint.getName() + " " + maxLonPoint.getX() + " " + maxLonPoint.getY());
|
||||
System.out.println(referencePointX);
|
||||
System.out.println(referencePointY);
|
||||
// for (Mark mark : raceViewController.getRace().getCourse()) {
|
||||
// if (mark.getMarkType() == MarkType.SINGLE_MARK) {
|
||||
// drawSingleMark((SingleMark) mark, Color.BLACK);
|
||||
// } else {
|
||||
// drawGateMark((GateMark) mark);
|
||||
// }
|
||||
// }
|
||||
// System.out.println("MIN/MAX POINTS");
|
||||
// System.out.println(minLatPoint.getName() + " " + minLatPoint.getX() + " " + minLatPoint.getY());
|
||||
// System.out.println(maxLatPoint.getName() + " " + maxLatPoint.getX() + " " + maxLatPoint.getY());
|
||||
// System.out.println(minLonPoint.getName() + " " + minLonPoint.getX() + " " + minLonPoint.getY());
|
||||
// System.out.println(maxLonPoint.getName() + " " + maxLonPoint.getX() + " " + maxLonPoint.getY());
|
||||
// System.out.println(referencePointX);
|
||||
// System.out.println(referencePointY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a given mark on canvas
|
||||
*
|
||||
* @param singleMark
|
||||
*/
|
||||
private void drawSingleMark(SingleMark singleMark, Color color) {
|
||||
gc.setFill(color);
|
||||
System.out.println("DRAWING " + singleMark.getName() + " at " + singleMark.getX() + ", " + singleMark.getY());
|
||||
gc.fillOval(singleMark.getX(), singleMark.getY(),MARK_SIZE,MARK_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a gate mark which contains two single marks
|
||||
*
|
||||
* @param gateMark
|
||||
*/
|
||||
private void drawGateMark(GateMark gateMark) {
|
||||
Color color = Color.BLUE;
|
||||
|
||||
if (gateMark.getName().equals("Start")){
|
||||
color = Color.GREEN;
|
||||
}
|
||||
|
||||
if (gateMark.getName().equals("Finish")){
|
||||
color = Color.RED;
|
||||
}
|
||||
|
||||
drawSingleMark(gateMark.getSingleMark1(), color);
|
||||
drawSingleMark(gateMark.getSingleMark2(), color);
|
||||
|
||||
GraphicsContext gc = canvas.getGraphicsContext2D();
|
||||
gc.save();
|
||||
gc.setStroke(color);
|
||||
if (gateMark.getMarkType() == MarkType.OPEN_GATE)
|
||||
gc.setLineDashes(3, 5);
|
||||
|
||||
gc.setLineWidth(2);
|
||||
gc.strokeLine(
|
||||
gateMark.getSingleMark1().getX() + MARK_SIZE / 2,
|
||||
gateMark.getSingleMark1().getY() + MARK_SIZE / 2,
|
||||
gateMark.getSingleMark2().getX() + MARK_SIZE / 2,
|
||||
gateMark.getSingleMark2().getY() + MARK_SIZE / 2
|
||||
);
|
||||
gc.restore();
|
||||
}
|
||||
// /**
|
||||
// * Draw a given mark on canvas
|
||||
// *
|
||||
// * @param singleMark
|
||||
// */
|
||||
// private void drawSingleMark(SingleMark singleMark, Color color) {
|
||||
// gc.setFill(color);
|
||||
// System.out.println("DRAWING " + singleMark.getName() + " at " + singleMark.getX() + ", " + singleMark.getY());
|
||||
// gc.fillOval(singleMark.getX(), singleMark.getY(),MARK_SIZE,MARK_SIZE);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Draw a gate mark which contains two single marks
|
||||
// *
|
||||
// * @param gateMark
|
||||
// */
|
||||
// private void drawGateMark(GateMark gateMark) {
|
||||
// Color color = Color.BLUE;
|
||||
//
|
||||
// if (gateMark.getName().equals("Start")){
|
||||
// color = Color.GREEN;
|
||||
// }
|
||||
//
|
||||
// if (gateMark.getName().equals("Finish")){
|
||||
// color = Color.RED;
|
||||
// }
|
||||
//
|
||||
// drawSingleMark(gateMark.getSingleMark1(), color);
|
||||
// drawSingleMark(gateMark.getSingleMark2(), color);
|
||||
//
|
||||
// GraphicsContext gc = canvas.getGraphicsContext2D();
|
||||
// gc.save();
|
||||
// gc.setStroke(color);
|
||||
// if (gateMark.getMarkType() == MarkType.OPEN_GATE)
|
||||
// gc.setLineDashes(3, 5);
|
||||
//
|
||||
// gc.setLineWidth(2);
|
||||
// gc.strokeLine(
|
||||
// gateMark.getSingleMark1().getX() + MARK_SIZE / 2,
|
||||
// gateMark.getSingleMark1().getY() + MARK_SIZE / 2,
|
||||
// gateMark.getSingleMark2().getX() + MARK_SIZE / 2,
|
||||
// gateMark.getSingleMark2().getY() + MARK_SIZE / 2
|
||||
// );
|
||||
// gc.restore();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Calculates x and y location for every marker that fits it to the canvas the race will be drawn on.
|
||||
@@ -478,8 +489,8 @@ public class CanvasController {
|
||||
}
|
||||
referencePointX = Math.round(referencePointX);
|
||||
referencePointY = Math.round(referencePointY);
|
||||
referencePoint.setX((int) referencePointX);
|
||||
referencePoint.setY((int) referencePointY);
|
||||
// referencePoint.setX((int) referencePointX);
|
||||
// referencePoint.setY((int) referencePointY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -517,27 +528,31 @@ public class CanvasController {
|
||||
* are scaled according to the distanceScaleFactor variable.
|
||||
*/
|
||||
private void givePointsXY() {
|
||||
Point2D canvasLocation;
|
||||
List<Mark> allPoints = new ArrayList<>(raceViewController.getRace().getCourse());
|
||||
//Point2D canvasLocation;
|
||||
// List<Mark> allPoints = new ArrayList<>(raceViewController.getRace().getCourse());
|
||||
Set<Mark> unqiuePoints = new HashSet<>(raceViewController.getRace().getCourse());
|
||||
System.out.println("unqiuePoints = " + unqiuePoints);
|
||||
RaceObject markGroup;
|
||||
|
||||
for (Mark mark : allPoints) {
|
||||
for (Mark mark : unqiuePoints) {
|
||||
if (mark.getMarkType() != MarkType.SINGLE_MARK) {
|
||||
GateMark gateMark = (GateMark) mark;
|
||||
// canvasLocation = findScaledXY(gateMark.getSingleMark1());
|
||||
// gateMark.getSingleMark1().setX((int) canvasLocation.getX());
|
||||
// gateMark.getSingleMark1().setY((int) canvasLocation.getY());
|
||||
//
|
||||
// canvasLocation = findScaledXY(gateMark.getSingleMark2());
|
||||
// gateMark.getSingleMark2().setX((int) canvasLocation.getX());
|
||||
// gateMark.getSingleMark2().setY((int) canvasLocation.getY());
|
||||
|
||||
canvasLocation = findScaledXY(gateMark.getSingleMark1());
|
||||
gateMark.getSingleMark1().setX((int) canvasLocation.getX());
|
||||
gateMark.getSingleMark1().setY((int) canvasLocation.getY());
|
||||
|
||||
canvasLocation = findScaledXY(gateMark.getSingleMark2());
|
||||
gateMark.getSingleMark2().setX((int) canvasLocation.getX());
|
||||
gateMark.getSingleMark2().setY((int) canvasLocation.getY());
|
||||
markGroup = new MarkGroup(mark, findScaledXY(gateMark.getSingleMark1()), findScaledXY(gateMark.getSingleMark2()));
|
||||
group.getChildren().add(markGroup);
|
||||
}
|
||||
if (mark.getMarkType() == MarkType.CLOSED_GATE)
|
||||
((GateMark) mark).assignXYCentered();
|
||||
else {
|
||||
canvasLocation = findScaledXY(mark);
|
||||
mark.setX((int) canvasLocation.getX());
|
||||
mark.setY((int) canvasLocation.getY());
|
||||
// canvasLocation = findScaledXY(mark);
|
||||
// mark.setX((int) canvasLocation.getX());
|
||||
// mark.setY((int) canvasLocation.getY());
|
||||
markGroup = new MarkGroup(mark, findScaledXY(mark));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,11 @@ public class BoatGroup extends RaceObject{
|
||||
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 = 2000;
|
||||
private static double expectedUpdateInterval = 200;
|
||||
private static int WAKE_FRAME_INTERVAL = 40;
|
||||
|
||||
private Boat boat;
|
||||
private int wakeCounter = WAKE_FRAME_INTERVAL;
|
||||
|
||||
public BoatGroup (Boat boat, Color color){
|
||||
this.boat = boat;
|
||||
@@ -60,11 +62,7 @@ public class BoatGroup extends RaceObject{
|
||||
velocityObject.setY(VELOCITY_Y_OFFSET);
|
||||
velocityObject.relocate(velocityObject.getX(), velocityObject.getY());
|
||||
|
||||
wake.setLayoutX(0);
|
||||
wake.setLayoutY(0);
|
||||
wake.relocate(wake.getLayoutX(), wake.getLayoutY());
|
||||
|
||||
super.getChildren().addAll(boatPoly, wake, teamNameObject, velocityObject);
|
||||
super.getChildren().addAll(boatPoly, teamNameObject, velocityObject);
|
||||
}
|
||||
|
||||
private void initChildren (Color color) {
|
||||
@@ -78,10 +76,10 @@ public class BoatGroup extends RaceObject{
|
||||
* @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, double rotation) {
|
||||
public void moveGroupBy(double dx, double dy, double rotation) {
|
||||
super.setLayoutX(super.getLayoutX() + dx);
|
||||
super.setLayoutY(super.getLayoutY() + dy);
|
||||
rotateBoat(rotation);
|
||||
rotateTo(currentRotation + rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,8 +88,7 @@ public class BoatGroup extends RaceObject{
|
||||
* @param y The Y coordinate to move the boat to
|
||||
*/
|
||||
public void moveTo (double x, double y, double rotation) {
|
||||
super.currentRotation = 0;
|
||||
rotateBoat(rotation);
|
||||
rotateTo(rotation);
|
||||
moveTo(x, y);
|
||||
}
|
||||
|
||||
@@ -109,98 +106,77 @@ public class BoatGroup extends RaceObject{
|
||||
} else if (rotationalGoal < currentRotation && rotationalVelocity < 0) {
|
||||
rotation = rotationalVelocity * timeInterval;
|
||||
}
|
||||
moveBy(dx, dy, rotation);
|
||||
}
|
||||
|
||||
public void setDestination (double newXValue, double newYValue, double rotation) {
|
||||
this.pixelVelocityX = (newXValue - super.getLayoutX()) / expectedUpdateInterval;
|
||||
this.pixelVelocityY = (newYValue - super.getLayoutY()) / expectedUpdateInterval;
|
||||
//this.destinationX = newXValue;
|
||||
//this.destinationY = newYValue;
|
||||
this.rotationalGoal = rotation;
|
||||
// if (super.getLayoutY() >= newYValue && super.getLayoutX() <= newXValue)
|
||||
// rotationalGoal = 90 - rotationalGoal;
|
||||
// else if (super.getLayoutY() < newYValue && super.getLayoutX() <= newXValue)
|
||||
// rotationalGoal = 90 + rotationalGoal;
|
||||
// else if (super.getLayoutY() >= newYValue && super.getLayoutX() > newXValue)
|
||||
// rotationalGoal = 270 + rotationalGoal;
|
||||
// else
|
||||
// rotationalGoal = 270 - rotationalGoal;
|
||||
// if (Math.abs(360 - rotationalGoal + currentRotation) < Math.abs(rotationalGoal - currentRotation)) {
|
||||
// System.out.println("ROTATE");
|
||||
// this.rotationalVelocity = (360 - rotationalGoal + currentRotation) / expectedUpdateInterval;
|
||||
// } else {
|
||||
// this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval;
|
||||
// }
|
||||
if (Math.abs(rotationalGoal - currentRotation) > 180) {
|
||||
if (rotationalGoal - currentRotation >= 0) {
|
||||
this.rotationalVelocity = ((rotationalGoal - currentRotation) - 360) / expectedUpdateInterval;
|
||||
} else {
|
||||
this.rotationalVelocity = (360 + (rotationalGoal - currentRotation)) / expectedUpdateInterval;
|
||||
}
|
||||
} else {
|
||||
this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval;
|
||||
moveGroupBy(dx, dy, rotation);
|
||||
for (Node wake : super.getChildren().subList(4, super.getChildren().size())) {
|
||||
if (!((Wake) wake).updatePosition(timeInterval))
|
||||
super.getChildren().remove(wake);
|
||||
}
|
||||
if (wakeCounter-- == 0) {
|
||||
wakeCounter = WAKE_FRAME_INTERVAL;
|
||||
super.getChildren().add(
|
||||
new Wake(
|
||||
super.getLayoutX(), super.getLayoutY(), pixelVelocityX, pixelVelocityY
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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.rotationalGoal = Math.abs(
|
||||
Math.toDegrees(
|
||||
Math.atan(
|
||||
(newYValue - super.getLayoutY()) / (newXValue - super.getLayoutX())
|
||||
)
|
||||
)
|
||||
);
|
||||
if (super.getLayoutY() >= newYValue && super.getLayoutX() <= newXValue)
|
||||
rotationalGoal = 90 - rotationalGoal;
|
||||
else if (super.getLayoutY() < newYValue && super.getLayoutX() <= newXValue)
|
||||
rotationalGoal = 90 + rotationalGoal;
|
||||
else if (super.getLayoutY() >= newYValue && super.getLayoutX() > newXValue)
|
||||
rotationalGoal = 270 + rotationalGoal;
|
||||
else
|
||||
rotationalGoal = 270 - rotationalGoal;
|
||||
if (Math.abs(rotationalGoal - currentRotation) > 180) {
|
||||
if (rotationalGoal - currentRotation >= 0) {
|
||||
this.rotationalVelocity = ((rotationalGoal - currentRotation) - 360) / expectedUpdateInterval;
|
||||
public void setDestination (double newXValue, double newYValue, double rotation, int... raceIds) {
|
||||
if (hasRaceId(raceIds)) {
|
||||
this.pixelVelocityX = (newXValue - super.getLayoutX()) / expectedUpdateInterval;
|
||||
this.pixelVelocityY = (newYValue - super.getLayoutY()) / expectedUpdateInterval;
|
||||
this.rotationalGoal = rotation;
|
||||
if (Math.abs(rotationalGoal - currentRotation) > 180) {
|
||||
if (rotationalGoal - currentRotation >= 0) {
|
||||
this.rotationalVelocity = ((rotationalGoal - currentRotation) - 360) / expectedUpdateInterval;
|
||||
} else {
|
||||
this.rotationalVelocity = (360 + (rotationalGoal - currentRotation)) / expectedUpdateInterval;
|
||||
}
|
||||
} else {
|
||||
this.rotationalVelocity = (360 + (rotationalGoal - currentRotation)) / expectedUpdateInterval;
|
||||
this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval;
|
||||
}
|
||||
} else {
|
||||
this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval;
|
||||
}
|
||||
}
|
||||
|
||||
public void rotateBoat (double rotationDeg) {
|
||||
currentRotation += rotationDeg;
|
||||
public void setDestination (double newXValue, double newYValue, int... raceIDs) {
|
||||
if (hasRaceId(raceIDs)) {
|
||||
double 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;
|
||||
setDestination(newXValue, newYValue, rotation, raceIDs);
|
||||
}
|
||||
}
|
||||
|
||||
public void rotateTo (double rotation) {
|
||||
Node boatPoly = super.getChildren().get(0);
|
||||
boatPoly.getTransforms().clear();
|
||||
boatPoly.getTransforms().add(new Rotate(currentRotation, BOAT_WIDTH/2, 0));
|
||||
boatPoly.getTransforms().add(new Rotate(rotation, BOAT_WIDTH/2, 0));
|
||||
Node wake = super.getChildren().get(1);
|
||||
wake.getTransforms().clear();
|
||||
wake.getTransforms().add(new Translate(0, BOAT_HEIGHT));
|
||||
wake.getTransforms().add(new Rotate(currentRotation, BOAT_WIDTH/2, -BOAT_HEIGHT));
|
||||
}
|
||||
|
||||
public static double getExpectedUpdateInterval() {
|
||||
return expectedUpdateInterval;
|
||||
}
|
||||
|
||||
public static void setExpectedUpdateInterval(double expectedUpdateInterval) {
|
||||
BoatGroup.expectedUpdateInterval = expectedUpdateInterval;
|
||||
wake.getTransforms().add(new Rotate(rotation, BOAT_WIDTH/2, -BOAT_HEIGHT));
|
||||
}
|
||||
|
||||
public void forceRotation () {
|
||||
rotateBoat (rotationalGoal - currentRotation);
|
||||
rotateTo (rotationalGoal);
|
||||
}
|
||||
|
||||
public void toggleAnnotations () {
|
||||
super.getChildren().get(1).setVisible(false);
|
||||
super.getChildren().get(2).setVisible(false);
|
||||
super.getChildren().get(3).setVisible(false);
|
||||
for (Node node : super.getChildren().subList(1, super.getChildren().size())) {
|
||||
node.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public Boat getBoat() {
|
||||
@@ -214,4 +190,8 @@ public class BoatGroup extends RaceObject{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int[] getRaceIds () {
|
||||
return new int[] {boat.getId()};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,11 +8,14 @@ import javafx.scene.Group;
|
||||
*/
|
||||
public abstract class RaceObject extends Group {
|
||||
|
||||
double rotationalGoal;
|
||||
double currentRotation;
|
||||
double rotationalVelocity;
|
||||
double pixelVelocityX;
|
||||
double pixelVelocityY;
|
||||
//Time between sections of race - Should be changed to 200 for actual program.
|
||||
protected static double expectedUpdateInterval = 2000;
|
||||
|
||||
protected double rotationalGoal;
|
||||
protected double currentRotation;
|
||||
protected double rotationalVelocity;
|
||||
protected double pixelVelocityX;
|
||||
protected double pixelVelocityY;
|
||||
|
||||
public boolean isSamePos (Point2D point) {
|
||||
return point.getX() == super.getLayoutX() && point.getY() == super.getLayoutY();
|
||||
@@ -21,12 +24,33 @@ public abstract class RaceObject extends Group {
|
||||
public Point2D getPosition () {
|
||||
return new Point2D(super.getLayoutX(), getLayoutY());
|
||||
}
|
||||
public abstract void setDestination (double x, double y, double rotation);
|
||||
public abstract void setDestination (double x, double y);
|
||||
|
||||
public static double getExpectedUpdateInterval() {
|
||||
return expectedUpdateInterval;
|
||||
}
|
||||
|
||||
public static void setExpectedUpdateInterval(double expectedUpdateInterval) {
|
||||
RaceObject.expectedUpdateInterval = expectedUpdateInterval;
|
||||
}
|
||||
|
||||
public abstract void setDestination (double x, double y, double rotation, int... raceIds);
|
||||
|
||||
public abstract void setDestination (double x, double y, int... raceIds);
|
||||
|
||||
public abstract void updatePosition (double timeInterval);
|
||||
|
||||
public abstract void moveTo (double x, double y, double rotation);
|
||||
|
||||
public abstract void moveTo (double x, double y);
|
||||
|
||||
public abstract void moveGroupBy(double x, double y, double rotation);
|
||||
|
||||
public abstract void rotateTo (double rotation);
|
||||
|
||||
public abstract boolean hasRaceId (int... raceIds);
|
||||
|
||||
public abstract int[] getRaceIds ();
|
||||
|
||||
public abstract void toggleAnnotations ();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package seng302.models;
|
||||
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Arc;
|
||||
import javafx.scene.shape.ArcType;
|
||||
|
||||
/**
|
||||
* Created by CJIRWIN on 27/04/2017.
|
||||
*/
|
||||
class Wake extends Arc {
|
||||
|
||||
private static int VELOCITY_SCALE_FACTOR = 3;
|
||||
private static int MAX_LIFESPAN = 180;
|
||||
private static double LIFESPAN_PER_FRAME = 1.0 / MAX_LIFESPAN;
|
||||
|
||||
private double velocityX;
|
||||
private double velocityY;
|
||||
private int lifespan = MAX_LIFESPAN;
|
||||
|
||||
Wake (double startingX, double startingY, double velocityX, double velocityY) {
|
||||
super(startingX, startingY, 25, 15, 160, 40);
|
||||
super.setFill(Color.BLUE);
|
||||
super.setType(ArcType.OPEN);
|
||||
super.setStrokeWidth(2.0);
|
||||
this.velocityX = -velocityX;
|
||||
this.velocityY = -velocityY;
|
||||
}
|
||||
|
||||
boolean updatePosition (double timeInterval) {
|
||||
lifespan--;
|
||||
super.setLayoutX(super.getLayoutX() + velocityX * timeInterval);
|
||||
super.setLayoutX(super.getLayoutX() + velocityX * timeInterval);
|
||||
super.setOpacity(LIFESPAN_PER_FRAME * lifespan * super.getOpacity());
|
||||
return lifespan == 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,15 +48,4 @@ public class GateMark extends Mark {
|
||||
return (this.getSingleMark1().getLongitude());
|
||||
}
|
||||
|
||||
public void assignXYCentered () {
|
||||
System.out.println("POSSIBLE GOOF " + xValue + " " + yValue);
|
||||
System.out.println(singleMark1.getX() + " " + singleMark1.getY());
|
||||
System.out.println(singleMark2.getX() + " " + singleMark2.getY());
|
||||
double dx = singleMark2.getX() - singleMark1.getX();
|
||||
System.out.println("dx + " + dx);
|
||||
double dy = singleMark2.getY() - singleMark1.getY();
|
||||
xValue = (int) Math.round(singleMark1.getX() + dx / 2);
|
||||
yValue = (int) Math.round(singleMark1.getY() + dy / 2);
|
||||
System.out.println("PROBABLE GAAF " + xValue + " " + yValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ public abstract class Mark {
|
||||
private double latitude;
|
||||
private double longitude;
|
||||
private int id;
|
||||
Integer xValue;
|
||||
Integer yValue;
|
||||
|
||||
/**
|
||||
* Create a mark instance by passing its name and type
|
||||
@@ -127,22 +125,6 @@ public abstract class Mark {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public int getX () {
|
||||
return xValue;
|
||||
}
|
||||
|
||||
public int getY () {
|
||||
return yValue;
|
||||
}
|
||||
|
||||
public void setX (int x) {
|
||||
this.xValue = x;
|
||||
}
|
||||
|
||||
public void setY (int y) {
|
||||
this.yValue = y;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,35 @@
|
||||
package seng302.models.mark;
|
||||
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Circle;
|
||||
import javafx.scene.shape.Line;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import seng302.models.RaceObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by CJIRWIN on 26/04/2017.
|
||||
*/
|
||||
public class MarkGroup extends RaceObject {
|
||||
|
||||
private static int MARK_RADIUS = 5;
|
||||
|
||||
private Mark mark;
|
||||
private double pixelVelocityXM1;
|
||||
private double pixelVelocityYM1;
|
||||
private double pixelVelocityXM2;
|
||||
private double pixelVelocityYM3;
|
||||
private static int MARK_RADIUS = 5;
|
||||
private static int LINE_THICKNESS = 2;
|
||||
private static double DASHED_GAP_LEN = 2d;
|
||||
private static double DASHED_LINE_LEN = 5d;
|
||||
|
||||
private List<Mark> marks = new ArrayList<>();
|
||||
private Mark mainMark;
|
||||
private double[] nodePixelVelocitiesX;
|
||||
private double[] nodePixelVelocitiesY;
|
||||
private Point2D[] nodeDestinations;
|
||||
|
||||
public MarkGroup (Mark mark, Point2D... points) {
|
||||
marks.add(mark);
|
||||
mainMark = mark;
|
||||
Color color = Color.BLACK;
|
||||
if (mark.getName().equals("Start")){
|
||||
color = Color.GREEN;
|
||||
@@ -31,11 +39,20 @@ public class MarkGroup extends RaceObject {
|
||||
if (mark.getMarkType() == MarkType.SINGLE_MARK) {
|
||||
super.getChildren().add(new Circle(0, 0, MARK_RADIUS, color));
|
||||
} else {
|
||||
super.getChildren().add(new Circle(0, 0, MARK_RADIUS, color));
|
||||
marks.add(((GateMark) mark).getSingleMark1());
|
||||
marks.add(((GateMark) mark).getSingleMark2());
|
||||
super.getChildren().add(
|
||||
new Circle(
|
||||
points[1].getX() - points[0].getX(),
|
||||
points[1].getY() - points[0].getY(),
|
||||
(points[1].getX() - points[0].getX() / 2),
|
||||
(points[1].getY() - points[0].getY() / 2),
|
||||
MARK_RADIUS,
|
||||
color
|
||||
)
|
||||
);
|
||||
super.getChildren().add(
|
||||
new Circle(
|
||||
-(points[1].getX() - points[0].getX() / 2),
|
||||
-(points[1].getY() - points[0].getY() / 2),
|
||||
MARK_RADIUS,
|
||||
color
|
||||
)
|
||||
@@ -46,33 +63,60 @@ public class MarkGroup extends RaceObject {
|
||||
points[1].getX() - points[0].getX(),
|
||||
points[1].getY() - points[0].getY()
|
||||
);
|
||||
line.setStrokeWidth(2);
|
||||
line.setStrokeWidth(LINE_THICKNESS);
|
||||
if (mark.getMarkType() == MarkType.OPEN_GATE) {
|
||||
line.getStrokeDashArray().addAll(3d, 5d);
|
||||
line.getStrokeDashArray().addAll(DASHED_GAP_LEN, DASHED_LINE_LEN);
|
||||
}
|
||||
super.getChildren().add(line);
|
||||
nodePixelVelocitiesX = new double[2];
|
||||
nodePixelVelocitiesY = new double[2];
|
||||
nodeDestinations = new Point2D[2];
|
||||
}
|
||||
this.mark = mark;
|
||||
moveTo(points[0].getX(), points[0].getY());
|
||||
}
|
||||
|
||||
public void setDestination (double x, double y, double rotation) {
|
||||
|
||||
public void setDestination (double x, double y, double rotation, int... raceIds) {
|
||||
setDestination(x, y, raceIds);
|
||||
this.rotationalGoal = rotation;
|
||||
if (Math.abs(rotationalGoal - currentRotation) > 180) {
|
||||
if (rotationalGoal - currentRotation >= 0) {
|
||||
this.rotationalVelocity = ((rotationalGoal - currentRotation) - 360) / expectedUpdateInterval;
|
||||
} else {
|
||||
this.rotationalVelocity = (360 + (rotationalGoal - currentRotation)) / expectedUpdateInterval;
|
||||
}
|
||||
} else {
|
||||
this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval;
|
||||
}
|
||||
}
|
||||
|
||||
public void setDestination (double x, double y) {
|
||||
|
||||
public void setDestination (double x, double y, int... raceIds) {
|
||||
int childrenIndex = -1;
|
||||
for (Mark mark : marks) {
|
||||
for (int id : raceIds)
|
||||
if (id == mark.getId() && childrenIndex != -1)
|
||||
setDestinationChild(x, y, childrenIndex);
|
||||
else if (id == mark.getId())
|
||||
setDestinationGroup(x, y);
|
||||
childrenIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
public void setMarkDestination (int markId, double x, double y) {
|
||||
|
||||
}
|
||||
public void updatePosition (double timeInterval) {
|
||||
|
||||
private void setDestinationChild (double x, double y, int childIndex) {
|
||||
double relativeX = x - super.getLayoutX();
|
||||
double relativeY = y - super.getLayoutY();
|
||||
this.nodeDestinations[childIndex] = new Point2D(relativeX, relativeY);
|
||||
this.nodePixelVelocitiesX[childIndex] = (relativeX - super.getChildren().get(childIndex).getLayoutX()) / expectedUpdateInterval;
|
||||
this.nodePixelVelocitiesY[childIndex] = (relativeY - super.getChildren().get(childIndex).getLayoutY()) / expectedUpdateInterval;
|
||||
}
|
||||
|
||||
public void moveTo (double x, double y, double rotation) {
|
||||
moveTo(x, y);
|
||||
private void setDestinationGroup (double x, double y) {
|
||||
pixelVelocityX = (x - super.getLayoutX()) / expectedUpdateInterval;
|
||||
pixelVelocityY = (y - super.getLayoutY()) / expectedUpdateInterval;
|
||||
}
|
||||
|
||||
|
||||
public void rotateTo (double rotation) {
|
||||
super.getTransforms().clear();
|
||||
super.getTransforms().add(
|
||||
new Rotate(
|
||||
@@ -83,20 +127,74 @@ public class MarkGroup extends RaceObject {
|
||||
);
|
||||
}
|
||||
|
||||
public void updatePosition (double timeInterval) {
|
||||
double x = pixelVelocityX * timeInterval;
|
||||
double y = pixelVelocityY * timeInterval;
|
||||
double rotation = rotationalVelocity * timeInterval;
|
||||
moveGroupBy(x, y, rotation);
|
||||
updateChildren(timeInterval);
|
||||
}
|
||||
|
||||
public void moveGroupBy (double x, double y, double rotation) {
|
||||
super.setLayoutX(super.getLayoutX() + x);
|
||||
super.setLayoutY(super.getOpacity() + y);
|
||||
rotateTo(rotation + currentRotation);
|
||||
}
|
||||
|
||||
private void updateChildren (double timeInterval) {
|
||||
if (mainMark.getMarkType() != MarkType.SINGLE_MARK) {
|
||||
Circle mark = (Circle) super.getChildren().get(0);
|
||||
if (nodePixelVelocitiesX[0] > 0 && mark.getLayoutX() >= nodeDestinations[0].getX()) {
|
||||
nodePixelVelocitiesX[0] = 0;
|
||||
} else if (nodePixelVelocitiesX[0] < 0 && mark.getLayoutX() <= nodeDestinations[0].getX()) {
|
||||
nodePixelVelocitiesX[0] = 0;
|
||||
} else {
|
||||
mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[0] * timeInterval);
|
||||
mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[0] * timeInterval);
|
||||
}
|
||||
if (nodePixelVelocitiesY[0] >= 0 && mark.getLayoutY() > nodeDestinations[0].getY()) {
|
||||
nodePixelVelocitiesY[0] = 0;
|
||||
} else if (nodePixelVelocitiesY[0] < 0 && mark.getLayoutY() <= nodeDestinations[0].getY()) {
|
||||
nodePixelVelocitiesY[0] = 0;
|
||||
} else {
|
||||
mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[0] * timeInterval);
|
||||
mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[0] * timeInterval);
|
||||
}
|
||||
mark = (Circle) super.getChildren().get(1);
|
||||
if (nodePixelVelocitiesX[1] > 0 && mark.getLayoutX() >= nodeDestinations[1].getX()) {
|
||||
nodePixelVelocitiesX[1] = 0;
|
||||
} else if (nodePixelVelocitiesX[1] < 0 && mark.getLayoutX() <= nodeDestinations[1].getX()) {
|
||||
nodePixelVelocitiesX[1] = 0;
|
||||
} else {
|
||||
mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[1] * timeInterval);
|
||||
mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[1] * timeInterval);
|
||||
}
|
||||
if (nodePixelVelocitiesY[1] >= 0 && mark.getLayoutY() > nodeDestinations[1].getY()) {
|
||||
nodePixelVelocitiesY[1] = 0;
|
||||
} else if (nodePixelVelocitiesY[1] < 0 && mark.getLayoutY() <= nodeDestinations[1].getY()) {
|
||||
nodePixelVelocitiesY[1] = 0;
|
||||
} else {
|
||||
mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[1] * timeInterval);
|
||||
mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[1] * timeInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void moveTo (double x, double y, double rotation) {
|
||||
moveTo(x, y);
|
||||
rotateTo(rotation);
|
||||
}
|
||||
|
||||
public void moveTo (double x, double y) {
|
||||
super.setLayoutX(x);
|
||||
super.setLayoutY(y);
|
||||
}
|
||||
|
||||
public boolean hasRaceId (int... raceIds) {
|
||||
for (int id : raceIds) {
|
||||
for (int id : raceIds)
|
||||
for (Mark mark : marks)
|
||||
if (id == mark.getId())
|
||||
return true;
|
||||
if (mark.getMarkType() != MarkType.SINGLE_MARK) {
|
||||
if (id == ((GateMark) mark).getSingleMark1().getId() || id == ((GateMark) mark).getSingleMark2().getId())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void toggleAnnotations () {
|
||||
@@ -111,4 +209,12 @@ public class MarkGroup extends RaceObject {
|
||||
MARK_RADIUS = markRadius;
|
||||
}
|
||||
|
||||
public int[] getRaceIds () {
|
||||
int[] idArray = new int[marks.size()];
|
||||
int i = 0;
|
||||
for (Mark mark : marks)
|
||||
idArray[i++] = mark.getId();
|
||||
return idArray;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user