Started work on start screen

- Server now sends out race start status messages during lobby & pre-start stages
- Added timer in lobby

Tags: #story[1109]
This commit is contained in:
Michael Rausch
2017-08-11 19:03:57 +12:00
parent 3ad37faedc
commit d2fd9ebaea
8 changed files with 97 additions and 27 deletions
@@ -62,6 +62,8 @@ public class GameState implements Runnable {
yachts = new HashMap<>(); yachts = new HashMap<>();
markOrder = new MarkOrder(); //This could be instantiated at some point with a select map? markOrder = new MarkOrder(); //This could be instantiated at some point with a select map?
startTime = System.currentTimeMillis() + 20000;
new Thread(this).start(); //Run the auto updates on the game state new Thread(this).start(); //Run the auto updates on the game state
} }
@@ -101,10 +103,6 @@ public class GameState implements Runnable {
} }
public static void setCurrentStage(GameStages currentStage) { public static void setCurrentStage(GameStages currentStage) {
if (currentStage == GameStages.RACING){
startTime = System.currentTimeMillis();
}
GameState.currentStage = currentStage; GameState.currentStage = currentStage;
} }
@@ -195,7 +193,7 @@ public class GameState implements Runnable {
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.out.println("[GameState] interrupted exception"); System.out.println("[GameState] interrupted exception");
} }
if (currentStage == GameStages.PRE_RACE) { if (currentStage == GameStages.PRE_RACE || currentStage == GameStages.LOBBYING) {
update(); update();
} }
@@ -135,7 +135,6 @@ public class MainServerThread extends Observable implements Runnable, ClientConn
t.schedule(new TimerTask() { t.schedule(new TimerTask() {
@Override @Override
public void run() { public void run() {
for (ServerToClientThread serverToClientThread : serverToClientThreads) { for (ServerToClientThread serverToClientThread : serverToClientThreads) {
serverToClientThread.sendRaceStatusMessage(); serverToClientThread.sendRaceStatusMessage();
} }
@@ -228,7 +228,7 @@ public class ServerToClientThread implements Runnable, Observer {
} }
//@TODO calculate lat/lng values //@TODO calculate lat/lng values
xml.setRegatta(new Regatta("RaceVision Test Game", 57.6679590, 11.8503233)); xml.setRegatta(new Regatta("Party Parrot Test Server", "Bermuda Test Course", 57.6679590, 11.8503233));
xml.setRace(race); xml.setRace(race);
XMLMessage xmlMessage; XMLMessage xmlMessage;
@@ -246,6 +246,7 @@ public class ServerToClientThread implements Runnable, Observer {
} }
public void updateClient() { public void updateClient() {
sendRaceStatusMessage();
sendBoatLocationPackets(); sendBoatLocationPackets();
updateClient = true; updateClient = true;
} }
@@ -376,6 +377,14 @@ public class ServerToClientThread implements Runnable, Observer {
sendMessage(new RaceStatusMessage(1, raceStatus, GameState.getStartTime(), GameState.getWindDirection(), sendMessage(new RaceStatusMessage(1, raceStatus, GameState.getStartTime(), GameState.getWindDirection(),
GameState.getWindSpeedMMS().longValue(), GameState.getPlayers().size(), GameState.getWindSpeedMMS().longValue(), GameState.getPlayers().size(),
RaceType.MATCH_RACE, 1, boatSubMessages)); RaceType.MATCH_RACE, 1, boatSubMessages));
if (GameState.getCurrentStage() == GameStages.PRE_RACE || GameState.getCurrentStage() == GameStages.LOBBYING){
Long raceStartTime = GameState.getStartTime();
sendMessage(new RaceStartStatusMessage(1, raceStartTime ,
1, RaceStartNotificationType.SET_RACE_START_TIME));
}
} }
public Socket getSocket() { public Socket getSocket() {
+6 -3
View File
@@ -20,7 +20,7 @@ public class RaceState {
private long raceTime; private long raceTime;
private long expectedStartTime; private long expectedStartTime;
private boolean isRaceStarted = false; private boolean isRaceStarted = false;
// long timeTillStart; long timeTillStart;
public RaceState() { public RaceState() {
} }
@@ -38,8 +38,7 @@ public class RaceState {
} }
public void updateState (RaceStartData data) { public void updateState (RaceStartData data) {
// this.timeTillStart = data.getRaceStartTime(); this.timeTillStart = data.getRaceStartTime();
System.out.println(data.getRaceStartTime());
} }
public String getRaceTimeStr () { public String getRaceTimeStr () {
@@ -50,6 +49,10 @@ public class RaceState {
return (expectedStartTime - raceTime) / 1000; return (expectedStartTime - raceTime) / 1000;
} }
public String getTimeTillStartStr () {
return DATE_TIME_FORMAT.format(getTimeTillStart() * 1000);
}
public double getWindSpeed() { public double getWindSpeed() {
return windSpeed; return windSpeed;
} }
@@ -18,10 +18,10 @@ public class Regatta {
private Integer utcOffset; private Integer utcOffset;
private Double magneticVariation; private Double magneticVariation;
public Regatta(String name, Double latitude, Double longitude) { public Regatta(String name, String courseName, Double latitude, Double longitude) {
this.name = name; this.name = name;
this.id = DEFAULT_REGATTA_ID; this.id = DEFAULT_REGATTA_ID;
this.courseName = name; this.courseName = courseName;
this.latitude = latitude; this.latitude = latitude;
this.longitude = longitude; this.longitude = longitude;
@@ -45,6 +45,7 @@ public class GameClient {
private RegattaXMLData regattaData; private RegattaXMLData regattaData;
private RaceXMLData courseData; private RaceXMLData courseData;
private RaceState raceState = new RaceState(); private RaceState raceState = new RaceState();
private LobbyController lobbyController;
private ObservableList<String> clientLobbyList = FXCollections.observableArrayList(); private ObservableList<String> clientLobbyList = FXCollections.observableArrayList();
@@ -67,8 +68,10 @@ public class GameClient {
LobbyController lobbyController = loadLobby(); LobbyController lobbyController = loadLobby();
lobbyController.setPlayerListSource(clientLobbyList); lobbyController.setPlayerListSource(clientLobbyList);
lobbyController.disableReadyButton(); lobbyController.disableReadyButton();
lobbyController.setTitle("Connected to host - IP : " + ipAddress + " Port : " + portNumber); lobbyController.setTitle(regattaData.getRegattaName());
lobbyController.setCourseName(regattaData.getCourseName());
lobbyController.addCloseListener((exitCause) -> this.loadStartScreen()); lobbyController.addCloseListener((exitCause) -> this.loadStartScreen());
this.lobbyController = lobbyController;
} }
public void runAsHost(String ipAddress, Integer portNumber) { public void runAsHost(String ipAddress, Integer portNumber) {
@@ -82,7 +85,8 @@ public class GameClient {
socketThread.addStreamObserver(this::parsePackets); socketThread.addStreamObserver(this::parsePackets);
LobbyController lobbyController = loadLobby(); LobbyController lobbyController = loadLobby();
lobbyController.setPlayerListSource(clientLobbyList); lobbyController.setPlayerListSource(clientLobbyList);
lobbyController.setTitle("Hosting Lobby - IP : " + ipAddress + " Port : " + portNumber); lobbyController.setTitle("Hosting: " + regattaData.getRegattaName());
lobbyController.setCourseName(regattaData.getCourseName());
lobbyController.addCloseListener(exitCause -> { lobbyController.addCloseListener(exitCause -> {
if (exitCause == CloseStatus.READY) { if (exitCause == CloseStatus.READY) {
server.startGame(); server.startGame();
@@ -90,6 +94,8 @@ public class GameClient {
loadStartScreen(); loadStartScreen();
} }
}); });
this.lobbyController = lobbyController;
} }
private void loadStartScreen() { private void loadStartScreen() {
@@ -151,13 +157,18 @@ public class GameClient {
switch (packet.getType()) { switch (packet.getType()) {
case RACE_STATUS: case RACE_STATUS:
processRaceStatusUpdate(StreamParser.extractRaceStatus(packet)); processRaceStatusUpdate(StreamParser.extractRaceStatus(packet));
startRaceIfAllDataReceived();
if (raceState.getTimeTillStart() <= 5){
startRaceIfAllDataReceived();
}
break; break;
case REGATTA_XML: case REGATTA_XML:
regattaData = XMLParser.parseRegatta( regattaData = XMLParser.parseRegatta(
StreamParser.extractXmlMessage(packet) StreamParser.extractXmlMessage(packet)
); );
raceState.setTimeZone( raceState.setTimeZone(
TimeZone.getTimeZone( TimeZone.getTimeZone(
ZoneId.ofOffset("UTC", ZoneOffset.ofHours(regattaData.getUtcOffset())) ZoneId.ofOffset("UTC", ZoneOffset.ofHours(regattaData.getUtcOffset()))
@@ -189,6 +200,7 @@ public class GameClient {
case RACE_START_STATUS: case RACE_START_STATUS:
raceState.updateState(StreamParser.extractRaceStartStatus(packet)); raceState.updateState(StreamParser.extractRaceStartStatus(packet));
if (lobbyController != null) lobbyController.updateRaceState(raceState);
break; break;
case BOAT_LOCATION: case BOAT_LOCATION:
@@ -1,8 +1,7 @@
package seng302.visualiser.controllers; package seng302.visualiser.controllers;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
@@ -16,6 +15,8 @@ import javafx.scene.layout.GridPane;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import seng302.gameServer.GameStages; import seng302.gameServer.GameStages;
import seng302.gameServer.GameState; import seng302.gameServer.GameState;
import seng302.model.RaceState;
import seng302.visualiser.GameClient;
/** /**
* A class describing the actions of the lobby screen * A class describing the actions of the lobby screen
@@ -72,6 +73,12 @@ public class LobbyController {
@FXML @FXML
private ImageView eighthImageView; private ImageView eighthImageView;
@FXML
private Text timeUntilStart;
@FXML
private Text courseNameText;
private List<ObservableList<String>> competitors = new ArrayList<>(); private List<ObservableList<String>> competitors = new ArrayList<>();
private ObservableList<String> firstCompetitor = FXCollections.observableArrayList(); private ObservableList<String> firstCompetitor = FXCollections.observableArrayList();
private ObservableList<String> secondCompetitor = FXCollections.observableArrayList(); private ObservableList<String> secondCompetitor = FXCollections.observableArrayList();
@@ -84,6 +91,7 @@ public class LobbyController {
private List<ImageView> imageViews = new ArrayList<>(); private List<ImageView> imageViews = new ArrayList<>();
private List<ListView> listViews; private List<ListView> listViews;
private RaceState raceState;
private int MAX_NUM_PLAYERS = 8; private int MAX_NUM_PLAYERS = 8;
@@ -103,6 +111,8 @@ public class LobbyController {
fourthCompetitor, fifthCompetitor, sixthCompetitor, seventhCompetitor, eighthCompetitor); fourthCompetitor, fifthCompetitor, sixthCompetitor, seventhCompetitor, eighthCompetitor);
initialiseImageView(); initialiseImageView();
timeUntilStart.setText("");
} }
private void initialiseListView() { private void initialiseListView() {
@@ -149,9 +159,12 @@ public class LobbyController {
@FXML @FXML
public void readyButtonPressed() { public void readyButtonPressed() {
GameState.setCurrentStage(GameStages.RACING); GameState.setCurrentStage(GameStages.PRE_RACE);
for (LobbyCloseListener readyListener : lobbyListeners) return;
readyListener.notify(CloseStatus.READY); // Do countdown logic here
//for (LobbyCloseListener readyListener : lobbyListeners)
// readyListener.notify(CloseStatus.READY);
} }
@@ -184,6 +197,10 @@ public class LobbyController {
lobbyIpText.setText(title); lobbyIpText.setText(title);
} }
public void setCourseName(String courseName){
courseNameText.setText(courseName);
}
public void addCloseListener(LobbyCloseListener listener) { public void addCloseListener(LobbyCloseListener listener) {
lobbyListeners.add(listener); lobbyListeners.add(listener);
} }
@@ -196,6 +213,12 @@ public class LobbyController {
Platform.runLater(this::initialiseListView); Platform.runLater(this::initialiseListView);
} }
public void updateRaceState(RaceState raceState){
System.out.println(raceState.getTimeTillStart());
this.raceState = raceState;
timeUntilStart.setText(raceState.getTimeTillStartStr());
}
public void disableReadyButton () { public void disableReadyButton () {
readyButton.setDisable(true); readyButton.setDisable(true);
} }
+32 -6
View File
@@ -1,6 +1,11 @@
<?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.ListView?> <?import javafx.scene.control.ListView?>
@@ -11,6 +16,7 @@
<?import javafx.scene.layout.RowConstraints?> <?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?> <?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?> <?import javafx.scene.text.Text?>
<GridPane fx:id="lobbyScreen" nodeOrientation="LEFT_TO_RIGHT" prefHeight="960.0" prefWidth="1530.0" style="-fx-background-color: #2C2c36;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.LobbyController"> <GridPane fx:id="lobbyScreen" nodeOrientation="LEFT_TO_RIGHT" prefHeight="960.0" prefWidth="1530.0" style="-fx-background-color: #2C2c36;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.LobbyController">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
@@ -21,11 +27,6 @@
<RowConstraints maxHeight="100.0" minHeight="0.0" prefHeight="0.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="100.0" minHeight="0.0" prefHeight="0.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<Text fx:id="lobbyIpText" fill="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="Lobby: IP" GridPane.columnSpan="2147483647" GridPane.halignment="CENTER">
<font>
<Font size="29.0" />
</font>
</Text>
<GridPane prefHeight="166.0" prefWidth="1530.0" GridPane.rowIndex="2"> <GridPane prefHeight="166.0" prefWidth="1530.0" GridPane.rowIndex="2">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
@@ -130,5 +131,30 @@
</ImageView> </ImageView>
</children> </children>
</GridPane> </GridPane>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="134.0" minHeight="10.0" prefHeight="32.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="134.0" minHeight="10.0" prefHeight="35.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="134.0" minHeight="10.0" prefHeight="32.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="79.0" minHeight="10.0" prefHeight="52.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="79.0" minHeight="10.0" prefHeight="35.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Text fx:id="lobbyIpText" fill="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="Server Name" GridPane.columnSpan="2147483647" GridPane.halignment="CENTER" GridPane.rowIndex="1">
<font>
<Font size="29.0" />
</font>
</Text>
<Text fx:id="timeUntilStart" fill="#f8f8f8" strokeType="OUTSIDE" strokeWidth="0.0" text="00:00" GridPane.columnSpan="2147483647" GridPane.halignment="CENTER" GridPane.rowIndex="3">
<font>
<Font size="20.0" />
</font>
</Text>
<Text fx:id="courseNameText" fill="#e1e1e1" strokeType="OUTSIDE" strokeWidth="0.0" text="Course Name" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
</children>
</GridPane>
</children> </children>
</GridPane> </GridPane>