diff --git a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java index 0d9f0562..986c778d 100644 --- a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java +++ b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java @@ -4,6 +4,7 @@ package visualiser.model; import javafx.scene.paint.Color; import javafx.scene.paint.LinearGradient; import javafx.scene.paint.Paint; +import javafx.scene.text.Font; import javafx.scene.transform.Rotate; import network.Messages.Enums.BoatStatusEnum; import shared.dataInput.RaceDataSource; @@ -12,6 +13,7 @@ import shared.model.*; import java.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; import java.util.List; /** @@ -141,8 +143,14 @@ public class ResizableRaceCanvas extends ResizableCanvas { * Draws a circle with a given diameter, centred on a given graph coordinate. * @param center The center coordinate of the circle. * @param diameter The diameter of the circle. + * @param paint The paint to use for the circle. */ - private void drawCircle(GraphCoordinate center, double diameter) { + private void drawCircle(GraphCoordinate center, double diameter, Paint paint) { + + gc.save(); + + gc.setFill(paint); + gc.setStroke(paint); //The graphCoordinates are for the center of the point, so we offset them to get the corner coordinate. gc.fillOval( @@ -150,6 +158,7 @@ public class ResizableRaceCanvas extends ResizableCanvas { center.getY() - (diameter / 2), diameter, diameter ); + gc.restore(); } /** @@ -158,20 +167,16 @@ public class ResizableRaceCanvas extends ResizableCanvas { * @param graphCoordinateA Starting Point of the line in GraphCoordinate. * @param graphCoordinateB End Point of the line in GraphCoordinate. * @param paint Colour the line is to coloured. + * @param lineWidth The width of the line. */ - private void drawLine(GraphCoordinate graphCoordinateA, GraphCoordinate graphCoordinateB, Paint paint) { + private void drawLine(GraphCoordinate graphCoordinateA, GraphCoordinate graphCoordinateB, Paint paint, double lineWidth) { + + gc.save(); gc.setStroke(paint); gc.setFill(paint); - - double endPointDiameter = 6; - - //Draw first end-point. - drawCircle(graphCoordinateA, endPointDiameter); - - //Draw second end-point. - drawCircle(graphCoordinateB, endPointDiameter); + gc.setLineWidth(lineWidth); //Draw line between them. gc.strokeLine( @@ -180,25 +185,10 @@ public class ResizableRaceCanvas extends ResizableCanvas { graphCoordinateB.getX(), graphCoordinateB.getY() ); + gc.restore(); } - /** - * Display a point on the Canvas. It has a diameter of 10 pixels. - * - * @param graphCoordinate Coordinate that the point is to be displayed at. - * @param paint Paint to use for the point. - */ - private void drawPoint(GraphCoordinate graphCoordinate, Paint paint) { - - //Set paint. - gc.setFill(paint); - - double pointDiameter = 10; - - //Draw the point. - drawCircle(graphCoordinate, pointDiameter); - } /** @@ -210,8 +200,10 @@ public class ResizableRaceCanvas extends ResizableCanvas { * @param coordinate coordinate the text appears * @param timeToNextMark The time until the boat reaches the next mark. * @param timeSinceLastMark The time since the boat passed the last mark. + * @param paint The color of the text. + * @param fontSize The size of the font. */ - private void drawText(String name, String abbrev, double speed, GraphCoordinate coordinate, String timeToNextMark, String timeSinceLastMark) { + private void drawText(String name, String abbrev, double speed, GraphCoordinate coordinate, String timeToNextMark, String timeSinceLastMark, Paint paint, double fontSize) { //The text to draw. Built during the function. String text = ""; @@ -257,8 +249,15 @@ public class ResizableRaceCanvas extends ResizableCanvas { yCoord += 30; } + gc.save(); + + gc.setStroke(paint); + gc.setFont(new Font(gc.getFont().getName(), fontSize)); + //Draw text. gc.fillText(text, xCoord, yCoord); + + gc.restore(); } @@ -274,7 +273,9 @@ public class ResizableRaceCanvas extends ResizableCanvas { boat.getCurrentSpeed(), this.map.convertGPS(boat.getCurrentPosition()), boat.getTimeToNextMarkFormatted(this.visualiserRace.getVisualiserRaceState().getRaceClock().getCurrentTime()), - boat.getTimeSinceLastMarkFormatted(this.visualiserRace.getVisualiserRaceState().getRaceClock().getCurrentTime()) ); + boat.getTimeSinceLastMarkFormatted(this.visualiserRace.getVisualiserRaceState().getRaceClock().getCurrentTime()), + Color.BLACK, + 20 ); } @@ -286,29 +287,51 @@ public class ResizableRaceCanvas extends ResizableCanvas { */ private void drawBoats() { - for (VisualiserBoat boat : new ArrayList<>(visualiserRace.getVisualiserRaceState().getBoats())) { + List boats = new ArrayList<>(visualiserRace.getVisualiserRaceState().getBoats()); + //Sort to ensure we draw boats in consistent order. + boats.sort(Comparator.comparingInt(Boat::getSourceID)); - //Draw the boat. - drawBoat(boat); + //Current draw order: + // track points + // wake + // boat + // text + //Track points. + for (VisualiserBoat boat : boats) { + drawTrack(boat); + } + + //Wake. + for (VisualiserBoat boat : boats) { //Only draw wake if they are currently racing. if (boat.getStatus() == BoatStatusEnum.RACING) { drawWake(boat); } + } + + //Boat. + for (VisualiserBoat boat : boats) { + drawBoat(boat); + } + + //Text. + for (VisualiserBoat boat : boats) { + drawBoatText(boat); + } + + +/* //If the race hasn't started, we set the time since last mark to the current time, to ensure we don't start counting until the race actually starts. if ((boat.getStatus() != BoatStatusEnum.RACING) && (boat.getStatus() == BoatStatusEnum.FINISHED)) { boat.setTimeAtLastMark(visualiserRace.getVisualiserRaceState().getRaceClock().getCurrentTime()); } +*/ - //Draw boat label. - drawBoatText(boat); - //Draw track. - drawTrack(boat); - } } @@ -341,12 +364,14 @@ public class ResizableRaceCanvas extends ResizableCanvas { //The above shape is essentially a triangle 12px wide, and 24px long. + + gc.save(); + //Draw the boat. gc.setFill(boat.getColor()); - gc.save(); rotate(boat.getBearing().degrees(), pos.getX(), pos.getY()); - gc.fillPolygon(x, y, 3); + gc.fillPolygon(x, y, x.length); gc.restore(); @@ -375,12 +400,14 @@ public class ResizableRaceCanvas extends ResizableCanvas { //The above shape is essentially a triangle 24px wide, and 48 long. + + gc.save(); + //Draw the boat. gc.setFill(Color.BLACK); - gc.save(); rotate(boat.getBearing().degrees(), pos.getX(), pos.getY()); - gc.fillPolygon(x, y, 3); + gc.fillPolygon(x, y, x.length); gc.restore(); } @@ -396,8 +423,15 @@ public class ResizableRaceCanvas extends ResizableCanvas { GraphCoordinate wakeFrom = this.map.convertGPS(boat.getCurrentPosition()); GraphCoordinate wakeTo = this.map.convertGPS(boat.getWake()); - //Draw. - drawLine(wakeFrom, wakeTo, boat.getColor()); + double lineWidth = 4; + double endPointDiameter = 12; + + //Line. + drawLine(wakeFrom, wakeTo, boat.getColor(), lineWidth); + + //Draw end-point. + drawCircle(wakeTo, endPointDiameter, Color.BLACK); + } @@ -423,8 +457,10 @@ public class ResizableRaceCanvas extends ResizableCanvas { //Calculate screen position. GraphCoordinate mark1 = this.map.convertGPS(mark.getPosition()); + double diameter = 10; + //Draw. - drawPoint(mark1, Color.LIMEGREEN); + drawCircle(mark1, diameter, Color.LIMEGREEN); } @@ -462,6 +498,8 @@ public class ResizableRaceCanvas extends ResizableCanvas { */ private void drawBoundary() { + gc.save(); + //Prepare to draw. gc.setLineWidth(1); gc.setFill(Color.AQUA); @@ -484,6 +522,8 @@ public class ResizableRaceCanvas extends ResizableCanvas { //Draw the boundary. gc.fillPolygon(xpoints, ypoints, xpoints.length); + gc.restore(); + } /** @@ -496,7 +536,6 @@ public class ResizableRaceCanvas extends ResizableCanvas { this.map.setGPSTopLeft(visualiserRace.getVisualiserRaceState().getRaceDataSource().getMapTopLeft()); this.map.setGPSBotRight(visualiserRace.getVisualiserRaceState().getRaceDataSource().getMapBottomRight()); - gc.setLineWidth(2); clear(); @@ -604,6 +643,8 @@ public class ResizableRaceCanvas extends ResizableCanvas { GraphCoordinate c1 = this.map.convertGPS(controlPoint); GraphCoordinate c2 = this.map.convertGPS(controlPoint2); + gc.save(); + gc.setLineWidth(2); gc.setStroke(Color.MEDIUMAQUAMARINE); @@ -614,20 +655,26 @@ public class ResizableRaceCanvas extends ResizableCanvas { gc.bezierCurveTo(c1.getX(), c1.getY(), c2.getX(), c2.getY(), curvePointEnd.getX(), curvePointEnd.getY()); gc.stroke(); gc.closePath(); - gc.save(); + //gc.save(); + gc.restore(); return pointToEndCurve; }else{//last leg so no curve GraphCoordinate startPath = this.map.convertGPS(legStartPoint); GraphCoordinate endPath = this.map.convertGPS(legs.get(index).getEndCompoundMark().getAverageGPSCoordinate()); + gc.save(); + gc.beginPath(); gc.moveTo(startPath.getX(), startPath.getY()); gc.lineTo(endPath.getX(), endPath.getY()); gc.stroke(); gc.closePath(); - gc.save(); + //gc.save(); drawArrowHead(legStartPoint, legs.get(index).getEndCompoundMark().getAverageGPSCoordinate()); + + gc.restore(); + return null; } } @@ -664,15 +711,22 @@ public class ResizableRaceCanvas extends ResizableCanvas { //Check that track points are enabled. if (this.annoPath) { + gc.save(); + + gc.setLineWidth(3); + //Apply the boat color. gc.setFill(boat.getColor()); + gc.setStroke(boat.getColor()); - double[] xPoints = new double[boat.getTrack().size()]; - double[] yPoints = new double[boat.getTrack().size()]; + List trackPoints = new ArrayList<>(boat.getTrack()); + + double[] xPoints = new double[trackPoints.size()]; + double[] yPoints = new double[trackPoints.size()]; int index = 0; //Copy trackpoint locations to x/y arrays. - for (TrackPoint point : new ArrayList<>(boat.getTrack())) { + for (TrackPoint point : trackPoints) { //Convert the GPSCoordinate to a screen coordinate. GraphCoordinate scaledCoordinate = this.map.convertGPS(point.getCoordinate()); @@ -684,6 +738,8 @@ public class ResizableRaceCanvas extends ResizableCanvas { } gc.strokePolyline(xPoints, yPoints, xPoints.length); + + gc.restore(); } } diff --git a/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java b/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java index 0d65d7ad..6b91e6ac 100644 --- a/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java +++ b/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java @@ -53,7 +53,7 @@ public class VisualiserBoat extends Boat { /** * Scalar used to scale the boat's wake. */ - private static final double wakeScale = 20; + private static final double wakeScale = 25; /** * If true then this boat has been allocated to the client. diff --git a/racevisionGame/src/main/java/visualiser/model/VisualiserRaceState.java b/racevisionGame/src/main/java/visualiser/model/VisualiserRaceState.java index b1767cd5..a1f21844 100644 --- a/racevisionGame/src/main/java/visualiser/model/VisualiserRaceState.java +++ b/racevisionGame/src/main/java/visualiser/model/VisualiserRaceState.java @@ -225,11 +225,7 @@ public class VisualiserRaceState extends RaceState { Leg startingLeg = getLegs().get(0); for (VisualiserBoat boat : boats) { - boat.setCurrentLeg(startingLeg); - boat.setTimeAtLastMark(getRaceClock().getCurrentTime()); - boat.setCurrentPosition(new GPSCoordinate(0, 0)); - } }