Merged annotation toggle and DNF features with heading visualisation.
This commit is contained in:
@@ -2,15 +2,12 @@ package seng302.Controllers;
|
||||
|
||||
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.SplitPane;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
@@ -39,6 +36,11 @@ public class RaceController extends Controller {
|
||||
@FXML
|
||||
SplitPane ongoingRacePane;
|
||||
|
||||
@FXML
|
||||
CheckBox showFPS;
|
||||
|
||||
@FXML
|
||||
CheckBox showAnno;
|
||||
|
||||
@FXML
|
||||
Label timer;
|
||||
@@ -67,8 +69,7 @@ public class RaceController extends Controller {
|
||||
public void updateMap(ObservableList<BoatInRace> boats) {
|
||||
BoatInRace[] boatInRaces = new BoatInRace[boats.size()];
|
||||
raceMap.setBoats(boats.toArray(boatInRaces));
|
||||
raceMap.drawRaceMap();
|
||||
raceMap.updateBoats();
|
||||
raceMap.update();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,7 +115,17 @@ public class RaceController extends Controller {
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
|
||||
//listener for fps
|
||||
showFPS.selectedProperty().addListener(new ChangeListener<Boolean>() {
|
||||
public void changed(ObservableValue<? extends Boolean> ov,
|
||||
Boolean old_val, Boolean new_val) {
|
||||
if (showFPS.isSelected()){
|
||||
FPS.setVisible(true);
|
||||
} else {
|
||||
FPS.setVisible(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,6 +137,7 @@ public class RaceController extends Controller {
|
||||
private void startRace(int scaleFactor) {
|
||||
BoatInRace[] boats = generateAC35Competitors();
|
||||
raceMap = new ResizableRaceCanvas();
|
||||
raceMap.setMouseTransparent(true);
|
||||
raceMap.widthProperty().bind(canvasBase.widthProperty());
|
||||
raceMap.heightProperty().bind(canvasBase.heightProperty());
|
||||
raceMap.setBoats(boats);
|
||||
@@ -142,6 +154,15 @@ public class RaceController extends Controller {
|
||||
|
||||
|
||||
new Thread((race)).start();
|
||||
|
||||
//listener for annotation
|
||||
showAnno.selectedProperty().addListener(new ChangeListener<Boolean>() {
|
||||
public void changed(ObservableValue<? extends Boolean> ov,
|
||||
Boolean old_val, Boolean new_val) {
|
||||
raceMap.toggleAnno();
|
||||
raceMap.update();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public class Boat {
|
||||
*/
|
||||
public Boat(String name, double velocity, String abbrev) {
|
||||
this.velocity = velocity;
|
||||
this.velocityProp = new SimpleStringProperty(String.valueOf(velocity* 1.94384));
|
||||
this.velocityProp = new SimpleStringProperty(String.valueOf(Math.round(velocity)));
|
||||
this.abbrev = abbrev;
|
||||
this.name = new SimpleStringProperty(name);
|
||||
}
|
||||
@@ -48,6 +48,10 @@ public class Boat {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the speed of the boat in knots.
|
||||
* @param velocity speed in knots
|
||||
*/
|
||||
public void setVelocity(double velocity) {
|
||||
this.velocity = velocity;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,12 @@ public class BoatInRace extends Boat {
|
||||
return calculateHeading(azimuth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the end of the boat's wake, which is 180 degrees
|
||||
* from the boat's heading, and whose length is proportional to the boat's
|
||||
* speed.
|
||||
* @return GPSCoordinate of wake endpoint.
|
||||
*/
|
||||
public GPSCoordinate getWake() {
|
||||
double reverseHeading = calculateHeading() - 180;
|
||||
double distance = Constants.wakeScale * getVelocity();
|
||||
|
||||
@@ -8,6 +8,7 @@ import javafx.collections.ObservableList;
|
||||
import seng302.Controllers.RaceController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Parent class for races
|
||||
@@ -164,10 +165,19 @@ public abstract class Race implements Runnable {
|
||||
Platform.runLater(() -> {controller.setTimer(time);});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the calculated fps to the fps label
|
||||
* @param fps The new calculated fps value
|
||||
*/
|
||||
private void updateFPS(int fps) {
|
||||
Platform.runLater(() -> {controller.setFrames("FPS: " + fps);});
|
||||
}
|
||||
|
||||
private boolean doNotFinish() {
|
||||
Random rand = new Random();
|
||||
return rand.nextInt(100) < 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Race Simulation, playing the race start to finish with the timescale.
|
||||
* This prints the boats participating, the order that the events occur in time order, and the respective information of the events.
|
||||
@@ -203,6 +213,11 @@ public abstract class Race implements Runnable {
|
||||
if (controller != null) controller.updateMap(startingBoats);
|
||||
if (timerEnabled)
|
||||
updateTime(calcTimer());
|
||||
} else {
|
||||
//Exit animation timer
|
||||
updateTime(calcTimer());
|
||||
updateFPS(0); //race ended so fps = 0
|
||||
stop(); //exit animation timer
|
||||
}
|
||||
fps++;
|
||||
if ((System.currentTimeMillis()-timeCurrent) > 1000){
|
||||
@@ -240,6 +255,10 @@ public abstract class Race implements Runnable {
|
||||
boatsFinished++;
|
||||
boat.setFinished(true);
|
||||
boat.setTimeFinished(timeElapsed);
|
||||
} else if(doNotFinish()) {
|
||||
boatsFinished++;
|
||||
boat.setFinished(true);
|
||||
boat.setCurrentLeg(new Leg("DNF",-1));
|
||||
} else {
|
||||
//Calculate how much the boat overshot the marker by
|
||||
boat.setDistanceTravelledInLeg(boat.getDistanceTravelledInLeg() - boat.getCurrentLeg().getDistance());
|
||||
|
||||
@@ -19,6 +19,7 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
private GraphicsContext gc;
|
||||
private RaceMap map;
|
||||
private BoatInRace[] boats;
|
||||
private boolean raceAnno = true;
|
||||
|
||||
/**
|
||||
* Sets the boats that are to be displayed in this race.
|
||||
@@ -141,6 +142,14 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
gc.fillText(text, xCoord, yCoord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws race map with up to date data.
|
||||
*/
|
||||
public void update() {
|
||||
this.drawRaceMap();
|
||||
this.updateBoats();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the Race Map
|
||||
*/
|
||||
@@ -177,18 +186,36 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
displayArrow(new GraphCoordinate(500, 20), 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws boats while race in progress, when leg heading is set.
|
||||
*/
|
||||
public void updateBoats() {
|
||||
if (boats != null) {
|
||||
for (BoatInRace boat : boats) {
|
||||
if (boat != null && !boat.getCurrentLeg().getName().equals("Finish")) {
|
||||
boolean finished = boat.getCurrentLeg().getName().equals("Finish") || boat.getCurrentLeg().getName().equals("DNF");
|
||||
if (!finished) {
|
||||
displayBoat(boat, boat.calculateHeading());
|
||||
GraphCoordinate wakeFrom = this.map.convertGPS(boat.getCurrentPosition());
|
||||
GraphCoordinate wakeTo = this.map.convertGPS(boat.getWake());
|
||||
displayLine(wakeFrom, wakeTo, boat.getColour());
|
||||
}
|
||||
else displayBoat(boat, 0);
|
||||
displayText(boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition()));
|
||||
else {
|
||||
displayBoat(boat, 0);
|
||||
}
|
||||
|
||||
if (raceAnno) displayText(boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the raceAnno value
|
||||
*/
|
||||
public void toggleAnno(){
|
||||
if (raceAnno){
|
||||
raceAnno = false;
|
||||
} else {
|
||||
raceAnno = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,12 +251,15 @@ public class ResizableRaceCanvas extends Canvas {
|
||||
return getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws boats during race setup, when leg heading is not set.
|
||||
*/
|
||||
public void drawBoats() {
|
||||
if (boats != null) {
|
||||
for (BoatInRace boat : boats) {
|
||||
if (boat != null) {
|
||||
displayBoat(boat, 0);
|
||||
displayText(boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition()));
|
||||
if (raceAnno) displayText(boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,9 +69,18 @@
|
||||
<items>
|
||||
<AnchorPane fx:id="canvasBase" prefHeight="581.0" prefWidth="537.0">
|
||||
<children>
|
||||
<Label fx:id="timer" layoutX="45.0" layoutY="146.0" text="0:0" AnchorPane.bottomAnchor="0.0"
|
||||
AnchorPane.rightAnchor="0.0"/>
|
||||
<Label fx:id="FPS" layoutX="-20.0" layoutY="153.0" text="FPS: 0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="-0.0" />
|
||||
<Label fx:id="FPS" text="FPS: 0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" />
|
||||
<Label fx:id="timer" layoutX="45.0" layoutY="146.0" text="0:0" AnchorPane.bottomAnchor="0.0" AnchorPane.rightAnchor="0.0" />
|
||||
<TitledPane fx:id="userControl" animated="false" text="User Control" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<content>
|
||||
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
|
||||
<children>
|
||||
<CheckBox fx:id="showFPS" mnemonicParsing="false" selected="true" text="Show FPS" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
<CheckBox fx:id="showAnno" mnemonicParsing="false" selected="true" text="Show Annotations" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="25.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</content>
|
||||
</TitledPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane layoutX="450.0" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="200.0"
|
||||
|
||||
Reference in New Issue
Block a user