diff --git a/pom.xml b/pom.xml
index aac3b0c7..b329e067 100644
--- a/pom.xml
+++ b/pom.xml
@@ -69,6 +69,21 @@
commons-cli
1.4
+
+
+ org.testfx
+ testfx-core
+ 4.0.1-alpha
+ test
+
+
+
+ org.testfx
+ testfx-junit
+ 4.0.6-alpha
+ test
+
+
diff --git a/src/main/java/seng302/gameServer/server/messages/BoatActionType.java b/src/main/java/seng302/gameServer/server/messages/BoatActionType.java
index 53fc6018..1b9fdd58 100644
--- a/src/main/java/seng302/gameServer/server/messages/BoatActionType.java
+++ b/src/main/java/seng302/gameServer/server/messages/BoatActionType.java
@@ -13,7 +13,8 @@ public enum BoatActionType {
SAILS_OUT(3),
TACK_GYBE(4),
UPWIND(5),
- DOWNWIND(6);
+ DOWNWIND(6),
+ MAINTAIN_HEADING(7);
private final int type;
private static final Map intToTypeMap = new HashMap<>();
diff --git a/src/main/java/seng302/model/Yacht.java b/src/main/java/seng302/model/Yacht.java
index d7cd1f9e..9afe778a 100644
--- a/src/main/java/seng302/model/Yacht.java
+++ b/src/main/java/seng302/model/Yacht.java
@@ -48,7 +48,7 @@ public class Yacht {
private Integer legNumber = 0;
//SERVER SIDE
- private final Double TURN_STEP = 5.0;
+ static public final Double TURN_STEP = 1.0; //This should be in some utils class somewhere 2bh. Public for tests sake.
private Double lastHeading;
private Boolean sailIn;
private GeoPoint location;
diff --git a/src/main/java/seng302/visualiser/map/Boundary.java b/src/main/java/seng302/v/map/Boundary.java
similarity index 96%
rename from src/main/java/seng302/visualiser/map/Boundary.java
rename to src/main/java/seng302/v/map/Boundary.java
index 21f2661d..68085ec7 100644
--- a/src/main/java/seng302/visualiser/map/Boundary.java
+++ b/src/main/java/seng302/v/map/Boundary.java
@@ -1,4 +1,4 @@
-package seng302.visualiser.map;
+package seng302.v.map;
/**
* The Boundary class represents a rectangle territorial boundary on a map. It
diff --git a/src/main/java/seng302/visualiser/map/CanvasMap.java b/src/main/java/seng302/v/map/CanvasMap.java
similarity index 98%
rename from src/main/java/seng302/visualiser/map/CanvasMap.java
rename to src/main/java/seng302/v/map/CanvasMap.java
index e79805e4..10cd60c3 100644
--- a/src/main/java/seng302/visualiser/map/CanvasMap.java
+++ b/src/main/java/seng302/v/map/CanvasMap.java
@@ -1,4 +1,4 @@
-package seng302.visualiser.map;
+package seng302.v.map;
import java.net.URL;
import javafx.geometry.Point2D;
diff --git a/src/main/java/seng302/visualiser/map/MercatorProjection.java b/src/main/java/seng302/v/map/MercatorProjection.java
similarity index 96%
rename from src/main/java/seng302/visualiser/map/MercatorProjection.java
rename to src/main/java/seng302/v/map/MercatorProjection.java
index 3f86e628..28bd341f 100644
--- a/src/main/java/seng302/visualiser/map/MercatorProjection.java
+++ b/src/main/java/seng302/v/map/MercatorProjection.java
@@ -1,4 +1,4 @@
-package seng302.visualiser.map;
+package seng302.v.map;
import javafx.geometry.Point2D;
import seng302.model.GeoPoint;
@@ -28,7 +28,7 @@ public class MercatorProjection {
* @param geo GeoPoint (lat, lng) location to be projected
* @return the projection Point2D (x, y) on planar
*/
- static Point2D toMapPoint(GeoPoint geo) {
+ public static Point2D toMapPoint(GeoPoint geo) {
double x, y;
Point2D origin = new Point2D(MERCATOR_RANGE / 2.0, MERCATOR_RANGE / 2.0);
x = (origin.getX() + geo.getLng() * pixelsPerLngDegree);
diff --git a/src/main/java/seng302/visualiser/map/TestMapController.java b/src/main/java/seng302/v/map/TestMapController.java
similarity index 95%
rename from src/main/java/seng302/visualiser/map/TestMapController.java
rename to src/main/java/seng302/v/map/TestMapController.java
index cd0b4c60..520a1e3b 100644
--- a/src/main/java/seng302/visualiser/map/TestMapController.java
+++ b/src/main/java/seng302/v/map/TestMapController.java
@@ -1,4 +1,4 @@
-package seng302.visualiser.map;
+package seng302.v.map;
import java.net.URL;
import java.util.ResourceBundle;
diff --git a/src/main/java/seng302/visualiser/ClientToServerThread.java b/src/main/java/seng302/visualiser/ClientToServerThread.java
index 414696c8..1bfaa10d 100644
--- a/src/main/java/seng302/visualiser/ClientToServerThread.java
+++ b/src/main/java/seng302/visualiser/ClientToServerThread.java
@@ -9,12 +9,15 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
+import java.util.Timer;
+import java.util.TimerTask;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
+import seng302.gameServer.server.messages.BoatActionType;
import seng302.model.stream.packets.StreamPacket;
import seng302.gameServer.server.messages.BoatActionMessage;
import seng302.gameServer.server.messages.Message;
@@ -47,11 +50,15 @@ public class ClientToServerThread implements Runnable {
private Socket socket;
private InputStream is;
+
+ //Output stream
private OutputStream os;
+ private Timer osTimer = new Timer();
+ private Queue eventQueue = new ConcurrentLinkedQueue<>();
+ private boolean upwindFlag = false, downwindFlag = false;
+ static public final int PACKET_SENDING_INTERVAL_MS = 20;
private int clientId;
-
-// private Boolean updateClient = true;
private ByteArrayOutputStream crcBuffer;
private boolean socketOpen = true;
@@ -83,6 +90,15 @@ public class ClientToServerThread implements Runnable {
thread = new Thread(this);
thread.start();
+
+ osTimer.scheduleAtFixedRate(
+ new TimerTask() {
+ @Override
+ public void run() {
+ processBoatActionQueue();
+ }
+ }, 0, PACKET_SENDING_INTERVAL_MS
+ );
}
/**
@@ -181,18 +197,42 @@ public class ClientToServerThread implements Runnable {
/**
- * Send the post-start race course information
- * @param boatActionMessage The message to send
+ * Processes next element in the queue of events to send.
*/
- public void sendBoatActionMessage(BoatActionMessage boatActionMessage) {
+ private void processBoatActionQueue() {
+ BoatActionType action = eventQueue.poll();
+ if (action != null) {
+ switch (action) {
+ case MAINTAIN_HEADING:
+ downwindFlag = upwindFlag = false; break;
+ case DOWNWIND:
+ downwindFlag = true; break;
+ case UPWIND:
+ upwindFlag = true; break;
+ default:
+ sendBoatAction(new BoatActionMessage(action)); break;
+ }
+ }
+ if (downwindFlag) {
+ sendBoatAction(new BoatActionMessage(BoatActionType.DOWNWIND));
+ }
+ if (upwindFlag) {
+ sendBoatAction(new BoatActionMessage(BoatActionType.UPWIND));
+ }
+ }
+
+ /**
+ * Sends a boat action of the given message type.
+ * @param message The given message type.
+ */
+ private void sendBoatAction(BoatActionMessage message) {
try {
- os.write(boatActionMessage.getBuffer());
+ os.write(message.getBuffer());
} catch (IOException e) {
clientLog("Could not write to server", 1);
}
}
-
private void closeSocket() {
try {
socket.close();
@@ -245,11 +285,11 @@ public class ClientToServerThread implements Runnable {
}
}
- public Thread getThread() {
- return thread;
- }
-
public int getClientId () {
return clientId;
}
+
+ public void sendBoatEvent(BoatActionType actionType) {
+ eventQueue.add(actionType);
+ }
}
diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java
index 915eef37..0b52a3a4 100644
--- a/src/main/java/seng302/visualiser/GameClient.java
+++ b/src/main/java/seng302/visualiser/GameClient.java
@@ -13,6 +13,7 @@ import javafx.scene.Node;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import seng302.gameServer.MainServerThread;
+import seng302.gameServer.server.messages.BoatActionType;
import seng302.model.RaceState;
import seng302.model.Yacht;
import seng302.model.stream.packets.StreamPacket;
@@ -22,8 +23,6 @@ import seng302.model.stream.parser.PositionUpdateData.DeviceType;
import seng302.model.stream.parser.RaceStatusData;
import seng302.model.stream.xml.parser.RaceXMLData;
import seng302.model.stream.xml.parser.RegattaXMLData;
-import seng302.gameServer.server.messages.BoatActionMessage;
-import seng302.gameServer.server.messages.BoatActionType;
import seng302.utilities.StreamParser;
import seng302.utilities.XMLParser;
import seng302.visualiser.controllers.LobbyController;
@@ -48,9 +47,6 @@ public class GameClient {
private ObservableList clientLobbyList = FXCollections.observableArrayList();
- private long lastSendingTime;
- private int KEY_STROKE_SENDING_FREQUENCY = 50;
-
public GameClient(Pane holder) {
this.holderPane = holder;
}
@@ -174,17 +170,13 @@ public class GameClient {
break;
case BOAT_XML:
- System.out.println("GOT SUM BOATS YAY :)");
allBoatsMap = XMLParser.parseBoats(
StreamParser.extractXmlMessage(packet)
);
clientLobbyList.clear();
allBoatsMap.forEach((id, boat) -> {
clientLobbyList.add(id + " " + boat.getBoatName());
-// System.out.println(id + " " + boat.getBoatName());
-
});
-// startRaceIfAllDataReceived();
break;
case RACE_START_STATUS:
@@ -279,47 +271,34 @@ public class GameClient {
* Handle the key-pressed event from the text field.
* @param e The key event triggering this call
*/
- public void keyPressed(KeyEvent e) {
- BoatActionMessage boatActionMessage;
- long currentTime = System.currentTimeMillis();
- if (currentTime - lastSendingTime > KEY_STROKE_SENDING_FREQUENCY) {
- lastSendingTime = currentTime;
- switch (e.getCode()) {
- case SPACE: // align with vmg
- boatActionMessage = new BoatActionMessage(BoatActionType.VMG);
- socketThread.sendBoatActionMessage(boatActionMessage);
- break;
- case PAGE_UP: // upwind
- boatActionMessage = new BoatActionMessage(BoatActionType.UPWIND);
- socketThread.sendBoatActionMessage(boatActionMessage);
- break;
- case PAGE_DOWN: // downwind
- boatActionMessage = new BoatActionMessage(BoatActionType.DOWNWIND);
- socketThread.sendBoatActionMessage(boatActionMessage);
- break;
- case ENTER: // tack/gybe
- boatActionMessage = new BoatActionMessage(BoatActionType.TACK_GYBE);
- socketThread.sendBoatActionMessage(boatActionMessage);
- break;
- //TODO Allow a zoom in and zoom out methods
- case Z: // zoom in
- System.out.println("Zoom in");
- break;
- case X: // zoom out
- System.out.println("Zoom out");
- break;
- }
- }
- }
-
- public void keyReleased(KeyEvent e) {
+ private void keyPressed(KeyEvent e) {
switch (e.getCode()) {
- //TODO 12/07/17 Determine the sail state and send the appropriate packet (eg. if sails are in, send a sail out packet)
- case SHIFT: // sails in/sails out
- BoatActionMessage boatActionMessage = new BoatActionMessage(
- BoatActionType.SAILS_IN);
- socketThread.sendBoatActionMessage(boatActionMessage);
+ case SPACE: // align with vmg
+ socketThread.sendBoatEvent(BoatActionType.VMG); break;
+ case PAGE_UP: // upwind
+ socketThread.sendBoatEvent(BoatActionType.UPWIND); break;
+ case PAGE_DOWN: // downwind
+ socketThread.sendBoatEvent(BoatActionType.DOWNWIND); break;
+ case ENTER: // tack/gybe
+ socketThread.sendBoatEvent(BoatActionType.TACK_GYBE); break;
+ //TODO Allow a zoom in and zoom out methods
+ case Z: // zoom in
+ System.out.println("Zoom in");
+ break;
+ case X: // zoom out
+ System.out.println("Zoom out");
break;
}
}
+
+ private void keyReleased(KeyEvent e) {
+ switch (e.getCode()) {
+ //TODO 12/07/17 Determine the sail state and send the appropriate packet (eg. if sails are in, send a sail out packet)
+ case SHIFT: // sails in/sails out
+ socketThread.sendBoatEvent(BoatActionType.SAILS_IN); break;
+ case PAGE_UP:
+ case PAGE_DOWN:
+ socketThread.sendBoatEvent(BoatActionType.MAINTAIN_HEADING); break;
+ }
+ }
}
diff --git a/src/main/java/seng302/visualiser/GameView.java b/src/main/java/seng302/visualiser/GameView.java
index 73d49b89..180f85ca 100644
--- a/src/main/java/seng302/visualiser/GameView.java
+++ b/src/main/java/seng302/visualiser/GameView.java
@@ -32,8 +32,8 @@ import seng302.visualiser.fxObjects.BoatObject;
import seng302.visualiser.fxObjects.CourseBoundary;
import seng302.visualiser.fxObjects.Gate;
import seng302.visualiser.fxObjects.Marker;
-import seng302.visualiser.map.Boundary;
-import seng302.visualiser.map.CanvasMap;
+import seng302.v.map.Boundary;
+import seng302.v.map.CanvasMap;
/**
* Created by cir27 on 20/07/17.
diff --git a/src/main/java/seng302/visualiser/controllers/LobbyController.java b/src/main/java/seng302/visualiser/controllers/LobbyController.java
index 1a8b13e3..809bd3b5 100644
--- a/src/main/java/seng302/visualiser/controllers/LobbyController.java
+++ b/src/main/java/seng302/visualiser/controllers/LobbyController.java
@@ -4,15 +4,13 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javafx.application.Platform;
-import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
-import javafx.scene.control.ListView;
+import javafx.scene.control.TextArea;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
-import javafx.scene.layout.GridPane;
import javafx.scene.text.Text;
import seng302.gameServer.GameStages;
import seng302.gameServer.GameState;
@@ -33,28 +31,26 @@ public class LobbyController {
void notify(CloseStatus exitCause);
}
- @FXML
- private GridPane lobbyScreen;
@FXML
private Text lobbyIpText;
@FXML
private Button readyButton;
@FXML
- private ListView firstListView;
+ private TextArea playerOneTxt;
@FXML
- private ListView secondListView;
+ private TextArea playerTwoTxt;
@FXML
- private ListView thirdListView;
+ private TextArea playerThreeTxt;
@FXML
- private ListView fourthListView;
+ private TextArea playerFourTxt;
@FXML
- private ListView fifthListView;
+ private TextArea playerFiveTxt;
@FXML
- private ListView sixthListView;
+ private TextArea playerSixTxt;
@FXML
- private ListView seventhListView;
+ private TextArea playerSevenTxt;
@FXML
- private ListView eighthListView;
+ private TextArea playerEightTxt;
@FXML
private ImageView firstImageView;
@FXML
@@ -72,79 +68,67 @@ public class LobbyController {
@FXML
private ImageView eighthImageView;
- private List> competitors = new ArrayList<>();
- private ObservableList firstCompetitor = FXCollections.observableArrayList();
- private ObservableList secondCompetitor = FXCollections.observableArrayList();
- private ObservableList thirdCompetitor = FXCollections.observableArrayList();
- private ObservableList fourthCompetitor = FXCollections.observableArrayList();
- private ObservableList fifthCompetitor = FXCollections.observableArrayList();
- private ObservableList sixthCompetitor = FXCollections.observableArrayList();
- private ObservableList seventhCompetitor = FXCollections.observableArrayList();
- private ObservableList eighthCompetitor = FXCollections.observableArrayList();
-
private List imageViews = new ArrayList<>();
- private List listViews;
+ private List