Merge branch 'master' into story1306_wind_arrow
# Conflicts: # racevisionGame/src/main/java/visualiser/layout/Assets3D.java
This commit is contained in:
@@ -16,8 +16,9 @@
|
|||||||
# https://www.kernel.org/pub/software/scm/git/docs/git-shortlog.html
|
# https://www.kernel.org/pub/software/scm/git/docs/git-shortlog.html
|
||||||
# http://stacktoheap.com/blog/2013/01/06/using-mailmap-to-fix-authors-list-in-git/
|
# http://stacktoheap.com/blog/2013/01/06/using-mailmap-to-fix-authors-list-in-git/
|
||||||
Erika Savell <[email protected]>
|
Erika Savell <[email protected]>
|
||||||
Connor Taylor-Brown <cbt24@cs17086jp.canterbury.ac.nz> <cbt24@uclive.canterbury.ac.nz>
|
Connor Taylor-Brown <cbt24@uclive.ac.nz> <cbt24@cs17086jp.canterbury.ac.nz>
|
||||||
Fraser Cope <[email protected]>
|
Fraser Cope <[email protected]>
|
||||||
Jessica Syder <[email protected]> Jessica Syder <[email protected]>
|
Jessica Syder <[email protected]> <[email protected]>
|
||||||
Joseph Gardner <[email protected]>
|
Joseph Gardner <[email protected]>
|
||||||
Hamish Ball <[email protected]> hba56 <[email protected]>
|
Hamish Ball <[email protected]>
|
||||||
|
David Wu <[email protected]>
|
||||||
@@ -63,6 +63,8 @@ public class Event {
|
|||||||
*/
|
*/
|
||||||
private SourceIdAllocator sourceIdAllocator;
|
private SourceIdAllocator sourceIdAllocator;
|
||||||
|
|
||||||
|
private RaceLogic raceLogic;
|
||||||
|
|
||||||
private Thread raceThread;
|
private Thread raceThread;
|
||||||
|
|
||||||
private Thread connectionThread;
|
private Thread connectionThread;
|
||||||
@@ -114,14 +116,17 @@ public class Event {
|
|||||||
|
|
||||||
//Read XML files.
|
//Read XML files.
|
||||||
try {
|
try {
|
||||||
//this.raceXML = RaceXMLCreator.alterRaceToWind(raceXMLFile, 90);
|
|
||||||
this.raceXML = Event.setRaceXMLAtCurrentTimeToNow(XMLReader.readXMLFileToString(raceXMLFile, StandardCharsets.UTF_8));
|
|
||||||
if(mapIndex==4){
|
if(mapIndex==4){
|
||||||
//this.raceXML = Event.setRaceXMLAtCurrentTimeToNow(XMLReader.readXMLFileToString(raceXMLFile, StandardCharsets.UTF_8), 1000, 5000);
|
//This is the tutorial map.
|
||||||
this.raceXML = RaceXMLCreator.alterRaceToWind(this.raceXML, XMLFileType.Contents, -1, true);
|
this.raceXML = Event.setRaceXMLAtCurrentTimeToNow(XMLReader.readXMLFileToString(raceXMLFile, StandardCharsets.UTF_8), 1000, 5000);
|
||||||
|
this.raceXML = RaceXMLCreator.alterRaceToWind(this.raceXML, XMLFileType.Contents, -1);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.raceXML = RaceXMLCreator.alterRaceToWind(this.raceXML, XMLFileType.Contents, windAngle, false);
|
this.raceXML = Event.setRaceXMLAtCurrentTimeToNow(XMLReader.readXMLFileToString(raceXMLFile, StandardCharsets.UTF_8));
|
||||||
|
this.raceXML = RaceXMLCreator.alterRaceToWind(this.raceXML, XMLFileType.Contents, windAngle);
|
||||||
this.raceXML = RaceXMLCreator.scaleRaceSize(raceXML, windSpeed, 15 * 60 * 1000);
|
this.raceXML = RaceXMLCreator.scaleRaceSize(raceXML, windSpeed, 15 * 60 * 1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.boatXML = XMLReader.readXMLFileToString(boatsXMLFile, StandardCharsets.UTF_8);
|
this.boatXML = XMLReader.readXMLFileToString(boatsXMLFile, StandardCharsets.UTF_8);
|
||||||
@@ -171,20 +176,20 @@ public class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RaceLogic newRace = new RaceLogic(
|
this.raceLogic = new RaceLogic(
|
||||||
mockRace,
|
mockRace,
|
||||||
this.latestMessages,
|
this.latestMessages,
|
||||||
this.compositeCommand);
|
this.compositeCommand);
|
||||||
|
|
||||||
this.raceThread = new Thread(newRace, "Event.Start()->RaceLogic thread");
|
this.raceThread = new Thread(raceLogic, "Event.Start()->RaceLogic thread");
|
||||||
raceThread.start();
|
raceThread.start();
|
||||||
|
|
||||||
|
|
||||||
//Create connection acceptor.
|
//Create connection acceptor.
|
||||||
this.sourceIdAllocator = new SourceIdAllocator(newRace.getRace());
|
this.sourceIdAllocator = new SourceIdAllocator(raceLogic.getRace());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.connectionAcceptor = new ConnectionAcceptor(latestMessages, compositeCommand, sourceIdAllocator, newRace);
|
this.connectionAcceptor = new ConnectionAcceptor(latestMessages, compositeCommand, sourceIdAllocator, raceLogic);
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new EventConstructionException("Could not create ConnectionAcceptor.", e);
|
throw new EventConstructionException("Could not create ConnectionAcceptor.", e);
|
||||||
@@ -217,16 +222,13 @@ public class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String setRaceXMLAtCurrentTimeToNow(String raceXML, long racePreStartTime, long racePreparatoryTime){
|
public static String setRaceXMLAtCurrentTimeToNow(String raceXML, long racePreStartTime, long racePreparatoryTime){
|
||||||
//The start time is current time + 4 minutes. prestart is 3 minutes, and we add another minute.
|
|
||||||
|
|
||||||
long millisecondsToAdd = racePreStartTime + racePreparatoryTime;
|
long minutesToAdd = 10;
|
||||||
|
|
||||||
long secondsToAdd = millisecondsToAdd / 1000;
|
|
||||||
|
|
||||||
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
|
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
|
||||||
ZonedDateTime creationTime = ZonedDateTime.now();
|
ZonedDateTime creationTime = ZonedDateTime.now();
|
||||||
raceXML = raceXML.replace("RACE_CREATION_TIME", dateFormat.format(creationTime));
|
raceXML = raceXML.replace("RACE_CREATION_TIME", dateFormat.format(creationTime));
|
||||||
raceXML = raceXML.replace("RACE_START_TIME", dateFormat.format(creationTime.plusSeconds(secondsToAdd)));
|
raceXML = raceXML.replace("RACE_START_TIME", dateFormat.format(creationTime.plusMinutes(minutesToAdd)));
|
||||||
|
|
||||||
return raceXML;
|
return raceXML;
|
||||||
}
|
}
|
||||||
@@ -241,4 +243,9 @@ public class Event {
|
|||||||
return new HostGame(ip, 3779,(byte) 1,(byte) 1, RaceStatusEnum.PRESTART, (byte) 1, (byte) 1);
|
return new HostGame(ip, 3779,(byte) 1,(byte) 1, RaceStatusEnum.PRESTART, (byte) 1, (byte) 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public RaceLogic getRaceLogic() {
|
||||||
|
return raceLogic;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,12 +61,17 @@ public class MockRace extends RaceState {
|
|||||||
*/
|
*/
|
||||||
private Polars polars;
|
private Polars polars;
|
||||||
|
|
||||||
private ActiveObserverCommand activeObserverCommand;
|
private Map<Integer, ActiveObserverCommand> activeObserverCommands;
|
||||||
|
|
||||||
private long racePreStartTime = Constants.RacePreStartTime;
|
private long racePreStartTime = Constants.RacePreStartTime;
|
||||||
|
|
||||||
private long racePreparatoryTime = Constants.RacePreparatoryTime;
|
private long racePreparatoryTime = Constants.RacePreparatoryTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the race has been manually started, false otherwise.
|
||||||
|
*/
|
||||||
|
private boolean hasBeenStarted = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a race object with a given RaceDataSource, BoatDataSource, and RegattaDataSource and sends events to the given mockOutput.
|
* Constructs a race object with a given RaceDataSource, BoatDataSource, and RegattaDataSource and sends events to the given mockOutput.
|
||||||
* @param boatDataSource Data source for boat related data (yachts and marker boats).
|
* @param boatDataSource Data source for boat related data (yachts and marker boats).
|
||||||
@@ -82,7 +87,7 @@ public class MockRace extends RaceState {
|
|||||||
this.setRaceDataSource(raceDataSource);
|
this.setRaceDataSource(raceDataSource);
|
||||||
this.setRegattaDataSource(regattaDataSource);
|
this.setRegattaDataSource(regattaDataSource);
|
||||||
|
|
||||||
this.activeObserverCommand = new ActiveObserverCommand();
|
this.activeObserverCommands = new HashMap<>();
|
||||||
this.polars = polars;
|
this.polars = polars;
|
||||||
this.scaleFactor = timeScale;
|
this.scaleFactor = timeScale;
|
||||||
|
|
||||||
@@ -127,6 +132,7 @@ public class MockRace extends RaceState {
|
|||||||
getRaceDataSource().getParticipants().add(sourceID);
|
getRaceDataSource().getParticipants().add(sourceID);
|
||||||
|
|
||||||
this.boats.add(mockBoat);
|
this.boats.add(mockBoat);
|
||||||
|
this.activeObserverCommands.put(boat.getSourceID(), new ActiveObserverCommand());
|
||||||
|
|
||||||
getRaceDataSource().incrementSequenceNumber();
|
getRaceDataSource().incrementSequenceNumber();
|
||||||
|
|
||||||
@@ -157,6 +163,23 @@ public class MockRace extends RaceState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delays the start of the race, if needed, to ensure that the race doesn't start until host wants it to.
|
||||||
|
* If the time until start is less that 5 minutes, it is extended to 10 minutes.
|
||||||
|
*/
|
||||||
|
public void delayRaceStart() {
|
||||||
|
long timeToStart = getRaceDataSource().getStartDateTime().toInstant().toEpochMilli() - System.currentTimeMillis();
|
||||||
|
|
||||||
|
long fiveMinutesMilli = 5 * 60 * 1000;
|
||||||
|
long tenMinutesMilli = 10 * 60 * 1000;
|
||||||
|
|
||||||
|
if ((timeToStart < fiveMinutesMilli) && (timeToStart > 0) && !hasBeenStarted) {
|
||||||
|
startRace(tenMinutesMilli, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the race status enumeration based on the current time.
|
* Updates the race status enumeration based on the current time.
|
||||||
*/
|
*/
|
||||||
@@ -165,7 +188,6 @@ public class MockRace extends RaceState {
|
|||||||
//The millisecond duration of the race. Negative means it hasn't started, so we flip sign.
|
//The millisecond duration of the race. Negative means it hasn't started, so we flip sign.
|
||||||
long timeToStart = - this.getRaceClock().getDurationMilli();
|
long timeToStart = - this.getRaceClock().getDurationMilli();
|
||||||
|
|
||||||
|
|
||||||
if (timeToStart > racePreStartTime) {
|
if (timeToStart > racePreStartTime) {
|
||||||
//Time > 3 minutes is the prestart period.
|
//Time > 3 minutes is the prestart period.
|
||||||
this.setRaceStatusEnum(RaceStatusEnum.PRESTART);
|
this.setRaceStatusEnum(RaceStatusEnum.PRESTART);
|
||||||
@@ -195,6 +217,26 @@ public class MockRace extends RaceState {
|
|||||||
this.racePreparatoryTime = racePreparatoryTime;
|
this.racePreparatoryTime = racePreparatoryTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getRacePreparatoryTime() {
|
||||||
|
return racePreparatoryTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the race in #timeToStartMilli milliseconds.
|
||||||
|
* @param timeToStartMilli Millseconds before starting the race.
|
||||||
|
* @param manualStart True if the race has been manually started, false otherwise.
|
||||||
|
*/
|
||||||
|
public void startRace(long timeToStartMilli, boolean manualStart) {
|
||||||
|
this.hasBeenStarted = manualStart;
|
||||||
|
ZonedDateTime startTime = ZonedDateTime.now().plus(timeToStartMilli, ChronoUnit.MILLIS);
|
||||||
|
|
||||||
|
getRaceDataSource().setStartDateTime(startTime);
|
||||||
|
getRaceDataSource().incrementSequenceNumber();
|
||||||
|
|
||||||
|
this.getRaceClock().setStartingTime(getRaceDataSource().getStartDateTime());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the status of all boats in the race to RACING.
|
* Sets the status of all boats in the race to RACING.
|
||||||
*/
|
*/
|
||||||
@@ -711,11 +753,11 @@ public class MockRace extends RaceState {
|
|||||||
super.setChanged();
|
super.setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addVelocityCommand(ObserverCommand c) {
|
public void addVelocityCommand(ObserverCommand c, int boatId) {
|
||||||
this.activeObserverCommand.changeVelocityCommand(this, c);
|
this.activeObserverCommands.get(boatId).changeVelocityCommand(this, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAngularCommand(ObserverCommand c) {
|
public void addAngularCommand(ObserverCommand c, int boatId) {
|
||||||
this.activeObserverCommand.changeAngularCommand(this, c);
|
this.activeObserverCommands.get(boatId).changeAngularCommand(this, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ public class RaceLogic implements RunnableWithFramePeriod, Observer {
|
|||||||
//Update race time.
|
//Update race time.
|
||||||
race.updateRaceTime(currentTime);
|
race.updateRaceTime(currentTime);
|
||||||
|
|
||||||
|
race.delayRaceStart();
|
||||||
|
|
||||||
//Update the race status based on the current time.
|
//Update the race status based on the current time.
|
||||||
race.updateRaceStatusEnum();
|
race.updateRaceStatusEnum();
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public class CollisionCommand extends ObserverCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void update(Observable o, Object arg) {
|
public void update(Observable o, Object arg) {
|
||||||
if(GPSCoordinate.calculateDistanceMeters(boat.getPosition(), startingPosition) < distance) {
|
if(GPSCoordinate.calculateDistanceMeters(boat.getPosition(), startingPosition) < distance) {
|
||||||
|
boat.setVelocityDefault(false);
|
||||||
boat.setPosition(GPSCoordinate.calculateNewPosition(boat.getPosition(), 3, azimuth));
|
boat.setPosition(GPSCoordinate.calculateNewPosition(boat.getPosition(), 3, azimuth));
|
||||||
} else {
|
} else {
|
||||||
race.deleteObserver(this);
|
race.deleteObserver(this);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class SailsCommand extends ObserverCommand {
|
|||||||
|
|
||||||
public SailsCommand(MockRace race, MockBoat boat, boolean sailsOut) {
|
public SailsCommand(MockRace race, MockBoat boat, boolean sailsOut) {
|
||||||
super(race, boat);
|
super(race, boat);
|
||||||
race.addVelocityCommand(this);
|
race.addVelocityCommand(this, boat.getSourceID());
|
||||||
this.sailsOut = sailsOut;
|
this.sailsOut = sailsOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +37,8 @@ public class SailsCommand extends ObserverCommand {
|
|||||||
public void update(Observable o, Object arg) {
|
public void update(Observable o, Object arg) {
|
||||||
double acceleration = 0.5;
|
double acceleration = 0.5;
|
||||||
|
|
||||||
|
if (!boat.isColliding()) {
|
||||||
|
boat.setVelocityDefault(false);
|
||||||
if (sailsOut && boat.getCurrentSpeed() < goalVelocity) {
|
if (sailsOut && boat.getCurrentSpeed() < goalVelocity) {
|
||||||
boat.setCurrentSpeed(Math.min(goalVelocity, boat.getCurrentSpeed() + acceleration));
|
boat.setCurrentSpeed(Math.min(goalVelocity, boat.getCurrentSpeed() + acceleration));
|
||||||
} else if (!sailsOut && boat.getCurrentSpeed() > goalVelocity) {
|
} else if (!sailsOut && boat.getCurrentSpeed() > goalVelocity) {
|
||||||
@@ -49,3 +51,4 @@ public class SailsCommand extends ObserverCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class TackGybeCommand extends ObserverCommand {
|
|||||||
*/
|
*/
|
||||||
public TackGybeCommand(MockRace race, MockBoat boat) {
|
public TackGybeCommand(MockRace race, MockBoat boat) {
|
||||||
super(race, boat);
|
super(race, boat);
|
||||||
race.addAngularCommand(this);
|
race.addAngularCommand(this, boat.getSourceID());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class VMGCommand extends ObserverCommand {
|
|||||||
*/
|
*/
|
||||||
public VMGCommand(MockRace race, MockBoat boat) {
|
public VMGCommand(MockRace race, MockBoat boat) {
|
||||||
super(race, boat);
|
super(race, boat);
|
||||||
race.addAngularCommand(this);
|
race.addAngularCommand(this, boat.getSourceID());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class WindCommand extends ObserverCommand {
|
|||||||
*/
|
*/
|
||||||
public WindCommand(MockRace race, MockBoat boat, boolean upwind) {
|
public WindCommand(MockRace race, MockBoat boat, boolean upwind) {
|
||||||
super(race, boat);
|
super(race, boat);
|
||||||
race.addAngularCommand(this);
|
race.addAngularCommand(this, boat.getSourceID());
|
||||||
this.direction = upwind? -1 : 1;
|
this.direction = upwind? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,13 +56,12 @@ public class RaceXMLCreator {
|
|||||||
* Rotates the race in a specified direction.
|
* Rotates the race in a specified direction.
|
||||||
* @param s xml file name or contents.
|
* @param s xml file name or contents.
|
||||||
* @param fileType Whether s is a file name or contents.
|
* @param fileType Whether s is a file name or contents.
|
||||||
* @param degrees degrees to rotate
|
* @param degrees degrees to rotate. -1 means don't rotate.
|
||||||
* @param tutorial Whether we wish to run the tutorial - this changes the race start time.
|
|
||||||
* @return the new xml file as a string
|
* @return the new xml file as a string
|
||||||
* @throws XMLReaderException if the xml is not readable
|
* @throws XMLReaderException if the xml is not readable
|
||||||
* @throws InvalidRaceDataException if the race is invalid
|
* @throws InvalidRaceDataException if the race is invalid
|
||||||
*/
|
*/
|
||||||
public static String alterRaceToWind(String s, XMLFileType fileType, double degrees, boolean tutorial) throws XMLReaderException, InvalidRaceDataException {
|
public static String alterRaceToWind(String s, XMLFileType fileType, double degrees) throws XMLReaderException, InvalidRaceDataException {
|
||||||
|
|
||||||
RaceXMLReader reader = new RaceXMLReader(s, fileType);
|
RaceXMLReader reader = new RaceXMLReader(s, fileType);
|
||||||
|
|
||||||
@@ -73,11 +72,6 @@ public class RaceXMLCreator {
|
|||||||
RaceXMLCreator.class.getClassLoader().getResource("mock/mockXML/schema/raceSchema.xsd"),
|
RaceXMLCreator.class.getClassLoader().getResource("mock/mockXML/schema/raceSchema.xsd"),
|
||||||
XMLRace.class);
|
XMLRace.class);
|
||||||
|
|
||||||
if(tutorial){
|
|
||||||
setRaceXMLAtCurrentTimeToNow(race, 1000l, 5000l);
|
|
||||||
} else {
|
|
||||||
setRaceXMLAtCurrentTimeToNow(race);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CompoundMark leewardGate = getLeewardGate(reader);
|
CompoundMark leewardGate = getLeewardGate(reader);
|
||||||
|
|||||||
@@ -151,4 +151,9 @@ public class EmptyRaceDataSource implements RaceDataSource {
|
|||||||
public void incrementSequenceNumber() {
|
public void incrementSequenceNumber() {
|
||||||
sequenceNumber++;
|
sequenceNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStartDateTime(ZonedDateTime time) {
|
||||||
|
raceStartTime = time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,12 @@ public interface RaceDataSource {
|
|||||||
*/
|
*/
|
||||||
ZonedDateTime getStartDateTime();
|
ZonedDateTime getStartDateTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the start time/date of the race.
|
||||||
|
* @param time Time to start at.
|
||||||
|
*/
|
||||||
|
void setStartDateTime(ZonedDateTime time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the creation time/date of the race xml file.
|
* Returns the creation time/date of the race xml file.
|
||||||
* @return The race xml file's creation time.
|
* @return The race xml file's creation time.
|
||||||
|
|||||||
@@ -507,4 +507,9 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
|
|||||||
public void incrementSequenceNumber() {
|
public void incrementSequenceNumber() {
|
||||||
sequenceNumber++;
|
sequenceNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStartDateTime(ZonedDateTime time) {
|
||||||
|
raceStartTime = time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import javafx.fxml.FXML;
|
|||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.ButtonType;
|
import javafx.scene.control.ButtonType;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
@@ -70,13 +71,10 @@ public class InGameLobbyController extends Controller {
|
|||||||
private Label playerLabel6;
|
private Label playerLabel6;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label countdownLabel;
|
private Button startButton;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private AnchorPane countdownTenPane;
|
private Button quitButton;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private Label countdownTenText;
|
|
||||||
|
|
||||||
private Event game;
|
private Event game;
|
||||||
|
|
||||||
@@ -219,37 +217,13 @@ public class InGameLobbyController extends Controller {
|
|||||||
* Starts the race.
|
* Starts the race.
|
||||||
*/
|
*/
|
||||||
private void startRace() {
|
private void startRace() {
|
||||||
//Initialises the race clock.
|
|
||||||
initialiseRaceClock(this.visualiserRaceEvent.getVisualiserRaceState());
|
|
||||||
|
|
||||||
//Starts the race countdown timer.
|
//Starts the race countdown timer.
|
||||||
countdownTimer();
|
countdownTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialises the race clock/timer labels for the start time, current time, and remaining time.
|
|
||||||
* @param visualiserRace The race to get data from.
|
|
||||||
*/
|
|
||||||
private void initialiseRaceClock(VisualiserRaceState visualiserRace) {
|
|
||||||
//Remaining time.
|
|
||||||
initialiseRaceClockDuration(visualiserRace);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialises the race duration label.
|
|
||||||
* @param visualiserRace The race to get data from.
|
|
||||||
*/
|
|
||||||
private void initialiseRaceClockDuration(VisualiserRaceState visualiserRace) {
|
|
||||||
|
|
||||||
visualiserRace.getRaceClock().durationProperty().addListener((observable, oldValue, newValue) -> {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
countdownLabel.setText(newValue);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Countdown timer until race starts.
|
* Countdown timer until race starts.
|
||||||
*/
|
*/
|
||||||
@@ -260,19 +234,6 @@ public class InGameLobbyController extends Controller {
|
|||||||
//Get the current race status.
|
//Get the current race status.
|
||||||
RaceStatusEnum raceStatus = visualiserRaceEvent.getVisualiserRaceState().getRaceStatusEnum();
|
RaceStatusEnum raceStatus = visualiserRaceEvent.getVisualiserRaceState().getRaceStatusEnum();
|
||||||
|
|
||||||
//Try catch for getting interval times
|
|
||||||
try {
|
|
||||||
long interval = ChronoUnit.MILLIS.between(visualiserRaceEvent.getVisualiserRaceState().getRaceClock().getCurrentTime(), visualiserRaceEvent.getVisualiserRaceState().getRaceClock().getStartingTime());
|
|
||||||
if(interval<=10000){
|
|
||||||
countdownLabel.setVisible(false);
|
|
||||||
countdownTenPane.setVisible(true);
|
|
||||||
countdownTenText.setVisible(true);
|
|
||||||
}
|
|
||||||
countdownText(interval);
|
|
||||||
} catch (Exception e){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//If the race has reached the preparatory phase, or has started...
|
//If the race has reached the preparatory phase, or has started...
|
||||||
if (raceStatus == RaceStatusEnum.PREPARATORY || raceStatus == RaceStatusEnum.STARTED) {
|
if (raceStatus == RaceStatusEnum.PREPARATORY || raceStatus == RaceStatusEnum.STARTED) {
|
||||||
@@ -311,6 +272,8 @@ public class InGameLobbyController extends Controller {
|
|||||||
|
|
||||||
this.visualiserRaceEvent.getVisualiserRaceState().getBoats().addListener(this.lobbyUpdateListener);
|
this.visualiserRaceEvent.getVisualiserRaceState().getBoats().addListener(this.lobbyUpdateListener);
|
||||||
|
|
||||||
|
enableStartIfHost();
|
||||||
|
|
||||||
startRace();
|
startRace();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
//TODO should probably let this propagate, so that we only enter this scene if everything works
|
//TODO should probably let this propagate, so that we only enter this scene if everything works
|
||||||
@@ -318,6 +281,22 @@ public class InGameLobbyController extends Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the start button if the client is the host of the game.
|
||||||
|
*/
|
||||||
|
private void enableStartIfHost() {
|
||||||
|
if (isHost) {
|
||||||
|
startButton.setVisible(true);
|
||||||
|
startButton.setDisable(false);
|
||||||
|
} else {
|
||||||
|
startButton.setVisible(false);
|
||||||
|
startButton.setDisable(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Menu button pressed. Prompt alert then return to menu
|
* Menu button pressed. Prompt alert then return to menu
|
||||||
* @throws IOException socket erro
|
* @throws IOException socket erro
|
||||||
@@ -345,7 +324,7 @@ public class InGameLobbyController extends Controller {
|
|||||||
* Start button pressed. Currently only prints out start
|
* Start button pressed. Currently only prints out start
|
||||||
*/
|
*/
|
||||||
public void startBtnPressed(){
|
public void startBtnPressed(){
|
||||||
//System.out.println("Should start the race. This button is only visible for the host");
|
App.game.getRaceLogic().getRace().startRace(App.game.getRaceLogic().getRace().getRacePreparatoryTime(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void joinSpecPressed(){
|
public void joinSpecPressed(){
|
||||||
@@ -356,48 +335,5 @@ public class InGameLobbyController extends Controller {
|
|||||||
//System.out.println("Empty race user pane pressed. Joining racers");
|
//System.out.println("Empty race user pane pressed. Joining racers");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Countdown interval checker that updates the countdown text
|
|
||||||
* @param interval Countdown interval to check
|
|
||||||
*/
|
|
||||||
private void countdownText(long interval){
|
|
||||||
countdownTenPane.setVisible(false);
|
|
||||||
//Do nothing if 5 seconds or less to go
|
|
||||||
if (interval <=5000){
|
|
||||||
countdownTenPane.setVisible(false);
|
|
||||||
//countdownTenText.setText("5");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//6 seconds left. Display 1 second for countdown
|
|
||||||
if (interval <=6000){
|
|
||||||
countdownTenText.setText("1");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//7 seconds left. Display 2 seconds for countdown
|
|
||||||
if (interval <=7000){
|
|
||||||
countdownTenText.setText("2");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//8 seconds left. Display 3 seconds for countdown
|
|
||||||
if (interval <=8000){
|
|
||||||
countdownTenText.setText("3");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//9 seconds left. Display 4 seconds for countdown
|
|
||||||
if (interval <=9000){
|
|
||||||
countdownTenText.setText("4");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//10 seconds left. Display 5 seconds for countdown
|
|
||||||
if (interval <=10000){
|
|
||||||
countdownTenText.setText("5");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,23 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import java.lang.*?>
|
|
||||||
<?import javafx.geometry.*?>
|
|
||||||
<?import javafx.scene.control.*?>
|
|
||||||
<?import javafx.scene.image.*?>
|
|
||||||
<?import javafx.scene.layout.*?>
|
|
||||||
<?import javafx.scene.text.*?>
|
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Label?>
|
||||||
<?import javafx.scene.control.SplitPane?>
|
|
||||||
<?import javafx.scene.control.TableColumn?>
|
|
||||||
<?import javafx.scene.control.TableView?>
|
|
||||||
<?import javafx.scene.image.Image?>
|
|
||||||
<?import javafx.scene.image.ImageView?>
|
|
||||||
<?import javafx.scene.layout.AnchorPane?>
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
<?import javafx.scene.layout.ColumnConstraints?>
|
<?import javafx.scene.layout.ColumnConstraints?>
|
||||||
<?import javafx.scene.layout.GridPane?>
|
<?import javafx.scene.layout.GridPane?>
|
||||||
<?import javafx.scene.layout.RowConstraints?>
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
<?import javafx.scene.text.Font?>
|
<?import javafx.scene.text.Font?>
|
||||||
|
|
||||||
<AnchorPane fx:id="gameLobbyWrapper" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="780.0" style="-fx-background-color: rgba(100, 100, 100, 0.2);" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="visualiser.Controllers.InGameLobbyController">
|
<AnchorPane fx:id="gameLobbyWrapper" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="780.0" style="-fx-background-color: rgba(100, 100, 100, 0.2);" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="visualiser.Controllers.InGameLobbyController">
|
||||||
<children>
|
<children>
|
||||||
<GridPane style="-fx-background-color: rgba(0, 0, 0, 0.3);" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
<GridPane style="-fx-background-color: rgba(0, 0, 0, 0.3);" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
<children>
|
<children>
|
||||||
<Button mnemonicParsing="false" onAction="#menuBtnPressed" text="Quit" GridPane.rowIndex="2">
|
<Button fx:id="quitButton" mnemonicParsing="false" onAction="#menuBtnPressed" text="Quit" GridPane.rowIndex="2">
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets left="20.0" />
|
<Insets left="20.0" />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</Button>
|
</Button>
|
||||||
<Label fx:id="countdownLabel" alignment="CENTER" contentDisplay="CENTER" textFill="WHITE" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2">
|
|
||||||
<font>
|
|
||||||
<Font size="16.0" />
|
|
||||||
</font>
|
|
||||||
</Label>
|
|
||||||
<GridPane fx:id="playerContainer" GridPane.columnSpan="3" GridPane.rowIndex="1">
|
<GridPane fx:id="playerContainer" GridPane.columnSpan="3" GridPane.rowIndex="1">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
@@ -82,6 +66,7 @@
|
|||||||
<Font name="Cabin-Bold" size="17.0" />
|
<Font name="Cabin-Bold" size="17.0" />
|
||||||
</font>
|
</font>
|
||||||
</Label>
|
</Label>
|
||||||
|
<Button fx:id="startButton" disable="true" mnemonicParsing="false" onAction="#startBtnPressed" text="Start!" visible="false" GridPane.columnIndex="2" GridPane.rowIndex="2" />
|
||||||
</children>
|
</children>
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
@@ -94,19 +79,5 @@
|
|||||||
<RowConstraints maxHeight="80.0" minHeight="80.0" prefHeight="80.0" vgrow="SOMETIMES" />
|
<RowConstraints maxHeight="80.0" minHeight="80.0" prefHeight="80.0" vgrow="SOMETIMES" />
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
<AnchorPane fx:id="countdownTenPane" prefHeight="200.0" prefWidth="200.0" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
|
||||||
<children>
|
|
||||||
<Label fx:id="countdownTenText" alignment="CENTER" text="COUNTDOWN" textFill="#ee0000" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
|
||||||
<font>
|
|
||||||
<Font name="System Bold" size="41.0" />
|
|
||||||
</font>
|
|
||||||
</Label>
|
|
||||||
<Label fx:id="preRacelabel" alignment="CENTER" text="Entering Race In:" textFill="RED" AnchorPane.bottomAnchor="80.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
|
||||||
<font>
|
|
||||||
<Font name="System Bold" size="18.0" />
|
|
||||||
</font>
|
|
||||||
</Label>
|
|
||||||
</children>
|
|
||||||
</AnchorPane>
|
|
||||||
</children>
|
</children>
|
||||||
</AnchorPane>
|
</AnchorPane>
|
||||||
|
|||||||
Reference in New Issue
Block a user