diff --git a/pom.xml b/pom.xml index aac3b0c7..fca06536 100644 --- a/pom.xml +++ b/pom.xml @@ -69,8 +69,8 @@ commons-cli 1.4 - + diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index 3b914350..8c6f85ac 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -67,8 +67,6 @@ public class App extends Application { @Override public void start(Stage primaryStage) throws Exception { - PolarTable.parsePolarFile(getClass().getResourceAsStream("/config/acc_polars.csv")); - Parent root = FXMLLoader.load(getClass().getResource("/views/StartScreenView.fxml")); primaryStage.setTitle("RaceVision"); Scene scene = new Scene(root, 1530, 960); diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 1bb968d1..9a54c7d1 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -4,9 +4,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import seng302.gameServer.server.messages.BoatAction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import seng302.gameServer.server.messages.BoatActionType; import seng302.model.Player; import seng302.model.Yacht; import seng302.model.mark.MarkOrder; @@ -56,7 +56,6 @@ public class GameState implements Runnable { players = new ArrayList<>(); currentStage = GameStages.LOBBYING; isRaceStarted = false; - yachts = new HashMap<>(); //set this when game stage changes to prerace previousUpdateTime = System.currentTimeMillis(); yachts = new HashMap<>(); @@ -75,7 +74,8 @@ public class GameState implements Runnable { public static void addPlayer(Player player) { players.add(player); - String playerText = player.getYacht().getSourceId() + " " + player.getYacht().getBoatName() + " " + player.getYacht().getCountry(); + String playerText = player.getYacht().getSourceId() + " " + player.getYacht().getBoatName() + + " " + player.getYacht().getCountry(); playerStringMap.put(player, playerText); } @@ -132,7 +132,7 @@ public class GameState implements Runnable { return yachts; } - public static void updateBoat(Integer sourceId, BoatActionType actionType) { + public static void updateBoat(Integer sourceId, BoatAction actionType) { Yacht playerYacht = yachts.get(sourceId); // System.out.println("-----------------------"); switch (actionType) { diff --git a/src/main/java/seng302/gameServer/HeartbeatThread.java b/src/main/java/seng302/gameServer/HeartbeatThread.java index f15868c3..b168a197 100644 --- a/src/main/java/seng302/gameServer/HeartbeatThread.java +++ b/src/main/java/seng302/gameServer/HeartbeatThread.java @@ -42,7 +42,6 @@ public class HeartbeatThread extends Thread{ */ private void sendHeartbeatToAllPlayers(){ Message heartbeat = new Heartbeat(seqNum); - for (Player player : GameState.getPlayers()){ if (!player.getSocket().isConnected()) { playerLostConnection(player); @@ -54,7 +53,6 @@ public class HeartbeatThread extends Thread{ playerLostConnection(player); } } - updateDelegate(); seqNum++; } @@ -71,7 +69,6 @@ public class HeartbeatThread extends Thread{ public void run(){ Timer t = new Timer(); - t.schedule(new TimerTask() { @Override public void run() { diff --git a/src/main/java/seng302/gameServer/MainServerThread.java b/src/main/java/seng302/gameServer/MainServerThread.java index dca712f3..24b94899 100644 --- a/src/main/java/seng302/gameServer/MainServerThread.java +++ b/src/main/java/seng302/gameServer/MainServerThread.java @@ -8,6 +8,7 @@ import java.util.Observable; import java.util.Timer; import java.util.TimerTask; import seng302.model.Player; +import seng302.model.PolarTable; /** * A class describing the overall server, which creates and collects server threads for each client @@ -31,7 +32,7 @@ public class MainServerThread extends Observable implements Runnable, ClientConn } catch (IOException e) { serverLog("IO error in server thread handler upon trying to make new server socket", 0); } - + PolarTable.parsePolarFile(getClass().getResourceAsStream("/config/acc_polars.csv")); terminated = false; thread = new Thread(this); thread.start(); @@ -43,6 +44,7 @@ public class MainServerThread extends Observable implements Runnable, ClientConn HeartbeatThread heartbeatThread; serverListenThread = new ServerListenThread(serverSocket, this); + heartbeatThread = new HeartbeatThread(this); heartbeatThread.start(); @@ -101,9 +103,11 @@ public class MainServerThread extends Observable implements Runnable, ClientConn public void clientConnected(ServerToClientThread serverToClientThread) { serverLog("Player Connected From " + serverToClientThread.getThread().getName(), 0); serverToClientThreads.add(serverToClientThread); - this.addObserver(serverToClientThread); - setChanged(); - notifyObservers(); + serverToClientThread.addConnectionListener(() -> { + for (ServerToClientThread thread : serverToClientThreads) { + thread.sendSetupMessages(); + } + }); } /** @@ -120,11 +124,15 @@ public class MainServerThread extends Observable implements Runnable, ClientConn serverLog("Player " + player.getYacht().getSourceId() + "'s socket disconnected", 0); GameState.removeYacht(player.getYacht().getSourceId()); GameState.removePlayer(player); + ServerToClientThread closedConnection = null; for (ServerToClientThread serverToClientThread : serverToClientThreads) { if (serverToClientThread.getSocket() == player.getSocket()) { - this.deleteObserver(serverToClientThread); + closedConnection = serverToClientThread; + } else { + serverToClientThread.sendSetupMessages(); } } + serverToClientThreads.remove(closedConnection); setChanged(); notifyObservers(); } diff --git a/src/main/java/seng302/gameServer/ServerPacketParser.java b/src/main/java/seng302/gameServer/ServerPacketParser.java index 21841f18..84f8fd17 100644 --- a/src/main/java/seng302/gameServer/ServerPacketParser.java +++ b/src/main/java/seng302/gameServer/ServerPacketParser.java @@ -5,16 +5,16 @@ import java.util.Arrays; import seng302.gameServer.server.messages.ClientType; import seng302.gameServer.server.messages.Message; import seng302.model.stream.packets.StreamPacket; -import seng302.gameServer.server.messages.BoatActionType; +import seng302.gameServer.server.messages.BoatAction; public class ServerPacketParser { - public static BoatActionType extractBoatAction(StreamPacket packet) { + public static BoatAction extractBoatAction(StreamPacket packet) { byte[] payload = packet.getPayload(); int messageVersionNo = payload[0]; long actionTypeValue = Message.bytesToLong(Arrays.copyOfRange(payload, 0, 1)); - return BoatActionType.getType((int) actionTypeValue); + return BoatAction.getType((int) actionTypeValue); } public static ClientType extractClientType(StreamPacket packet){ diff --git a/src/main/java/seng302/gameServer/ServerToClientThread.java b/src/main/java/seng302/gameServer/ServerToClientThread.java index 223598bd..f3044367 100644 --- a/src/main/java/seng302/gameServer/ServerToClientThread.java +++ b/src/main/java/seng302/gameServer/ServerToClientThread.java @@ -12,8 +12,6 @@ import java.net.SocketException; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; -import java.util.Observable; -import java.util.Observer; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; import java.util.zip.CRC32; @@ -40,6 +38,26 @@ import seng302.model.stream.packets.StreamPacket; import seng302.model.stream.xml.generator.Race; import seng302.model.stream.xml.generator.Regatta; import seng302.utilities.XMLGenerator; +import seng302.gameServer.server.messages.BoatAction; +import seng302.gameServer.server.messages.BoatLocationMessage; +import seng302.gameServer.server.messages.BoatStatus; +import seng302.gameServer.server.messages.BoatSubMessage; +import seng302.gameServer.server.messages.ClientType; +import seng302.gameServer.server.messages.Message; +import seng302.gameServer.server.messages.RaceStatus; +import seng302.gameServer.server.messages.RaceStatusMessage; +import seng302.gameServer.server.messages.RaceType; +import seng302.gameServer.server.messages.RegistrationResponseMessage; +import seng302.gameServer.server.messages.RegistrationResponseStatus; +import seng302.gameServer.server.messages.XMLMessage; +import seng302.gameServer.server.messages.XMLMessageSubType; +import seng302.model.Player; +import seng302.model.Yacht; +import seng302.model.stream.packets.PacketType; +import seng302.model.stream.packets.StreamPacket; +import seng302.model.stream.xml.generator.Race; +import seng302.model.stream.xml.generator.Regatta; +import seng302.utilities.XMLGenerator; /** * A class describing a single connection to a Client for the purposes of sending and receiving on @@ -48,6 +66,14 @@ import seng302.utilities.XMLGenerator; */ public class ServerToClientThread implements Runnable, Observer { + /** + * Called to notify listeners when this thread receives a connection correctly. + */ + @FunctionalInterface + interface ConnectionListener { + void notifyConnection (); + } + private Logger logger = LoggerFactory.getLogger(ServerToClientThread.class); private Thread thread; @@ -66,6 +92,8 @@ public class ServerToClientThread implements Runnable, Observer { private XMLGenerator xml; + private List connectionListeners = new ArrayList<>(); + public ServerToClientThread(Socket socket) { this.socket = socket; seqNo = 0; @@ -81,7 +109,7 @@ public class ServerToClientThread implements Runnable, Observer { thread.start(); } - private void setUpYacht(){ + private void setUpPlayer(){ BufferedReader fn; String fName = ""; BufferedReader ln; @@ -144,12 +172,14 @@ public class ServerToClientThread implements Runnable, Observer { this.clientType = clientType; this.sourceId = sourceId; - setUpYacht(); - isRegistered = true; os.write(responseMessage.getBuffer()); - sendSetupMessages(); + setUpPlayer(); + + for (ConnectionListener listener : connectionListeners) { + listener.notifyConnection(); + } } public void run() { @@ -180,7 +210,7 @@ public class ServerToClientThread implements Runnable, Observer { //System.out.println("RECEIVED A PACKET"); switch (PacketType.assignPacketType(type, payload)) { case BOAT_ACTION: - BoatActionType actionType = ServerPacketParser + BoatAction actionType = ServerPacketParser .extractBoatAction( new StreamPacket(type, payloadLength, timeStamp, payload)); GameState.updateBoat(sourceId, actionType); @@ -206,7 +236,7 @@ public class ServerToClientThread implements Runnable, Observer { } } - private void sendSetupMessages() { + public void sendSetupMessages() { xml = new XMLGenerator(); Race race = new Race(); @@ -240,7 +270,6 @@ public class ServerToClientThread implements Runnable, Observer { } } - private int readByte() throws Exception { int currentByte = -1; try { @@ -291,7 +320,6 @@ public class ServerToClientThread implements Runnable, Observer { public void sendBoatLocationPackets() { ArrayList yachts = new ArrayList<>(GameState.getYachts().values()); for (Yacht yacht : yachts) { -// System.out.println("[SERVER] Lat: " + yacht.getLocation().getLat() + " Lon: " + yacht.getLocation().getLng()); BoatLocationMessage boatLocationMessage = new BoatLocationMessage( yacht.getSourceId(), @@ -312,7 +340,6 @@ public class ServerToClientThread implements Runnable, Observer { public void sendRaceStatusMessage() { // variables taken from GameServerThread - List boatSubMessages = new ArrayList<>(); BoatStatus boatStatus; RaceStatus raceStatus; @@ -347,4 +374,12 @@ public class ServerToClientThread implements Runnable, Observer { public Socket getSocket() { return socket; } + + public void addConnectionListener(ConnectionListener listener) { + connectionListeners.add(listener); + } + + public void removeConnectionListener(ConnectionListener listener) { + connectionListeners.remove(listener); + } } diff --git a/src/main/java/seng302/gameServer/server/messages/BoatActionType.java b/src/main/java/seng302/gameServer/server/messages/BoatAction.java similarity index 62% rename from src/main/java/seng302/gameServer/server/messages/BoatActionType.java rename to src/main/java/seng302/gameServer/server/messages/BoatAction.java index 53fc6018..cc53668c 100644 --- a/src/main/java/seng302/gameServer/server/messages/BoatActionType.java +++ b/src/main/java/seng302/gameServer/server/messages/BoatAction.java @@ -6,29 +6,30 @@ import java.util.Map; /** * Created by kre39 on 12/07/17. */ -public enum BoatActionType { +public enum BoatAction { VMG(1), SAILS_IN(2), 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<>(); + private static final Map intToTypeMap = new HashMap<>(); static { - for (BoatActionType type : BoatActionType.values()) { + for (BoatAction type : BoatAction.values()) { intToTypeMap.put(type.getValue(), type); } } - BoatActionType(int type){ + BoatAction(int type){ this.type = type; } - public static BoatActionType getType(int value) { + public static BoatAction getType(int value) { return intToTypeMap.get(value); } diff --git a/src/main/java/seng302/gameServer/server/messages/BoatActionMessage.java b/src/main/java/seng302/gameServer/server/messages/BoatActionMessage.java index cfa596f7..2fc084e5 100644 --- a/src/main/java/seng302/gameServer/server/messages/BoatActionMessage.java +++ b/src/main/java/seng302/gameServer/server/messages/BoatActionMessage.java @@ -6,9 +6,9 @@ package seng302.gameServer.server.messages; public class BoatActionMessage extends Message{ private final MessageType MESSAGE_TYPE = MessageType.BOAT_ACTION; private final int MESSAGE_SIZE = 1; - private BoatActionType actionType; + private BoatAction actionType; - public BoatActionMessage(BoatActionType actionType) { + public BoatActionMessage(BoatAction actionType) { this.actionType = actionType; setHeader(new Header(MessageType.BOAT_ACTION, 0, (short) 1)); // the second variable is the source id allocateBuffer(); diff --git a/src/main/java/seng302/model/PolarTable.java b/src/main/java/seng302/model/PolarTable.java index dee22278..9334cc54 100644 --- a/src/main/java/seng302/model/PolarTable.java +++ b/src/main/java/seng302/model/PolarTable.java @@ -71,8 +71,6 @@ public final class PolarTable { } catch (IOException e) { System.out.println("[PolarTable] IO exception"); } - - } @@ -155,7 +153,6 @@ public final class PolarTable { public static Double getClosestWindSpeedInPolar(Double thisWindSpeed) { Double smallestDif = Double.POSITIVE_INFINITY; Double closestWind = 0d; - for (Double polarWindSpeed : polarTable.keySet()) { Double difference = Math.abs(polarWindSpeed - thisWindSpeed); if (difference < smallestDif) { diff --git a/src/main/java/seng302/model/Yacht.java b/src/main/java/seng302/model/Yacht.java index da1b434f..b46acac3 100644 --- a/src/main/java/seng302/model/Yacht.java +++ b/src/main/java/seng302/model/Yacht.java @@ -59,7 +59,7 @@ public class Yacht extends Observable { private Integer legNumber = 0; //SERVER SIDE - private final Double TURN_STEP = 5.0; + public static final Double TURN_STEP = 5.0; //This should be in some utils class somewhere 2bh. Public for tests sake. private Double lastHeading; private Boolean sailIn; private GeoPoint location; @@ -498,9 +498,9 @@ public class Yacht extends Observable { private void turnTowardsHeading(Double newHeading) { Double newVal = heading - newHeading; if (Math.floorMod(newVal.longValue(), 360L) > 180) { - adjustHeading(TURN_STEP); + adjustHeading(TURN_STEP / 5); } else { - adjustHeading(-TURN_STEP); + adjustHeading(-TURN_STEP / 5); } } diff --git a/src/main/java/seng302/visualiser/ClientToServerThread.java b/src/main/java/seng302/visualiser/ClientToServerThread.java index f59fa81d..dc38e129 100644 --- a/src/main/java/seng302/visualiser/ClientToServerThread.java +++ b/src/main/java/seng302/visualiser/ClientToServerThread.java @@ -10,6 +10,8 @@ import java.util.ArrayList; import java.util.Arrays; 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; @@ -19,7 +21,12 @@ import javafx.scene.control.Alert.AlertType; import javafx.scene.control.ButtonType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import seng302.gameServer.server.messages.*; +import seng302.gameServer.server.messages.BoatAction; +import seng302.gameServer.server.messages.BoatActionMessage; +import seng302.gameServer.server.messages.ClientType; +import seng302.gameServer.server.messages.Message; +import seng302.gameServer.server.messages.RegistrationRequestMessage; +import seng302.gameServer.server.messages.RegistrationResponseStatus; import seng302.model.stream.packets.PacketType; import seng302.model.stream.packets.StreamPacket; @@ -51,9 +58,16 @@ public class ClientToServerThread implements Runnable { private Socket socket; private InputStream is; - private OutputStream os; + private Logger logger = LoggerFactory.getLogger(ClientToServerThread.class); + //Output stream + private OutputStream os; + private Timer upWindPacketTimer = new Timer(); + private Timer downWindPacketTimer = new Timer(); + private boolean upwindTimerFlag = false, downwindTimerFlag = false; + static public final int PACKET_SENDING_INTERVAL_MS = 100; + private int clientId = -1; // private Boolean updateClient = true; @@ -141,6 +155,7 @@ public class ClientToServerThread implements Runnable { } } } catch (ByteReadException e) { + e.printStackTrace(); closeSocket(); Platform.runLater(() -> { Alert alert = new Alert(AlertType.ERROR); @@ -151,7 +166,6 @@ public class ClientToServerThread implements Runnable { clientLog(e.getMessage(), 1); return; } -// System.out.println("streamPackets = " + streamPackets.size()); } closeSocket(); clientLog("Closed connection to Server", 0); @@ -205,21 +219,81 @@ public class ClientToServerThread implements Runnable { }); } - /** - * Send the post-start race course information - * @param boatActionMessage The message to send + * Sends packets for the given boat action. Special cases are: \n + * - DOWNWIND = Packets are sent every ClientToServerThread.PACKET_SENDING_INTERVAL_MS + * - UPWIND = Packets are sent every ClientToServerThread.PACKET_SENDING_INTERVAL_MS + * - MAINTAIN_HEADING = DOWNWIND and UPWIND packets stop being sent. + * @param actionType The boat action that will dictate packets sent. */ - public void sendBoatActionMessage(BoatActionMessage boatActionMessage) { - if (clientId == -1) return; - - try { - os.write(boatActionMessage.getBuffer()); - } catch (IOException e) { - clientLog("Could not write to server", 1); + public void sendBoatAction(BoatAction actionType) { + switch (actionType) { + case MAINTAIN_HEADING: + if (upwindTimerFlag) { + cancelTimer(upWindPacketTimer); + upwindTimerFlag = false; + upWindPacketTimer = new Timer(); + } + if (downwindTimerFlag) { + cancelTimer(downWindPacketTimer); + downwindTimerFlag = false; + downWindPacketTimer = new Timer(); + } + break; + case DOWNWIND: + if (!downwindTimerFlag) { + downwindTimerFlag = true; + downWindPacketTimer.scheduleAtFixedRate( + new TimerTask() { + @Override + public void run() { + sendBoatAction(new BoatActionMessage(BoatAction.DOWNWIND)); + } + }, 0, PACKET_SENDING_INTERVAL_MS + ); + } + break; + case UPWIND: + if (!upwindTimerFlag) { + upwindTimerFlag = true; + upWindPacketTimer.scheduleAtFixedRate( + new TimerTask() { + @Override + public void run() { + sendBoatAction(new BoatActionMessage(BoatAction.UPWIND)); + } + }, 0, PACKET_SENDING_INTERVAL_MS + ); + } + break; + default: + sendBoatAction(new BoatActionMessage(actionType)); + break; } } + /** + * Cancels a packet sending timer. + * @param timer The timer to cancel. + */ + private void cancelTimer (Timer timer) { + timer.cancel(); + timer.purge(); + } + + /** + * Sends a boat action of the given message type. + * @param message The given message type. + */ + private void sendBoatAction(BoatActionMessage message) { + if (clientId != -1) { + try { + os.write(message.getBuffer()); + } catch (IOException e) { + clientLog("Could not write to server", 1); + } + } + } private void closeSocket() { try { @@ -273,11 +347,8 @@ public class ClientToServerThread implements Runnable { } } - public Thread getThread() { - return thread; - } - public int getClientId () { return clientId; } + } diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index a2ad4486..e65cfbd9 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -13,8 +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.BoatActionMessage; -import seng302.gameServer.server.messages.BoatActionType; +import seng302.gameServer.server.messages.BoatAction; import seng302.model.RaceState; import seng302.model.Yacht; import seng302.model.stream.packets.StreamPacket; @@ -31,7 +30,8 @@ import seng302.visualiser.controllers.LobbyController.CloseStatus; import seng302.visualiser.controllers.RaceViewController; /** - * Created by cir27 on 20/07/17. + * This class is a client side instance of a yacht racing game in JavaFX. The game is instantiated + * with a JavaFX Pane to insert itself into. */ public class GameClient { @@ -48,13 +48,20 @@ public class GameClient { private ObservableList clientLobbyList = FXCollections.observableArrayList(); - private long lastSendingTime; - private int KEY_STROKE_SENDING_FREQUENCY = 50; - + /** + * Create an instance of the game client. Does not do anything until run with runAsClient() + * runAsHost(). + * @param holder The JavaFX Pane that the visual elements for the race will be inserted into. + */ public GameClient(Pane holder) { this.holderPane = holder; } + /** + * Connect to a game at the given address and starts the visualiser. + * @param ipAddress IP to connect to. + * @param portNumber Port to connect to. + */ public void runAsClient(String ipAddress, Integer portNumber) { try { socketThread = new ClientToServerThread(ipAddress, portNumber); @@ -71,6 +78,11 @@ public class GameClient { lobbyController.addCloseListener((exitCause) -> this.loadStartScreen()); } + /** + * Connect to a game as the host at the given address and starts the visualiser. + * @param ipAddress IP to connect to. + * @param portNumber Port to connect to. + */ public void runAsHost(String ipAddress, Integer portNumber) { server = new MainServerThread(); try { @@ -94,10 +106,8 @@ public class GameClient { private void loadStartScreen() { socketThread.setSocketToClose(); - socketThread = null; if (server != null) { - // TODO: 26/07/17 cir27 - handle disconnecting -// server.shutDown(); + server.terminate(); server = null; } FXMLLoader fxmlLoader = new FXMLLoader( @@ -179,12 +189,9 @@ public class GameClient { StreamParser.extractXmlMessage(packet) ); clientLobbyList.clear(); - allBoatsMap.forEach((id, boat) -> { - clientLobbyList.add(id + " " + boat.getBoatName()); -// System.out.println(id + " " + boat.getBoatName()); - - }); -// startRaceIfAllDataReceived(); + allBoatsMap.forEach((id, boat) -> + clientLobbyList.add(id + " " + boat.getBoatName()) + ); break; case RACE_START_STATUS: @@ -279,47 +286,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.sendBoatAction(BoatAction.VMG); break; + case PAGE_UP: // upwind + socketThread.sendBoatAction(BoatAction.UPWIND); break; + case PAGE_DOWN: // downwind + socketThread.sendBoatAction(BoatAction.DOWNWIND); break; + case ENTER: // tack/gybe + socketThread.sendBoatAction(BoatAction.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.sendBoatAction(BoatAction.SAILS_IN); break; + case PAGE_UP: + case PAGE_DOWN: + socketThread.sendBoatAction(BoatAction.MAINTAIN_HEADING); break; + } + } } diff --git a/src/main/java/seng302/visualiser/GameView.java b/src/main/java/seng302/visualiser/GameView.java index 14c8a319..a7f353d9 100644 --- a/src/main/java/seng302/visualiser/GameView.java +++ b/src/main/java/seng302/visualiser/GameView.java @@ -135,7 +135,7 @@ public class GameView extends Pane { } } // Platform.runLater(() -> -// boatObjects.forEach((boat, boatObject) -> boatObject.updateLocation()) + boatObjects.forEach((boat, boatObject) -> boatObject.updateLocation()); // ); } }; @@ -502,7 +502,6 @@ public class GameView extends Pane { distanceFromReference = GeoUtility.getDistance( minLatPoint, new GeoPoint(unscaledLat, unscaledLon) ); -// System.out.println("distanceFromReference = " + distanceFromReference); if (angleFromReference >= 0 && angleFromReference <= Math.PI / 2) { xAxisLocation += Math.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); yAxisLocation -= Math.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference); @@ -522,8 +521,6 @@ public class GameView extends Pane { if(horizontalInversion) { xAxisLocation = canvasWidth - bufferSize - (xAxisLocation - bufferSize); } -// System.out.println("yAxisLocation = " + yAxisLocation + " " + unscaledLat); -// System.out.println("xAxisLocation = " + xAxisLocation + " " + unscaledLon); return new Point2D(xAxisLocation, yAxisLocation); } 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