mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a8599d788b | |||
| 5101e55413 | |||
| 6ecd1c82f4 | |||
| ffd94b34bc | |||
| ba49660868 | |||
| 5dbc23866a | |||
| 057af2799a | |||
| 45669c333a | |||
| f7fd5494ef | |||
| a1d468c689 | |||
| 6fafb02a8f | |||
| 4f80640718 | |||
| d436d2a6e4 | |||
| 27379ae96d | |||
| ce3e08abfc | |||
| 923c381797 | |||
| ece45ff967 | |||
| 02dc1dbd3d | |||
| d9b9c2f808 | |||
| 4e3de02a93 | |||
| 261f68f143 | |||
| ed9b7acc62 | |||
| 74c1219e0d | |||
| 83218ae0a0 | |||
| 0231c43a2c | |||
| a05a41d5ec | |||
| 06bc3644bc | |||
| 7620f0023e | |||
| 77ee1ebbc0 | |||
| 6d0835b0cf | |||
| 54410efa12 | |||
| 74241ee819 | |||
| a9ce8901f5 | |||
| 8810554ce9 | |||
| 7e3ed872ed | |||
| 21ce34dda2 | |||
| 2bf318a122 | |||
| e56d284792 | |||
| 80c26a9e4a | |||
| c4a3df32c8 | |||
| 1e19dd5ab6 | |||
| 1aedcaddf5 | |||
| d7fc339ad5 | |||
| 51078c82a0 | |||
| 22fbb529ef | |||
| 02aabc3162 | |||
| d2a05de25a | |||
| d3e8a21d2f | |||
| c72c4929ff | |||
| 265b20ad61 | |||
| 852575c9e7 | |||
| 567e351c7f | |||
| 72fe8c4881 | |||
| 270326ea77 |
@@ -1,13 +1,29 @@
|
||||
# SENG302 Project Template
|
||||
# Party Parrots At Sea
|
||||
|
||||
Basic Maven project with required Maven reporting setup and basic GitLab CI.
|
||||
**Authors:** Michael Rausch, William Muir, Haoming Yin, Alistair Mcintyre, Kusal Ekanayake, Calum Irwin, Peter Galloway, Tan Zhi You
|
||||
|
||||
It is a requirement that your product should be completely built to a deliverable form using the Maven package goal.
|
||||
### SENG302
|
||||
> The Software Engineering group project gives students in-depth experience in developing software applications in groups. Participants work in groups to develop a complex real application. At the end of this course you will have practiced the skills required to be a Software Engineer in the real world, including gaining the required skills to be able to develop complex applications, dealing with vague (and often conflicting) customer requirements, working under pressure and being a valuable member of a software development team.
|
||||
|
||||
Remember to set up your GitLab CI server (refer to the student guide for instructions).
|
||||
**Find out more:** www.canterbury.ac.nz/courseinfo/GetCourses.aspx?course=SENG302
|
||||
|
||||
### Running the discovery server
|
||||
|
||||
|
||||
```
|
||||
xvfb-run -a -e server.log java -jar app.jar -runAsDiscoveryServer
|
||||
```
|
||||
|
||||
### Video
|
||||
|
||||
https://youtu.be/aHxJsfZLg54
|
||||
|
||||
### Screenshots
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
# Basic Project Structure
|
||||
- `src/` Your application source
|
||||
- `doc/` User and design documentation
|
||||
- `doc/examples/` Demo example files for use with your application
|
||||
|
||||
|
||||
@@ -13,9 +13,6 @@ import org.slf4j.LoggerFactory;
|
||||
import seng302.discoveryServer.DiscoveryServer;
|
||||
import seng302.visualiser.controllers.ViewManager;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class App extends Application {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(App.class);
|
||||
@@ -95,16 +92,12 @@ public class App extends Application {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
/*
|
||||
* Do not trust Java to do garbage collection
|
||||
*/
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
System.gc();
|
||||
}
|
||||
}, 0, 1200);
|
||||
|
||||
// new Timer().schedule(new TimerTask() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// System.gc();
|
||||
// }
|
||||
// }, 0, 1_000);
|
||||
|
||||
try {
|
||||
parseArgs(args);
|
||||
|
||||
@@ -48,7 +48,7 @@ public class DiscoveryServer {
|
||||
" .:;...'cxxxxxxxxxxxxoc;,::,..cdl;;l' \n" +
|
||||
" .cl;':,'';oxxxxxxdxxxxxx:....,cooc,cO; \n" +
|
||||
" .,,,::;,lxoc:,,:lxxxxxxxxxxxo:,,;lxxl;'oNc \n" +
|
||||
" .cdxo;':lxxxxxxc'';cccccoxxxxxxxxxxxxo,.;lc. " + ANSI_YELLOW + "Party-Parrots-At-Sea Discovery Server v0.1 " + selectedColor +"\n" +
|
||||
" .cdxo;':lxxxxxxc'';cccccoxxxxxxxxxxxxo,.;lc. " + ANSI_YELLOW + "Party-Parrots-At-Sea Discovery Server v1.0.0 (Release) " + selectedColor +"\n" +
|
||||
" .loc'.'lxxxxxxxxocc;''''';ccoxxxxxxxxx:..oc \n" +
|
||||
"olc,..',:cccccccccccc:;;;;;;;;:ccccccccc,.'c, \n" +
|
||||
"Ol;......................................;l' ");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package seng302.discoveryServer;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import seng302.discoveryServer.util.ServerListing;
|
||||
@@ -19,7 +20,7 @@ import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class DiscoveryServerClient {
|
||||
private final Integer UPDATE_INTERVAL_MS = 5000;
|
||||
private final Integer UPDATE_INTERVAL_MS = 1000;
|
||||
|
||||
private static String roomCode = null;
|
||||
private Timer serverListingUpdateTimer;
|
||||
@@ -41,7 +42,10 @@ public class DiscoveryServerClient {
|
||||
|
||||
private void failError() {
|
||||
isInInvalidState = true;
|
||||
ViewManager.getInstance().showErrorSnackBar("You do not appear to be able to connect to the internet. Matchmaking will be unavailable.");
|
||||
Platform.runLater(() -> {
|
||||
ViewManager.getInstance().showErrorSnackBar("You do not appear to be able to connect to the internet. Matchmaking will be unavailable.");
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public boolean didFail(){
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package seng302.discoveryServer.util;
|
||||
|
||||
public class ServerListing {
|
||||
public final static int SERVER_TTL_DEFAULT = 10;
|
||||
public final static int SERVER_TTL_DEFAULT = 5;
|
||||
|
||||
private String serverName = "";
|
||||
private String mapName = "";
|
||||
|
||||
@@ -11,6 +11,8 @@ import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import javafx.beans.property.ReadOnlyDoubleWrapper;
|
||||
import javafx.scene.paint.Color;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -68,7 +70,7 @@ public class GameState implements Runnable {
|
||||
|
||||
//Collision constants
|
||||
private static final Double MARK_COLLISION_DISTANCE = 15d;
|
||||
public static final Double YACHT_COLLISION_DISTANCE = 25.0;
|
||||
public static final Double YACHT_COLLISION_DISTANCE = 15.0;
|
||||
private static final Double BOUNCE_DISTANCE_MARK = 20.0;
|
||||
public static final Double BOUNCE_DISTANCE_YACHT = 30.0;
|
||||
private static final Double COLLISION_VELOCITY_PENALTY = 0.3;
|
||||
@@ -82,6 +84,7 @@ public class GameState implements Runnable {
|
||||
|
||||
private static Long previousUpdateTime;
|
||||
public static Double windDirection;
|
||||
public static ReadOnlyDoubleWrapper windDirectionProperty = new ReadOnlyDoubleWrapper();
|
||||
private static Double windSpeed;
|
||||
private static Double serverSpeedMultiplier;
|
||||
|
||||
@@ -96,7 +99,7 @@ public class GameState implements Runnable {
|
||||
private static long startTime;
|
||||
private static Set<Mark> marks = new HashSet<>();
|
||||
private static List<Limit> courseLimit = new ArrayList<>();
|
||||
private static Integer maxPlayers = 8;
|
||||
private static Integer maxPlayers = 12;
|
||||
|
||||
private static List<Token> tokensInPlay;
|
||||
private static RandomSpawn randomSpawn;
|
||||
@@ -108,9 +111,10 @@ public class GameState implements Runnable {
|
||||
|
||||
public GameState() {
|
||||
windDirection = 180d;
|
||||
windDirectionProperty.set(windDirection);
|
||||
windSpeed = 10000d;
|
||||
yachts = new HashMap<>();
|
||||
tokensInPlay = new ArrayList<>();
|
||||
tokensInPlay = new CopyOnWriteArrayList<>();
|
||||
players = new ArrayList<>();
|
||||
customizationFlag = false;
|
||||
playerHasLeftFlag = false;
|
||||
@@ -120,7 +124,7 @@ public class GameState implements Runnable {
|
||||
newMessageListeners = new ArrayList<>();
|
||||
|
||||
resetStartTime();
|
||||
//setCourseLimit("/server_config/race.xml");
|
||||
|
||||
new Thread(this, "GameState").start(); //Run the auto updates on the game state
|
||||
}
|
||||
|
||||
@@ -191,6 +195,7 @@ public class GameState implements Runnable {
|
||||
|
||||
public static void setWindDirection(Double newWindDirection) {
|
||||
windDirection = newWindDirection;
|
||||
windDirectionProperty.set(newWindDirection);
|
||||
}
|
||||
|
||||
public static void setWindSpeed(Double newWindSpeed) {
|
||||
@@ -509,6 +514,7 @@ public class GameState implements Runnable {
|
||||
Double optimalAngle = PolarTable.getOptimalAngle();
|
||||
Double heading = yacht.getHeading();
|
||||
windDirection = (double) Math.floorMod(Math.round(heading + optimalAngle), 360L);
|
||||
windDirectionProperty.set(windDirection);
|
||||
}
|
||||
|
||||
|
||||
@@ -1058,4 +1064,8 @@ public class GameState implements Runnable {
|
||||
public static void setTokensEnabled (boolean tokensEnabled) {
|
||||
GameState.tokensEnabled = tokensEnabled;
|
||||
}
|
||||
|
||||
public static ReadOnlyDoubleWrapper getWindDirectionProperty() {
|
||||
return windDirectionProperty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.net.ServerSocket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import org.slf4j.Logger;
|
||||
@@ -19,12 +18,6 @@ import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||
import seng302.utilities.GeoUtility;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* A class describing the overall server, which creates and collects server threads for each client
|
||||
@@ -32,22 +25,32 @@ import java.util.TimerTask;
|
||||
*/
|
||||
public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(MainServerThread.class);
|
||||
|
||||
private static final int PORT = 4942;
|
||||
private static int selectedPort = PORT;
|
||||
private static final Integer CLIENT_UPDATES_PER_SECOND = 60;
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(MainServerThread.class);
|
||||
private boolean terminated;
|
||||
|
||||
private Thread thread;
|
||||
private boolean hasStarted = false;
|
||||
|
||||
private ServerSocket serverSocket = null;
|
||||
private ArrayList<ServerToClientThread> serverToClientThreads = new ArrayList<>();
|
||||
private static Integer capacity;
|
||||
private RaceXMLData raceXMLData;
|
||||
private RegattaXMLData regattaXMLData;
|
||||
private boolean serverStarted = false;
|
||||
|
||||
public MainServerThread() {
|
||||
new GameState();
|
||||
try {
|
||||
serverSocket = new ServerSocket(0);
|
||||
selectedPort = serverSocket.getLocalPort();
|
||||
} catch (IOException e) {
|
||||
logger.trace("IO error in server thread handler upon trying to make new server socket",
|
||||
0);
|
||||
}
|
||||
terminated = false;
|
||||
Thread thread = new Thread(this, "MainServer");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private void startAdvertisingServer() {
|
||||
Integer capacity = GameState.getCapacity();
|
||||
@@ -65,25 +68,12 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
.setMapName(regattaXMLData.getCourseName())
|
||||
.setCapacity(capacity)
|
||||
.setNumberOfPlayers(numPlayers - 1)
|
||||
.registerGame(PORT, regattaXMLData.getRegattaName());
|
||||
.registerGame(selectedPort, regattaXMLData.getRegattaName());
|
||||
} catch (IOException e) {
|
||||
logger.warn("Could not register server");
|
||||
}
|
||||
}
|
||||
|
||||
public MainServerThread() {
|
||||
new GameState();
|
||||
try {
|
||||
serverSocket = new ServerSocket(PORT);
|
||||
} catch (IOException e) {
|
||||
logger.trace("IO error in server thread handler upon trying to make new server socket",
|
||||
0);
|
||||
}
|
||||
terminated = false;
|
||||
thread = new Thread(this, "MainServer");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private void startServer() {
|
||||
PolarTable.parsePolarFile(getClass().getResourceAsStream("/server_config/acc_polars.csv"));
|
||||
MessageFactory.updateXMLGenerator(raceXMLData, regattaXMLData);
|
||||
@@ -122,7 +112,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
} catch (InterruptedException e) {
|
||||
logger.trace("Interrupted exception in Main Server Thread thread sleep", 1);
|
||||
}
|
||||
if (GameState.getCurrentStage() == GameStages.LOBBYING && GameState.getCustomizationFlag()) {
|
||||
if (GameState.getCurrentStage() == GameStages.LOBBYING && GameState
|
||||
.getCustomizationFlag()) {
|
||||
MessageFactory.updateBoats(new ArrayList<>(GameState.getYachts().values()));
|
||||
sendSetupMessages();
|
||||
GameState.resetCustomizationFlag();
|
||||
@@ -141,7 +132,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
else if (GameState.getCurrentStage() == GameStages.FINISHED) {
|
||||
broadcastMessage(MessageFactory.getRaceStatusMessage());
|
||||
try {
|
||||
Thread.sleep(1000); //Hackish fix to make sure all threads have sent closing RaceStatus
|
||||
Thread.sleep(
|
||||
1000); //Hackish fix to make sure all threads have sent closing RaceStatus
|
||||
terminate();
|
||||
} catch (InterruptedException ie) {
|
||||
logger.trace("Thread interrupted while waiting to terminate clients", 1);
|
||||
@@ -149,7 +141,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
}
|
||||
}
|
||||
try {
|
||||
synchronized (this){
|
||||
synchronized (this) {
|
||||
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
|
||||
serverToClientThread.terminate();
|
||||
}
|
||||
@@ -205,9 +197,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
startServer();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//serverToClientThread.addConnectionListener(this::sendSetupMessages);
|
||||
}
|
||||
|
||||
serverToClientThreads.add(serverToClientThread);
|
||||
|
||||
try {
|
||||
@@ -216,7 +207,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
logger.warn("Couldn't update advertisement");
|
||||
}
|
||||
|
||||
while (regattaXMLData == null && raceXMLData == null){
|
||||
while (regattaXMLData == null && raceXMLData == null) {
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
@@ -242,7 +233,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
|
||||
if (serverToClientThread.getSocket() == player.getSocket()) {
|
||||
closedConnection = serverToClientThread;
|
||||
} else if (GameState.getCurrentStage() != GameStages.RACING){
|
||||
} else if (GameState.getCurrentStage() != GameStages.RACING) {
|
||||
serverToClientThread.sendSetupMessages();
|
||||
}
|
||||
}
|
||||
@@ -255,7 +246,9 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
logger.warn("Couldn't update advertisement");
|
||||
}
|
||||
|
||||
closedConnection.terminate();
|
||||
if (closedConnection != null) {
|
||||
closedConnection.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
public void startGame() {
|
||||
@@ -273,16 +266,12 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
public void run() {
|
||||
broadcastMessage(MessageFactory.getRaceStatusMessage());
|
||||
if (GameState.getCurrentStage() == GameStages.PRE_RACE
|
||||
|| GameState.getCurrentStage() == GameStages.LOBBYING) {
|
||||
|| GameState.getCurrentStage() == GameStages.LOBBYING) {
|
||||
broadcastMessage(MessageFactory.getRaceStartStatusMessage());
|
||||
}
|
||||
}
|
||||
}, 0, 500);
|
||||
|
||||
|
||||
// if (GameState.getCurrentStage() == GameStages.LOBBYING) {
|
||||
// sendSetupMessages();
|
||||
// }
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
@@ -293,117 +282,15 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
* Initialise boats to specific spaced out geopoints behind starting line.
|
||||
*/
|
||||
private void initialiseBoatPositions() {
|
||||
// CompoundMark cm = GameState.getMarkOrder().getMarkOrder().get(0);
|
||||
// GeoPoint startMark1 = cm.getSubMark(1);
|
||||
// GeoPoint startMark2 = cm.getSubMark(2);
|
||||
//
|
||||
// // Calculating midpoint
|
||||
// Double perpendicularAngle = GeoUtility.getBearing(startMark1, startMark2);
|
||||
// Double length = GeoUtility.getDistance(startMark1, startMark2);
|
||||
// GeoPoint midpoint = GeoUtility.getGeoCoordinate(startMark1, perpendicularAngle, length / 2);
|
||||
//
|
||||
// // Setting each boats position side by side
|
||||
// final double SEPARATION = 50.0; // distance apart in meters
|
||||
//
|
||||
// int boatIndex = 0;
|
||||
// for (ServerYacht yacht : GameState.getYachts().values()) {
|
||||
// int distanceApart = boatIndex / 2;
|
||||
//
|
||||
// if (boatIndex % 2 == 1 && boatIndex != 0) {
|
||||
// distanceApart++;
|
||||
// distanceApart *= -1;
|
||||
// }
|
||||
//
|
||||
// GeoPoint spawnMark = GeoUtility
|
||||
// .getGeoCoordinate(midpoint, perpendicularAngle, distanceApart * SEPARATION);
|
||||
//
|
||||
// if (yacht.getHeading() < perpendicularAngle) {
|
||||
// spawnMark = GeoUtility
|
||||
// .getGeoCoordinate(spawnMark, perpendicularAngle + 90, SEPARATION);
|
||||
// } else {
|
||||
// spawnMark = GeoUtility
|
||||
// .getGeoCoordinate(spawnMark, perpendicularAngle + 270, SEPARATION);
|
||||
// }
|
||||
//
|
||||
// yacht.setLocation(spawnMark);
|
||||
// boatIndex++;
|
||||
// }
|
||||
|
||||
// final double SEPARATION = 50.0; // distance apart in meters
|
||||
//
|
||||
// //Reverse of the angle from start to first mark
|
||||
// double angleToFirstMark = 360 - GeoUtility.getBearing(
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getMidPoint(),
|
||||
// GameState.getMarkOrder().getMarkOrder().get(1).getMidPoint()
|
||||
// );
|
||||
//
|
||||
// //Length of start line
|
||||
// double startLineLength = GeoUtility.getDistance(
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(1),
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(2)
|
||||
// );
|
||||
//
|
||||
// //Angle of start line
|
||||
// double startMarkToMarkAngle = GeoUtility.getBearing(
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(1),
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(2)
|
||||
// );
|
||||
//
|
||||
// //How many yachts can fit along the start line
|
||||
// int spacesAlongLine = (int) Math.round(startLineLength / SEPARATION);
|
||||
// //The free space left by the boats.
|
||||
// double buffer = (startLineLength % SEPARATION) / 2;
|
||||
//
|
||||
// //Randomize starting order.
|
||||
// List<ServerYacht> serverYachtList = new ArrayList<>(GameState.getYachts().values());
|
||||
// Collections.shuffle(serverYachtList);
|
||||
//
|
||||
// //set the starting point away from start line.
|
||||
// GeoPoint startingPoint = GeoUtility.getGeoCoordinate(
|
||||
// GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(1),
|
||||
// angleToFirstMark, SEPARATION
|
||||
// );
|
||||
//
|
||||
// //Move it along the start line
|
||||
// startingPoint = GeoUtility.getGeoCoordinate(
|
||||
// startingPoint, startMarkToMarkAngle, buffer
|
||||
// );
|
||||
//
|
||||
// int yachtCount = 0;
|
||||
// int repeats = 0;
|
||||
//
|
||||
// GeoPoint yachtLocation;
|
||||
//
|
||||
// for (ServerYacht serverYacht : serverYachtList) {
|
||||
//
|
||||
// //Move away from start line
|
||||
// yachtLocation = GeoUtility.getGeoCoordinate(
|
||||
// startingPoint, angleToFirstMark,repeats * SEPARATION
|
||||
// );
|
||||
// //Move along start line
|
||||
// yachtLocation = GeoUtility.getGeoCoordinate(
|
||||
// yachtLocation, startMarkToMarkAngle, yachtCount * SEPARATION
|
||||
// );
|
||||
// serverYacht.setLocation(yachtLocation);
|
||||
// serverYacht.setHeading(GeoUtility.getBearing(
|
||||
// yachtLocation, GameState.getMarkOrder().getMarkOrder().get(1).getMidPoint()
|
||||
// ));
|
||||
// //Set location for next yacht
|
||||
// yachtCount++;
|
||||
// if (yachtCount > spacesAlongLine) {
|
||||
// yachtCount = 0;
|
||||
// repeats++;
|
||||
// }
|
||||
// }
|
||||
|
||||
final double DISTANCE_TO_START = 75d;
|
||||
final double YACHT_SEPARATION = 20d;
|
||||
final double YACHT_SEPARATION = 35d;
|
||||
|
||||
//Length of start line
|
||||
double startLineLength = GeoUtility.getDistance(
|
||||
GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(1),
|
||||
GameState.getMarkOrder().getMarkOrder().get(0).getSubMark(2)
|
||||
);
|
||||
) - YACHT_SEPARATION;
|
||||
|
||||
//How many yachts can fit along the start line
|
||||
int spacesAlongLine = (int) Math.round(startLineLength / YACHT_SEPARATION);
|
||||
@@ -425,7 +312,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
GameState.getMarkOrder().getMarkOrder().get(1).getMidPoint()
|
||||
);
|
||||
|
||||
GeoPoint startingPoint = GeoUtility.getGeoCoordinate(
|
||||
GeoPoint midPoint = GeoUtility.getGeoCoordinate(
|
||||
GameState.getMarkOrder().getMarkOrder().get(0).getMidPoint(),
|
||||
angleToStart, DISTANCE_TO_START
|
||||
);
|
||||
@@ -434,24 +321,24 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
Collections.shuffle(randomisedYachts);
|
||||
while (randomisedYachts.size() > 0) {
|
||||
|
||||
int numYachtsInLine = spacesAlongLine > randomisedYachts.size() ? randomisedYachts.size() : spacesAlongLine;
|
||||
double yachtSpace = numYachtsInLine * YACHT_SEPARATION / 2;
|
||||
int numYachts = spacesAlongLine > randomisedYachts.size() ? randomisedYachts.size() : spacesAlongLine;
|
||||
double yachtSpace = (numYachts - 1) * YACHT_SEPARATION / 2;
|
||||
|
||||
GeoPoint firstYachtPoint = GeoUtility.getGeoCoordinate(
|
||||
startingPoint, startMarkToMarkAngle + 180, yachtSpace
|
||||
midPoint, startMarkToMarkAngle + 180, yachtSpace
|
||||
);
|
||||
|
||||
for (int i=0; i<numYachtsInLine; i++){
|
||||
for (int i = 0; i < numYachts; i++) {
|
||||
randomisedYachts.get(0).setHeading(angleFromStart);
|
||||
randomisedYachts.get(0).setLocation(firstYachtPoint);
|
||||
firstYachtPoint = GeoUtility.getGeoCoordinate(
|
||||
firstYachtPoint, startMarkToMarkAngle, yachtSpace
|
||||
firstYachtPoint, startMarkToMarkAngle, YACHT_SEPARATION
|
||||
);
|
||||
randomisedYachts.remove(0);
|
||||
}
|
||||
|
||||
startingPoint = GeoUtility.getGeoCoordinate(
|
||||
startingPoint, angleToStart, DISTANCE_TO_START
|
||||
midPoint = GeoUtility.getGeoCoordinate(
|
||||
midPoint, angleToStart, YACHT_SEPARATION * 1.5
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -459,4 +346,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
public boolean hasStarted() {
|
||||
return hasStarted;
|
||||
}
|
||||
|
||||
public int getPortNumber() {
|
||||
return selectedPort;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package seng302.gameServer;
|
||||
|
||||
import seng302.gameServer.messages.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import seng302.gameServer.messages.BoatLocationMessage;
|
||||
@@ -25,9 +24,6 @@ import seng302.model.token.Token;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.utilities.XMLGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A Class for interfacing between the data we have in the GameState to the messages we need to send
|
||||
* through the MainServerThread.
|
||||
@@ -77,9 +73,6 @@ public class MessageFactory {
|
||||
}
|
||||
|
||||
public static void updateBoats(List<ServerYacht> yachts) {
|
||||
// for (ServerYacht serverYacht : yachts) {
|
||||
// System.out.println(serverYacht);
|
||||
// }
|
||||
xmlGenerator.getRace().setBoats(yachts);
|
||||
String xmlStr = xmlGenerator.getBoatsAsXml();
|
||||
MessageFactory.boats = new XMLMessage(xmlStr, XMLMessageSubType.BOAT, xmlStr.length());
|
||||
|
||||
@@ -146,6 +146,8 @@ public class ServerAdvertiser {
|
||||
public void unregister(){
|
||||
if (serviceInfo != null)
|
||||
jmdnsInstance.unregisterService(serviceInfo);
|
||||
|
||||
repositoryClient.unregister();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,15 +13,11 @@ import javafx.beans.property.ReadOnlyIntegerProperty;
|
||||
import javafx.beans.property.ReadOnlyIntegerWrapper;
|
||||
import javafx.beans.property.ReadOnlyLongProperty;
|
||||
import javafx.beans.property.ReadOnlyLongWrapper;
|
||||
import javafx.beans.value.ObservableObjectValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.paint.Color;
|
||||
import jdk.nashorn.internal.objects.annotations.Function;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||
|
||||
/**
|
||||
@@ -286,6 +282,7 @@ public class ClientYacht extends Observable {
|
||||
|
||||
public void setHeading(Double heading) {
|
||||
this.heading = heading;
|
||||
System.out.println(heading);
|
||||
setHeadingProperty();
|
||||
}
|
||||
|
||||
|
||||
@@ -134,4 +134,8 @@ public class RaceState {
|
||||
public Boolean getRaceFinished() {
|
||||
return raceFinished;
|
||||
}
|
||||
|
||||
public ReadOnlyDoubleWrapper getWindDirection() {
|
||||
return windDirection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,6 @@ public class CompoundMark {
|
||||
getSubMark(1).setRoundingSide(RoundingSide.STARBOARD);
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package seng302.visualiser;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.util.Pair;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import seng302.gameServer.messages.*;
|
||||
import seng302.model.stream.packets.PacketType;
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
import seng302.utilities.XMLParser;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -43,7 +34,7 @@ import seng302.model.stream.xml.generator.RaceXMLTemplate;
|
||||
import seng302.model.stream.xml.generator.RegattaXMLTemplate;
|
||||
import seng302.utilities.XMLGenerator;
|
||||
import seng302.utilities.XMLParser;
|
||||
import seng302.visualiser.controllers.ViewManager;
|
||||
|
||||
|
||||
/**
|
||||
* A class describing a single connection to a Server for the purposes of sending and receiving on
|
||||
@@ -180,10 +171,12 @@ public class ClientToServerThread implements Runnable {
|
||||
notifyDisconnectListeners("Connection to server was terminated");
|
||||
closeSocket();
|
||||
|
||||
Platform.runLater(() -> {
|
||||
ViewManager.getInstance().showErrorSnackBar("Server rejected connection.");
|
||||
ViewManager.getInstance().goToStartView();
|
||||
});
|
||||
//thread.interrupt();
|
||||
|
||||
// Platform.runLater(() -> {
|
||||
// ViewManager.getInstance().showErrorSnackBar("Server rejected connection.");
|
||||
// ViewManager.getInstance().goToStartView();
|
||||
// });
|
||||
}
|
||||
|
||||
public void sendCustomizationRequest(CustomizeRequestType reqType, byte[] payload) {
|
||||
|
||||
@@ -5,9 +5,7 @@ import java.text.SimpleDateFormat;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.Timer;
|
||||
@@ -17,7 +15,6 @@ import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.util.Pair;
|
||||
import seng302.gameServer.GameStages;
|
||||
@@ -55,7 +52,6 @@ import seng302.visualiser.controllers.dialogs.PopupDialogController;
|
||||
*/
|
||||
public class GameClient {
|
||||
|
||||
private Pane holderPane;
|
||||
private ClientToServerThread socketThread;
|
||||
private MainServerThread server;
|
||||
|
||||
@@ -77,10 +73,8 @@ public class GameClient {
|
||||
/**
|
||||
* 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;
|
||||
public GameClient() {
|
||||
this.gameKeyBind = GameKeyBind.getInstance();
|
||||
}
|
||||
|
||||
@@ -89,7 +83,7 @@ public class GameClient {
|
||||
* @param ipAddress IP to connect to.
|
||||
* @param portNumber Port to connect to.
|
||||
*/
|
||||
public void runAsClient(String ipAddress, Integer portNumber) {
|
||||
public boolean runAsClient(String ipAddress, Integer portNumber) {
|
||||
try {
|
||||
startClientToServerThread(ipAddress, portNumber);
|
||||
socketThread.addDisconnectionListener((cause) -> {
|
||||
@@ -100,41 +94,40 @@ public class GameClient {
|
||||
|
||||
ViewManager.getInstance().setPlayerList(clientLobbyList);
|
||||
|
||||
while (regattaData == null){
|
||||
int triesLeft = 10;
|
||||
|
||||
while (regattaData == null && triesLeft >= 0){
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException ignored) {
|
||||
;
|
||||
}
|
||||
triesLeft--;
|
||||
}
|
||||
|
||||
if (triesLeft < 1){
|
||||
return false;
|
||||
}
|
||||
|
||||
ViewManager.getInstance().setProperty("serverName", regattaData.getRegattaName());
|
||||
ViewManager.getInstance().setProperty("mapName", regattaData.getCourseName());
|
||||
|
||||
getServerThread().setConnectionErrorListener((eMessage) -> {
|
||||
ViewManager.getInstance().showErrorSnackBar(eMessage);
|
||||
//destroyClientToServerThread();
|
||||
});
|
||||
getServerThread().setConnectionErrorListener((eMessage) -> ViewManager.getInstance().showErrorSnackBar(eMessage));
|
||||
|
||||
this.lobbyController = ViewManager.getInstance().goToLobby(true);
|
||||
|
||||
} catch (IOException ioe) {
|
||||
ViewManager.getInstance().showErrorSnackBar("There are no servers currently available.");
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyClientToServerThread() {
|
||||
socketThread.closeSocket();
|
||||
socketThread = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ServerDescription runAsHost(
|
||||
String ipAddress, Integer portNumber, String serverName, Integer maxPlayers, String race,
|
||||
String serverName, Integer maxPlayers, String race,
|
||||
Integer numLegs, Boolean tokensEnabled
|
||||
) {
|
||||
XMLGenerator.setDefaultRaceName(serverName);
|
||||
@@ -150,7 +143,7 @@ public class GameClient {
|
||||
}
|
||||
|
||||
try {
|
||||
startClientToServerThread(ipAddress, 4942);
|
||||
startClientToServerThread("localhost", server.getPortNumber());
|
||||
} catch (IOException e) {
|
||||
showConnectionError("Cannot connect to server as host");
|
||||
}
|
||||
@@ -184,8 +177,11 @@ public class GameClient {
|
||||
|
||||
this.lobbyController = ViewManager.getInstance().goToLobby(false);
|
||||
|
||||
lobbyController.setPortNumber(""+server.getPortNumber());
|
||||
|
||||
ViewManager.getInstance().setPlayerList(clientLobbyList);
|
||||
return new ServerDescription(serverName, regattaData.getCourseName(), GameState.getNumberOfPlayers(), GameState.getCapacity(), ipAddress, 4942);
|
||||
return new ServerDescription(serverName, regattaData.getCourseName(), GameState.getNumberOfPlayers(), GameState.getCapacity(),
|
||||
"localhost", server.getPortNumber());
|
||||
}
|
||||
|
||||
private void tearDownConnection() {
|
||||
@@ -288,10 +284,12 @@ public class GameClient {
|
||||
case CHATTER_TEXT:
|
||||
Pair<Integer, String> playerIdMessagePair = StreamParser
|
||||
.extractChatterText(packet);
|
||||
raceView.updateChatHistory(
|
||||
allBoatsMap.get(playerIdMessagePair.getKey()).getColour(),
|
||||
playerIdMessagePair.getValue()
|
||||
);
|
||||
if (playerIdMessagePair != null) {
|
||||
raceView.updateChatHistory(
|
||||
allBoatsMap.get(playerIdMessagePair.getKey()).getColour(),
|
||||
playerIdMessagePair.getValue()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,8 +326,6 @@ public class GameClient {
|
||||
positionData.getLon(), positionData.getHeading(),
|
||||
positionData.getGroundSpeed());
|
||||
}
|
||||
} else if (positionData.getType() == DeviceType.MARK_TYPE) {
|
||||
//CompoundMark mark = courseData.getCompoundMarks().get(positionData.getDeviceId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,21 +363,17 @@ public class GameClient {
|
||||
ClientYacht clientYacht = allBoatsMap.get((int) boatData[0]);
|
||||
clientYacht.setEstimateTimeTillNextMark(raceState.getRaceTime() - boatData[1]);
|
||||
clientYacht.setEstimateTimeAtFinish(boatData[2]);
|
||||
// int legNumber = (int) boatData[3];
|
||||
clientYacht.setBoatStatus((int) boatData[4]);
|
||||
// if (legNumber != clientYacht.getLegNumber()) {
|
||||
// clientYacht.setLegNumber(legNumber);
|
||||
// }
|
||||
}
|
||||
|
||||
if (raceFinished) {
|
||||
raceViewController.showFinishDialog(finishedBoats);
|
||||
if (raceFinished && !raceState.getRaceFinished()) {
|
||||
raceState.setRaceFinished();
|
||||
Sounds.playFinishSound();
|
||||
close();
|
||||
ViewManager.getInstance().getGameClient().stopGame();
|
||||
raceViewController.showFinishDialog(finishedBoats);
|
||||
// close();
|
||||
// ViewManager.getInstance().getGameClient().stopGame();
|
||||
//loadFinishScreenView();
|
||||
}
|
||||
raceState.setRaceFinished();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,10 +384,6 @@ public class GameClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void close() {
|
||||
socketThread.setSocketToClose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the key-pressed event from the text field.
|
||||
* @param e The key event triggering this call
|
||||
@@ -522,10 +510,6 @@ public class GameClient {
|
||||
return socketThread;
|
||||
}
|
||||
|
||||
public List<String> getPlayerNames(){
|
||||
return Collections.unmodifiableList(clientLobbyList.sorted());
|
||||
}
|
||||
|
||||
public void stopGame() {
|
||||
GameState.setCurrentStage(GameStages.CANCELLED);
|
||||
if (server != null) server.terminate();
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
package seng302.visualiser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Node;
|
||||
import seng302.model.ClientYacht;
|
||||
import seng302.model.Limit;
|
||||
import seng302.model.ScaledPoint;
|
||||
import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.mark.Corner;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.fxObjects.Marker;
|
||||
|
||||
/**
|
||||
* Abstract class for keeping functionality common between race visualisation.
|
||||
@@ -24,8 +29,36 @@ public abstract class GameView {
|
||||
List<CompoundMark> course = new ArrayList<>();
|
||||
List<CompoundMark> compoundMarks = new ArrayList<>();
|
||||
List<Corner> courseOrder = new ArrayList<>();
|
||||
HashMap<Mark, Marker> markerObjects = new HashMap<>();
|
||||
|
||||
public abstract Node getAssets();
|
||||
public abstract void updateCourse(List<CompoundMark> newCourse, List<Corner> sequence);
|
||||
public abstract void updateBorder(List<Limit> border);
|
||||
|
||||
void updateMarkArrows (ClientYacht yacht, int legNumber) {
|
||||
CompoundMark compoundMark;
|
||||
if (legNumber - 1 >= 0 && legNumber-1 < course.size()) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
compoundMark = course.get(legNumber-1);
|
||||
for (Mark mark : compoundMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextExitArrow();
|
||||
}
|
||||
}
|
||||
CompoundMark nextMark = null;
|
||||
if (legNumber < course.size()) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
nextMark = course.get(legNumber);
|
||||
for (Mark mark : nextMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextEnterArrow();
|
||||
}
|
||||
}
|
||||
if (legNumber - 2 >= 0) {
|
||||
CompoundMark lastMark = course.get(Math.max(0, legNumber - 2));
|
||||
if (lastMark != nextMark) {
|
||||
for (Mark mark : lastMark.getMarks()) {
|
||||
markerObjects.get(mark).hideAllArrows();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import seng302.model.mark.Corner;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.token.Token;
|
||||
import seng302.utilities.GeoUtility;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.cameras.ChaseCamera;
|
||||
import seng302.visualiser.cameras.IsometricCamera;
|
||||
import seng302.visualiser.cameras.RaceCamera;
|
||||
@@ -55,7 +54,7 @@ public class GameView3D extends GameView {
|
||||
|
||||
private final double FOV = 60;
|
||||
private final double DEFAULT_CAMERA_X = 0;
|
||||
private final double DEFAULT_CAMERA_Y = 100;
|
||||
private final double DEFAULT_CAMERA_Y = 160;
|
||||
|
||||
private Group root3D;
|
||||
private SubScene view;
|
||||
@@ -66,11 +65,6 @@ public class GameView3D extends GameView {
|
||||
private PerspectiveCamera isometricCam;
|
||||
private PerspectiveCamera topDownCam;
|
||||
private PerspectiveCamera chaseCam;
|
||||
|
||||
/* Note that if either of these is null then values for it have not been added and the other
|
||||
should be used as the limits of the map. */
|
||||
private Map<Mark, Marker3D> markerObjects;
|
||||
|
||||
private BoatObject playerBoat;
|
||||
private Map<ClientYacht, BoatObject> boatObjects = new HashMap<>();
|
||||
private Group wakesGroup = new Group();
|
||||
@@ -81,6 +75,7 @@ public class GameView3D extends GameView {
|
||||
private Double windDir;
|
||||
private Skybox skybox;
|
||||
|
||||
|
||||
public GameView3D () {
|
||||
isometricCam = new IsometricCamera(DEFAULT_CAMERA_X, DEFAULT_CAMERA_Y);
|
||||
topDownCam = new TopDownCamera();
|
||||
@@ -95,11 +90,11 @@ public class GameView3D extends GameView {
|
||||
}
|
||||
|
||||
gameObjects = new Group();
|
||||
root3D = new Group(isometricCam, gameObjects);
|
||||
root3D = new Group(chaseCam, gameObjects);
|
||||
view = new SubScene(
|
||||
root3D, 5000, 3000, true, SceneAntialiasing.BALANCED
|
||||
);
|
||||
view.setCamera(isometricCam);
|
||||
view.setCamera(chaseCam);
|
||||
|
||||
skybox = new Skybox(new Image(getClass().getResourceAsStream("/images/skybox.jpg")), 100000, isometricCam);
|
||||
skybox.getTransforms().addAll(new Rotate(90, Rotate.X_AXIS));
|
||||
@@ -350,18 +345,19 @@ public class GameView3D extends GameView {
|
||||
for (ObservableValue o : Arrays
|
||||
.asList(playerBoat.layoutXProperty(), playerBoat.layoutXProperty())) {
|
||||
o.addListener((obs, oldVal, newVal) -> {
|
||||
if (playerYacht.getLegNumber() < course.size()) {
|
||||
List<Mark> marks = course.get(playerYacht.getLegNumber()).getMarks();
|
||||
Point2D midPoint = new Point2D(0, 0);
|
||||
if (marks.size() == 1) {
|
||||
midPoint = scaledPoint.findScaledXY(marks.get(0));
|
||||
} else if (marks.size() == 2) {
|
||||
midPoint = (scaledPoint.findScaledXY(marks.get(0)))
|
||||
.midpoint(scaledPoint.findScaledXY(marks.get(1)));
|
||||
}
|
||||
|
||||
List<Mark> marks = course.get(playerYacht.getLegNumber()).getMarks();
|
||||
Point2D midPoint = new Point2D(0, 0);
|
||||
if (marks.size() == 1) {
|
||||
midPoint = scaledPoint.findScaledXY(marks.get(0));
|
||||
} else if (marks.size() == 2) {
|
||||
midPoint = (scaledPoint.findScaledXY(marks.get(0)))
|
||||
.midpoint(scaledPoint.findScaledXY(marks.get(1)));
|
||||
}
|
||||
|
||||
if (midPoint != null) {
|
||||
playerBoat.updateMarkIndicator(midPoint);
|
||||
if (midPoint != null) {
|
||||
playerBoat.updateMarkIndicator(midPoint);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
@@ -375,6 +371,10 @@ public class GameView3D extends GameView {
|
||||
return view;
|
||||
}
|
||||
|
||||
public SubScene getView() {
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the boatObjects color with that of the clientYachts object. Used in notification from
|
||||
* a listener on this attribute in clientYacht to re paint the boat mesh
|
||||
@@ -501,6 +501,7 @@ public class GameView3D extends GameView {
|
||||
}
|
||||
|
||||
public void setBoatAsPlayer (ClientYacht playerYacht) {
|
||||
playerBoat.updateMarkIndicator(scaledPoint.findScaledXY(course.get(0).getMidPoint()));
|
||||
playerYacht.toggleSail();
|
||||
playerBoatAnimationTimer = new AnimationTimer() {
|
||||
|
||||
@@ -534,31 +535,4 @@ public class GameView3D extends GameView {
|
||||
public void setWindDir(double windDir) {
|
||||
this.windDir = windDir;
|
||||
}
|
||||
|
||||
private void updateMarkArrows (ClientYacht yacht, int legNumber) {
|
||||
CompoundMark compoundMark;
|
||||
if (legNumber - 1 >= 0) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
compoundMark = course.get(legNumber-1);
|
||||
for (Mark mark : compoundMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextExitArrow();
|
||||
}
|
||||
}
|
||||
CompoundMark nextMark = null;
|
||||
if (legNumber < course.size() - 1) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
nextMark = course.get(legNumber);
|
||||
for (Mark mark : nextMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextEnterArrow();
|
||||
}
|
||||
}
|
||||
if (legNumber - 2 >= 0) {
|
||||
CompoundMark lastMark = course.get(Math.max(0, legNumber - 2));
|
||||
if (lastMark != nextMark) {
|
||||
for (Mark mark : lastMark.getMarks()) {
|
||||
markerObjects.get(mark).hideAllArrows();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package seng302.visualiser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
@@ -35,7 +34,8 @@ public class MapMaker {
|
||||
private int index = 0;
|
||||
private XMLGenerator xmlGenerator = new XMLGenerator();
|
||||
|
||||
private List<String> maps = new ArrayList<>(Arrays.asList("default.xml", "horseshoe.xml", "loop.xml"));
|
||||
private List<String> maps = new ArrayList<>(
|
||||
Arrays.asList("default.xml", "horseshoe.xml", "loop.xml", "madagascar.xml", "waiheke.xml"));
|
||||
|
||||
public static MapMaker getInstance() {
|
||||
if (instance == null) {
|
||||
@@ -108,10 +108,6 @@ public class MapMaker {
|
||||
return mapPreviews.get(index).getAssets();
|
||||
}
|
||||
|
||||
public RaceXMLData getCurrentRace() {
|
||||
return races.get(index);
|
||||
}
|
||||
|
||||
public RegattaXMLData getCurrentRegatta() {
|
||||
return regattas.get(index);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package seng302.visualiser;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.Node;
|
||||
@@ -19,6 +18,7 @@ import seng302.model.mark.Corner;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.utilities.GeoUtility;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory;
|
||||
import seng302.visualiser.fxObjects.Marker;
|
||||
import seng302.visualiser.fxObjects.assets_2D.CourseBoundary;
|
||||
import seng302.visualiser.fxObjects.assets_2D.Gate;
|
||||
import seng302.visualiser.fxObjects.assets_2D.Marker2D;
|
||||
@@ -29,7 +29,6 @@ import seng302.visualiser.fxObjects.assets_2D.Marker2D;
|
||||
public class MapPreview extends GameView {
|
||||
|
||||
private Polygon raceBorder = new CourseBoundary();
|
||||
protected Map<Mark, Marker2D> markerObjects;
|
||||
|
||||
public MapPreview(List<CompoundMark> marks, List<Corner> course, List<Limit> border) {
|
||||
this.compoundMarks = marks;
|
||||
@@ -207,7 +206,7 @@ public class MapPreview extends GameView {
|
||||
}
|
||||
GeoPoint secondToLastMarkAv = new GeoPoint(averageLat / numMarks, averageLng / numMarks);
|
||||
for (Mark mark : course.get(course.size()-1).getMarks()) {
|
||||
markerObjects.get(mark).addArrows(
|
||||
markerObjects.get(mark).addFinishArrow(
|
||||
mark.getRoundingSide() == RoundingSide.STARBOARD ? MarkArrowFactory.RoundingSide.STARBOARD : MarkArrowFactory.RoundingSide.PORT,
|
||||
GeoUtility.getBearing(secondToLastMarkAv, mark),
|
||||
GeoUtility.getBearing(mark, mark)
|
||||
@@ -240,7 +239,7 @@ public class MapPreview extends GameView {
|
||||
* @param colour The desired colour of the gate.
|
||||
* @return the new gate.
|
||||
*/
|
||||
private Gate makeAndBindGate(Marker2D m1, Marker2D m2, Paint colour) {
|
||||
private Gate makeAndBindGate(Marker m1, Marker m2, Paint colour) {
|
||||
Gate gate = new Gate(colour);
|
||||
gate.startXProperty().bind(
|
||||
m1.layoutXProperty()
|
||||
|
||||
@@ -11,8 +11,6 @@ import seng302.model.ClientYacht;
|
||||
import seng302.model.Limit;
|
||||
import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.mark.Corner;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.utilities.Sounds;
|
||||
|
||||
/**
|
||||
* Class converts a map preview to a minimap by adding boats.
|
||||
@@ -20,15 +18,9 @@ import seng302.utilities.Sounds;
|
||||
public class MiniMap extends MapPreview {
|
||||
|
||||
private HashMap<ClientYacht, Polygon> boatIcons = new HashMap<>();
|
||||
private Polygon playerBoat;
|
||||
private double playerRotation;
|
||||
private List<ClientYacht> boats;
|
||||
private ClientYacht player;
|
||||
|
||||
public MiniMap (List<CompoundMark> marks, List<Corner> course, List<Limit> border, List<ClientYacht> boats, ClientYacht player) {
|
||||
super(marks, course, border);
|
||||
this.boats = boats;
|
||||
this.player = player;
|
||||
setBoats(boats);
|
||||
player.addMarkRoundingListener(this::updateMarkArrows);
|
||||
}
|
||||
@@ -56,31 +48,4 @@ public class MiniMap extends MapPreview {
|
||||
gameObjects.getChildren().addAll(boatIcons.values());
|
||||
});
|
||||
}
|
||||
|
||||
private void updateMarkArrows (ClientYacht yacht, int legNumber) {
|
||||
CompoundMark compoundMark;
|
||||
if (legNumber - 1 >= 0) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
compoundMark = course.get(legNumber-1);
|
||||
for (Mark mark : compoundMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextExitArrow();
|
||||
}
|
||||
}
|
||||
CompoundMark nextMark = null;
|
||||
if (legNumber < course.size() - 1) {
|
||||
Sounds.playMarkRoundingSound();
|
||||
nextMark = course.get(legNumber);
|
||||
for (Mark mark : nextMark.getMarks()) {
|
||||
markerObjects.get(mark).showNextEnterArrow();
|
||||
}
|
||||
}
|
||||
if (legNumber - 2 >= 0) {
|
||||
CompoundMark lastMark = course.get(Math.max(0, legNumber - 2));
|
||||
if (lastMark != nextMark) {
|
||||
for (Mark mark : lastMark.getMarks()) {
|
||||
markerObjects.get(mark).hideAllArrows();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package seng302.visualiser;
|
||||
|
||||
import seng302.gameServer.ServerAdvertiser;
|
||||
import seng302.gameServer.ServerDescription;
|
||||
import static seng302.gameServer.ServerAdvertiser.getLocalHostIp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.jmdns.JmDNS;
|
||||
import javax.jmdns.ServiceEvent;
|
||||
import javax.jmdns.ServiceListener;
|
||||
import javax.jmdns.impl.JmDNSImpl;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.*;
|
||||
|
||||
import static seng302.gameServer.ServerAdvertiser.getLocalHostIp;
|
||||
import seng302.gameServer.ServerAdvertiser;
|
||||
import seng302.gameServer.ServerDescription;
|
||||
|
||||
/**
|
||||
* Listens for servers on the local network
|
||||
@@ -58,7 +58,7 @@ public class ServerListener{
|
||||
servers.remove(toRemove);
|
||||
}
|
||||
|
||||
delegate.serverRemoved(new ArrayList<ServerDescription>(servers));
|
||||
delegate.serverRemoved(new ArrayList<>(servers));
|
||||
|
||||
// Get all other servers with the same name to respond if they are up
|
||||
jmdns.requestServiceInfo(ServerAdvertiser.SERVICE_TYPE, serverName);
|
||||
@@ -94,13 +94,6 @@ public class ServerListener{
|
||||
|
||||
listener = new GameServeMonitor();
|
||||
jmdns.addServiceListener(ServerAdvertiser.SERVICE_TYPE, listener);
|
||||
|
||||
/*new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
refresh();
|
||||
}
|
||||
}, 50, SERVICE_REFRESH_INTERVAL);*/
|
||||
}
|
||||
|
||||
public static ServerListener getInstance() throws IOException {
|
||||
@@ -134,7 +127,7 @@ public class ServerListener{
|
||||
for (ServerDescription server : servers){
|
||||
if (server.serverShouldBeRemoved()){
|
||||
listener.servers.remove(server);
|
||||
delegate.serverRemoved(new ArrayList<ServerDescription>(listener.servers));
|
||||
delegate.serverRemoved(new ArrayList<>(listener.servers));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ public class IsometricCamera extends PerspectiveCamera implements RaceCamera {
|
||||
private final Double MAX_Y = 170.0;
|
||||
|
||||
private final Double PAN_LIMIT = 160.0;
|
||||
private final Double NEAR_ZOOM_LIMIT = -50.0;
|
||||
private final Double FAR_ZOOM_LIMIT = -160.0;
|
||||
private final Double NEAR_ZOOM_LIMIT = -30.0;
|
||||
private final Double FAR_ZOOM_LIMIT = -180.0;
|
||||
|
||||
private Double horizontalPan;
|
||||
private Double verticalPan;
|
||||
@@ -29,7 +29,7 @@ public class IsometricCamera extends PerspectiveCamera implements RaceCamera {
|
||||
super(true);
|
||||
transforms = this.getTransforms();
|
||||
|
||||
zoomFactor = (FAR_ZOOM_LIMIT + NEAR_ZOOM_LIMIT) / 2.0;
|
||||
zoomFactor = FAR_ZOOM_LIMIT;
|
||||
horizontalPan = cameraStartX;
|
||||
verticalPan = cameraStartY;
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@ import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||
|
||||
public class TopDownCamera extends PerspectiveCamera implements RaceCamera {
|
||||
|
||||
private final Double PAN_LIMIT = 30.0;
|
||||
private final Double NEAR_ZOOM_LIMIT = -30.0;
|
||||
private final Double FAR_ZOOM_LIMIT = -130.0;
|
||||
private final Double PAN_LIMIT = 40d;
|
||||
private final Double NEAR_ZOOM_LIMIT = -20.0;
|
||||
private final Double FAR_ZOOM_LIMIT = -200d;
|
||||
private final Double ZOOM_STEP = 2.5;
|
||||
|
||||
private ObservableList<Transform> transforms;
|
||||
@@ -27,7 +27,7 @@ public class TopDownCamera extends PerspectiveCamera implements RaceCamera {
|
||||
super(true);
|
||||
transforms = this.getTransforms();
|
||||
|
||||
zoomFactor = (FAR_ZOOM_LIMIT + NEAR_ZOOM_LIMIT) / 2.0;
|
||||
zoomFactor = FAR_ZOOM_LIMIT;
|
||||
horizontalPan = 0.0;
|
||||
verticalPan = 0.0;
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
package seng302.visualiser.controllers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import seng302.model.ClientYacht;
|
||||
import seng302.utilities.Sounds;
|
||||
|
||||
public class FinishScreenViewController implements Initializable {
|
||||
|
||||
@FXML
|
||||
private GridPane finishScreenGridPane;
|
||||
@FXML
|
||||
private TableView<ClientYacht> finishOrderTable;
|
||||
@FXML
|
||||
private TableColumn<ClientYacht, String> posCol;
|
||||
@FXML
|
||||
private TableColumn<ClientYacht, String> boatNameCol;
|
||||
@FXML
|
||||
private TableColumn<ClientYacht, String> shortNameCol;
|
||||
@FXML
|
||||
private TableColumn<ClientYacht, String> countryCol;
|
||||
|
||||
ObservableList<ClientYacht> data = FXCollections.observableArrayList();
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
finishScreenGridPane.getStylesheets()
|
||||
.add(getClass().getResource("/css/Master.css").toString());
|
||||
finishOrderTable.getStylesheets().add(getClass().getResource("/css/Master.css").toString());
|
||||
|
||||
// set up data for table
|
||||
finishOrderTable.setItems(data);
|
||||
|
||||
// setting table col data
|
||||
posCol.setCellValueFactory(
|
||||
new PropertyValueFactory<>("position")
|
||||
);
|
||||
boatNameCol.setCellValueFactory(
|
||||
new PropertyValueFactory<>("boatName")
|
||||
);
|
||||
shortNameCol.setCellValueFactory(
|
||||
new PropertyValueFactory<>("shortName")
|
||||
);
|
||||
countryCol.setCellValueFactory(
|
||||
new PropertyValueFactory<>("country")
|
||||
);
|
||||
finishOrderTable.refresh();
|
||||
}
|
||||
|
||||
public void setFinishers(Collection<ClientYacht> participants) {
|
||||
List<ClientYacht> sorted = new ArrayList<>(participants);
|
||||
sorted.sort(Comparator.comparingInt(ClientYacht::getPlacing));
|
||||
finishOrderTable.getItems().setAll(sorted);
|
||||
}
|
||||
|
||||
private void setContentPane(String jfxUrl) {
|
||||
try {
|
||||
// get the main controller anchor pane (FinishView -> MainView)
|
||||
AnchorPane contentPane = (AnchorPane) finishScreenGridPane.getParent();
|
||||
contentPane.getChildren().removeAll();
|
||||
contentPane.getChildren().clear();
|
||||
contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
||||
contentPane.getChildren()
|
||||
.addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl)));
|
||||
} catch (javafx.fxml.LoadException e) {
|
||||
System.out.println("[Controller] FXML load exception");
|
||||
} catch (IOException e) {
|
||||
System.out.println("[Controller] IO exception");
|
||||
}
|
||||
}
|
||||
|
||||
public void switchToStartScreenView() {
|
||||
Sounds.playButtonClick();
|
||||
setContentPane("/views/StartScreenView.fxml");
|
||||
}
|
||||
|
||||
public void playButtonHoverSound(MouseEvent mouseEvent) {
|
||||
Sounds.playHoverSound();
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,12 @@ import com.jfoenix.controls.JFXDialog;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
@@ -20,7 +18,6 @@ import javafx.geometry.Point3D;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
@@ -43,7 +40,6 @@ import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.MapPreview;
|
||||
import seng302.visualiser.controllers.cells.PlayerCell;
|
||||
import seng302.visualiser.controllers.dialogs.BoatCustomizeController;
|
||||
import seng302.visualiser.controllers.dialogs.PopupDialogController;
|
||||
import seng302.visualiser.controllers.dialogs.TokenInfoDialogController;
|
||||
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
|
||||
import seng302.visualiser.fxObjects.assets_3D.ModelType;
|
||||
@@ -71,6 +67,8 @@ public class LobbyController implements Initializable {
|
||||
@FXML
|
||||
private Label roomLabel;
|
||||
@FXML
|
||||
private Label portNumber;
|
||||
@FXML
|
||||
private Pane speedTokenPane, handlingTokenPane, windWalkerTokenPane, bumperTokenPane, randomTokenPane;
|
||||
//---------FXML END---------//
|
||||
|
||||
@@ -85,6 +83,8 @@ public class LobbyController implements Initializable {
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
roomLabel.setText("");
|
||||
portNumber.setText("");
|
||||
|
||||
this.playerBoats = ViewManager.getInstance().getGameClient().getAllBoatsMap();
|
||||
|
||||
if (this.playersColor == null) {
|
||||
@@ -353,8 +353,8 @@ public class LobbyController implements Initializable {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param raceState
|
||||
* Updates the state of the race and changes the value
|
||||
* @param raceState the new race state
|
||||
*/
|
||||
public void updateRaceState(RaceState raceState){
|
||||
this.raceState = raceState;
|
||||
@@ -376,4 +376,8 @@ public class LobbyController implements Initializable {
|
||||
public void setRoomCode(String roomCode) {
|
||||
roomLabel.setText("Room: " + roomCode);
|
||||
}
|
||||
|
||||
public void setPortNumber(String p){
|
||||
portNumber.setText("Port: " + p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,28 +7,33 @@ import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import javafx.animation.RotateTransition;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.SubScene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.util.Duration;
|
||||
import javafx.scene.text.Text;
|
||||
import seng302.model.ClientYacht;
|
||||
import seng302.model.RaceState;
|
||||
import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.GameView3D;
|
||||
import seng302.visualiser.MiniMap;
|
||||
import seng302.visualiser.controllers.cells.WindCell;
|
||||
import seng302.visualiser.controllers.dialogs.FinishDialogController;
|
||||
import seng302.visualiser.fxObjects.ChatHistory;
|
||||
|
||||
@@ -50,6 +55,8 @@ public class RaceViewController extends Thread {
|
||||
@FXML
|
||||
private Pane chatHistoryHolder;
|
||||
@FXML
|
||||
private JFXButton chatToggleButton;
|
||||
@FXML
|
||||
private TextField chatInput;
|
||||
@FXML
|
||||
private Label timerLabel;
|
||||
@@ -59,6 +66,20 @@ public class RaceViewController extends Thread {
|
||||
private Pane miniMapPane;
|
||||
@FXML
|
||||
private ImageView windImageView;
|
||||
@FXML
|
||||
private AnchorPane rvAnchorPane;
|
||||
@FXML
|
||||
private AnchorPane windArrowHolder;
|
||||
@FXML
|
||||
private Slider annotationSlider;
|
||||
@FXML
|
||||
private Button selectAnnotationBtn;
|
||||
@FXML
|
||||
private ComboBox<ClientYacht> yachtSelectionComboBox;
|
||||
@FXML
|
||||
private Text fpsDisplay;
|
||||
// @FXML
|
||||
// private ImageView windImageView;
|
||||
@FXML
|
||||
private Label windDirectionLabel;
|
||||
@FXML
|
||||
@@ -68,12 +89,20 @@ public class RaceViewController extends Thread {
|
||||
@FXML
|
||||
private ImageView velocityIcon, handlingIcon, windWalkerIcon, bumperIcon, badRandomIcon;
|
||||
@FXML
|
||||
private VBox windArrowVBox;
|
||||
@FXML
|
||||
private JFXButton miniMapButton;
|
||||
|
||||
|
||||
private WindCell windCell;
|
||||
//Race Data
|
||||
private Map<Integer, ClientYacht> participants;
|
||||
private Map<Integer, CompoundMark> markers;
|
||||
private RaceXMLData courseData;
|
||||
private GameView3D gameView;
|
||||
private RaceState raceState;
|
||||
private ChatHistory chatHistory;
|
||||
private Timer timer = new Timer();
|
||||
private Timer timer = new Timer();
|
||||
private ClientYacht player;
|
||||
private JFXDialog finishScreenDialog;
|
||||
private FinishDialogController finishDialogController;
|
||||
@@ -85,6 +114,8 @@ public class RaceViewController extends Thread {
|
||||
public void initialize() {
|
||||
miniMapPane.setVisible(false);
|
||||
miniMapButton.setVisible(false);
|
||||
chatHistoryHolder.setVisible(false);
|
||||
chatToggleButton.setVisible(false);
|
||||
contentStackPane.setVisible(false);
|
||||
Image loadingImage = new Image("PP.png");
|
||||
loadingScreen.setImage(loadingImage);
|
||||
@@ -120,6 +151,9 @@ public class RaceViewController extends Thread {
|
||||
chatHistoryHolder.heightProperty()
|
||||
);
|
||||
|
||||
contentStackPane.getChildren().remove(chatToggleButton);
|
||||
contentStackPane.getChildren().add(chatToggleButton);
|
||||
|
||||
contentStackPane.setOnMouseClicked(event -> {
|
||||
contentStackPane.requestFocus();
|
||||
});
|
||||
@@ -134,6 +168,30 @@ public class RaceViewController extends Thread {
|
||||
});
|
||||
|
||||
lastWindDirection = 0d;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise wind arrow cell.
|
||||
*/
|
||||
private void initialiseWindArrow() {
|
||||
FXMLLoader loader = new FXMLLoader(
|
||||
getClass().getResource("/views/cells/WindCell.fxml"));
|
||||
windCell = new WindCell();
|
||||
loader.setController(windCell);
|
||||
|
||||
try {
|
||||
loader.load();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
windCell.init(player, raceState.getWindDirection());
|
||||
windCell.setCamera(gameView.getView().getCamera());
|
||||
gameView.getView().cameraProperty()
|
||||
.addListener((obs, oldVal, newVal) -> windCell.setCamera(newVal));
|
||||
|
||||
windArrowVBox.getChildren().add(windCell.getAssets());
|
||||
}
|
||||
|
||||
public void showFinishDialog(ArrayList<ClientYacht> finishedBoats) {
|
||||
@@ -146,12 +204,10 @@ public class RaceViewController extends Thread {
|
||||
contentStackPane.setVisible(true);
|
||||
miniMapPane.setVisible(true);
|
||||
miniMapButton.setVisible(true);
|
||||
Platform.runLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
contentStackPane.requestFocus();
|
||||
}
|
||||
});
|
||||
chatHistoryHolder.setVisible(true);
|
||||
chatToggleButton.setVisible(true);
|
||||
|
||||
Platform.runLater(() -> contentStackPane.requestFocus());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,10 +251,20 @@ public class RaceViewController extends Thread {
|
||||
miniMapButton.setOnMouseClicked((event) -> {
|
||||
if (miniMapPane.visibleProperty().get()) {
|
||||
miniMapPane.setVisible(false);
|
||||
miniMapButton.setText("✓");
|
||||
miniMapButton.setText("+");
|
||||
} else {
|
||||
miniMapPane.setVisible(true);
|
||||
miniMapButton.setText("✕");
|
||||
miniMapButton.setText("—");
|
||||
}
|
||||
});
|
||||
|
||||
chatToggleButton.setOnMouseClicked((event) -> {
|
||||
if (chatHistoryHolder.visibleProperty().get()) {
|
||||
chatHistoryHolder.setVisible(false);
|
||||
chatToggleButton.setText("+");
|
||||
} else {
|
||||
chatHistoryHolder.setVisible(true);
|
||||
chatToggleButton.setText("—");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -233,6 +299,12 @@ public class RaceViewController extends Thread {
|
||||
});
|
||||
gameView.setWindDir(raceState.windDirectionProperty().doubleValue());
|
||||
Platform.runLater(this::initializeUpdateTimer);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
//windCell.setCamera(gameView.getView().getCamera());
|
||||
|
||||
initialiseWindArrow();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,11 +360,10 @@ public class RaceViewController extends Thread {
|
||||
}
|
||||
}
|
||||
|
||||
public void removeIcon(ClientYacht yacht) {
|
||||
private void removeIcon(ClientYacht yacht) {
|
||||
if (yacht == player) {
|
||||
blinkingTimer.cancel();
|
||||
iconToDisplay.setVisible(false);
|
||||
iconToDisplay = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,12 +390,12 @@ public class RaceViewController extends Thread {
|
||||
*/
|
||||
private void updateWindDirection(double direction) {
|
||||
windDirectionLabel.setText(String.format("%.1f°", direction));
|
||||
RotateTransition rt = new RotateTransition(Duration.millis(300), windImageView);
|
||||
rt.setByAngle(direction - lastWindDirection);
|
||||
rt.setCycleCount(3);
|
||||
rt.setAutoReverse(true);
|
||||
rt.play();
|
||||
lastWindDirection = direction;
|
||||
// RotateTransition rt = new RotateTransition(Duration.millis(300), windImageView);
|
||||
// rt.setByAngle(direction - lastWindDirection);
|
||||
// rt.setCycleCount(3);
|
||||
// rt.setAutoReverse(true);
|
||||
// rt.play();
|
||||
// lastWindDirection = direction;
|
||||
// windImageView.setRotate(direction);
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +140,9 @@ public class ServerListController implements Initializable, ServerListenerDelega
|
||||
return;
|
||||
}
|
||||
|
||||
ViewManager.getInstance().getGameClient().runAsClient(listing.getAddress(), listing.getPortNumber());
|
||||
if (!ViewManager.getInstance().getGameClient().runAsClient(listing.getAddress(), listing.getPortNumber())){
|
||||
ViewManager.getInstance().showErrorSnackBar("Could not connect to server");
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,6 +9,7 @@ import javafx.scene.layout.StackPane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* The pre loading screen before launch the start view
|
||||
* Created by Kusal on 26-Sep-17.
|
||||
*/
|
||||
public class SplashScreenController implements Initializable{
|
||||
@@ -26,17 +27,14 @@ public class SplashScreenController implements Initializable{
|
||||
public void run(){
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
Platform.runLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Stage stage = new Stage();
|
||||
ViewManager.getInstance().initialStartView(stage);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
rootPane.getScene().getWindow().hide();
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
Stage stage = new Stage();
|
||||
ViewManager.getInstance().initialStartView(stage);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
rootPane.getScene().getWindow().hide();
|
||||
});
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -6,10 +6,16 @@ import com.jfoenix.controls.JFXDialog;
|
||||
import com.jfoenix.controls.JFXDialog.DialogTransition;
|
||||
import com.jfoenix.controls.JFXSnackbar;
|
||||
import com.jfoenix.svg.SVGGlyph;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.*;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.SceneAntialiasing;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
@@ -24,9 +30,6 @@ import seng302.visualiser.GameClient;
|
||||
import seng302.visualiser.controllers.dialogs.KeyBindingDialogController;
|
||||
import seng302.visualiser.controllers.dialogs.PopupDialogController;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ViewManager {
|
||||
|
||||
private static ViewManager instance;
|
||||
@@ -79,7 +82,7 @@ public class ViewManager {
|
||||
decorator.applyCss();
|
||||
decorator.getStylesheets()
|
||||
.add(getClass().getResource("/css/Master.css").toExternalForm());
|
||||
gameClient = new GameClient(decorator);
|
||||
gameClient = new GameClient();
|
||||
setDecorator(decorator);
|
||||
|
||||
stage.getIcons().add(new Image(getClass().getResourceAsStream("/PP.png")));
|
||||
@@ -376,8 +379,8 @@ public class ViewManager {
|
||||
scene.setOnKeyPressed(gameClient::keyPressed);
|
||||
scene.setOnKeyReleased(gameClient::keyReleased);
|
||||
|
||||
stage.setMinHeight(500);
|
||||
stage.setMinWidth(800);
|
||||
stage.setMinHeight(800);
|
||||
stage.setMinWidth(1200);
|
||||
stage.setTitle("Party Parrots At Sea");
|
||||
stage.getIcons().add(new Image(getClass().getResourceAsStream("/PP.png")));
|
||||
stage.setOnCloseRequest(e -> closeAll());
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package seng302.visualiser.controllers.cells;
|
||||
|
||||
import java.util.Arrays;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.ReadOnlyDoubleWrapper;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Point3D;
|
||||
import javafx.scene.Camera;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.PerspectiveCamera;
|
||||
import javafx.scene.SceneAntialiasing;
|
||||
import javafx.scene.SubScene;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import javafx.scene.transform.Transform;
|
||||
import javafx.scene.transform.Translate;
|
||||
import seng302.model.ClientYacht;
|
||||
import seng302.visualiser.cameras.ChaseCamera;
|
||||
import seng302.visualiser.fxObjects.assets_3D.Model;
|
||||
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
|
||||
|
||||
public class WindCell {
|
||||
|
||||
//--------FXML BEGIN--------//
|
||||
@FXML
|
||||
private Pane windPane;
|
||||
//---------FXML END---------//
|
||||
|
||||
private final double FOV = 60;
|
||||
private final double DEFAULT_CAMERA_X = 0;
|
||||
private final double DEFAULT_CAMERA_Y = 50;
|
||||
|
||||
private Group root3D;
|
||||
private SubScene view;
|
||||
private Group gameObjects;
|
||||
|
||||
private ChaseCamera chaseCam;
|
||||
|
||||
private ClientYacht playerYacht;
|
||||
|
||||
// Cameras
|
||||
private PerspectiveCamera camera = null;
|
||||
|
||||
private Model windArrowModel;
|
||||
private Boolean isChaseCam;
|
||||
|
||||
/**
|
||||
* Initialise WindCell fxml and load 3D wind arrow into a group.
|
||||
*/
|
||||
public void init(ClientYacht playerYacht, ReadOnlyDoubleWrapper windDirection) {
|
||||
|
||||
this.playerYacht = playerYacht;
|
||||
camera = new PerspectiveCamera();
|
||||
camera.setFarClip(1000);
|
||||
camera.setNearClip(0.1);
|
||||
camera.setFieldOfView(60);
|
||||
initialiseWindView();
|
||||
|
||||
for (DoubleProperty o : Arrays.asList(playerYacht.getHeadingProperty(), windDirection)) {
|
||||
o.addListener((obs, oldValue, newValue) -> {
|
||||
Platform.runLater(() -> {
|
||||
if (isChaseCam) {
|
||||
camera.getTransforms().clear();
|
||||
for (Transform t : chaseCam.getTransforms()) {
|
||||
if (t instanceof Rotate) {
|
||||
camera.getTransforms().add(t);
|
||||
}
|
||||
}
|
||||
this.camera.getTransforms().addAll(
|
||||
new Translate(-55, -60, 0)
|
||||
);
|
||||
}
|
||||
|
||||
windArrowModel.getAssets().getTransforms().clear();
|
||||
windArrowModel.getAssets().getTransforms().addAll(
|
||||
new Rotate(windDirection.getValue(),
|
||||
new Point3D(0, 0, 1))
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void initialiseWindView() {
|
||||
gameObjects = new Group();
|
||||
windPane.getChildren().add(gameObjects);
|
||||
|
||||
root3D = new Group(camera, gameObjects);
|
||||
view = new SubScene(
|
||||
root3D, 110, 120, true, SceneAntialiasing.BALANCED
|
||||
);
|
||||
view.setCamera(camera);
|
||||
|
||||
windArrowModel = ModelFactory.makeWindArrow();
|
||||
|
||||
gameObjects.getChildren().addAll(
|
||||
windArrowModel.getAssets()
|
||||
);
|
||||
}
|
||||
|
||||
public Node getAssets() {
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
public void updateCameraTransforms(Camera camera) {
|
||||
this.camera.getTransforms().clear();
|
||||
|
||||
for (Transform transform : camera.getTransforms()) {
|
||||
if (!(transform instanceof Translate)) {
|
||||
this.camera.getTransforms().add(transform);
|
||||
}
|
||||
}
|
||||
this.camera.getTransforms().addAll(
|
||||
new Translate(-55, -60, 0)
|
||||
);
|
||||
windArrowModel.getAssets().getTransforms().clear();
|
||||
}
|
||||
|
||||
public void setCamera(Camera camera) {
|
||||
isChaseCam = camera instanceof ChaseCamera;
|
||||
if (isChaseCam) {
|
||||
this.chaseCam = (ChaseCamera) camera;
|
||||
} else {
|
||||
this.chaseCam = null;
|
||||
}
|
||||
updateCameraTransforms(camera);
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@ public class ServerCreationController implements Initializable {
|
||||
*/
|
||||
private void createServer() {
|
||||
ServerDescription serverDescription = ViewManager.getInstance().getGameClient()
|
||||
.runAsHost("localhost", 4941, serverName.getText(), (int) maxPlayersSlider
|
||||
.runAsHost(serverName.getText(), (int) maxPlayersSlider
|
||||
.getValue(), mapMaker.getCurrentRacePath(), (int) legsSlider.getValue(), pickupsCheckBox.isSelected());
|
||||
|
||||
if (serverDescription == null){
|
||||
|
||||
@@ -86,16 +86,6 @@ public class MarkArrowFactory {
|
||||
*/
|
||||
public static Group constructEntryArrow (RoundingSide roundingSide, double angleOfEntry,
|
||||
double angleOfExit, Paint colour) {
|
||||
// Check to see if the the angle around mark would take you inside of it. (less than 180)
|
||||
// If so make interior angle.
|
||||
if (roundingSide == RoundingSide.PORT && angleOfEntry < angleOfExit &&
|
||||
Math.abs(angleOfExit - angleOfEntry) < 180) {
|
||||
return makeInteriorAngle(roundingSide, angleOfExit, angleOfEntry, colour);
|
||||
|
||||
} else if (roundingSide == RoundingSide.STARBOARD && angleOfEntry > angleOfExit &&
|
||||
-Math.abs(angleOfEntry - angleOfExit) > -180) {
|
||||
return makeInteriorAngle(roundingSide, angleOfExit, angleOfEntry, colour);
|
||||
}
|
||||
//Create regular exit arrow.
|
||||
Group arrow = new Group();
|
||||
Group exitSection = constructExitArrow(roundingSide, angleOfExit, colour);
|
||||
@@ -132,7 +122,9 @@ public class MarkArrowFactory {
|
||||
* @param colour colour of arrow
|
||||
* @return the arrow.
|
||||
*/
|
||||
private static Group makeInteriorAngle (RoundingSide roundingSide, double angleOfExit, double angleOfEntry, Paint colour) {
|
||||
public static Group constructInteriorArrow(RoundingSide roundingSide, double angleOfExit,
|
||||
double angleOfEntry, Paint colour) {
|
||||
|
||||
Group arrow = new Group();
|
||||
Polygon lineSegment;
|
||||
//Reverse angle of exit/entry to find position between them
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package seng302.visualiser.fxObjects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.scene.Group;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory.RoundingSide;
|
||||
|
||||
/**
|
||||
* Created by cir27 on 28/09/17.
|
||||
*/
|
||||
public abstract class Marker extends Group{
|
||||
|
||||
protected List<Group> enterArrows = new ArrayList<>();
|
||||
protected List<Group> exitArrows = new ArrayList<>();
|
||||
protected int enterArrowIndex = 0;
|
||||
protected int exitArrowIndex = 0;
|
||||
|
||||
public abstract void addArrows(RoundingSide roundingSide, double entryAngle, double exitAngle);
|
||||
|
||||
public abstract void addFinishArrow(RoundingSide roundingSide, double entryAngle, double exitAngle);
|
||||
|
||||
/**
|
||||
* Shows the next EnterArrow. Does nothing if there are no more enter arrows. Other arrows become hidden.
|
||||
*/
|
||||
public void showNextEnterArrow() {
|
||||
showArrow(enterArrows, enterArrowIndex);
|
||||
enterArrowIndex++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the next ExitArrow. Does nothing if there are no more enter arrows. Other arrows become hidden.
|
||||
*/
|
||||
public void showNextExitArrow() {
|
||||
showArrow(exitArrows, exitArrowIndex);
|
||||
exitArrowIndex++;
|
||||
}
|
||||
|
||||
protected abstract void showArrow(List<Group> arrowList, int arrowListIndex);
|
||||
|
||||
public abstract void hideAllArrows();
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
package seng302.visualiser.fxObjects.assets_2D;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.CacheHint;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
/**
|
||||
* Grouping of string objects over a semi transparent background.
|
||||
*/
|
||||
public class AnnotationBox extends Group {
|
||||
|
||||
@FunctionalInterface
|
||||
public interface AnnotationFormatter<T> {
|
||||
String transformString (T input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class stores a text object and relationship for updating the text object if needed
|
||||
*
|
||||
* @param <T> The type of observable value passed to the annotation, if there is one.
|
||||
*/
|
||||
public class Annotation<T> {
|
||||
private Text text;
|
||||
private ObservableValue<T> source;
|
||||
private AnnotationFormatter<T> format;
|
||||
|
||||
/**
|
||||
* Constructor for observing annotation
|
||||
* @param textObject the javaFX text object the annotation is displayed in
|
||||
* @param source observable value that the annotation is taken from
|
||||
* @param formatter interface describing how to format the source data if needed
|
||||
*/
|
||||
public Annotation (Text textObject, ObservableValue<T> source, AnnotationFormatter<T> formatter) {
|
||||
this.text = textObject;
|
||||
this.source = source;
|
||||
this.format = formatter;
|
||||
source.addListener((obs, oldVal, newVal) ->
|
||||
Platform.runLater(() -> text.setText(format.transformString(newVal)))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for a static annotation
|
||||
* @param textObject the javaFX text object the annotation is displayed in
|
||||
* @param annotationText the static value of the test object
|
||||
*/
|
||||
public Annotation (Text textObject, String annotationText) {
|
||||
textObject.setText(annotationText);
|
||||
text = textObject;
|
||||
}
|
||||
|
||||
private Text getText () {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
//Text offset constants
|
||||
private static final double X_OFFSET_TEXT = 20d;
|
||||
private static final double Y_OFFSET_TEXT_INIT = -35d;
|
||||
private static final double Y_OFFSET_PER_TEXT = 12d;
|
||||
//Background constants
|
||||
private static final double TEXT_BUFFER = 3;
|
||||
private static final double BACKGROUND_X = X_OFFSET_TEXT - TEXT_BUFFER;
|
||||
private static final double BACKGROUND_Y = Y_OFFSET_TEXT_INIT - TEXT_BUFFER;
|
||||
private static final double BACKGROUND_H_PER_TEXT = 9.5d;
|
||||
private static final double BACKGROUND_ARC_SIZE = 10;
|
||||
|
||||
private int visibleAnnotations = 0;
|
||||
private double backgroundWidth = 145d;
|
||||
|
||||
private Rectangle background = new Rectangle();
|
||||
private Paint theme = Color.BLACK;
|
||||
|
||||
private Map<String, Annotation> annotationsByName = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates an empty annotation box. The box is offset from (0,0) by (17, -38).
|
||||
*/
|
||||
public AnnotationBox() {
|
||||
this.setCache(true);
|
||||
background.setX(BACKGROUND_X);
|
||||
background.setY(BACKGROUND_Y);
|
||||
background.setWidth(backgroundWidth);
|
||||
background.setHeight(Math.abs(BACKGROUND_X) + TEXT_BUFFER + BACKGROUND_H_PER_TEXT * 4);
|
||||
background.setArcHeight(BACKGROUND_ARC_SIZE);
|
||||
background.setArcWidth(BACKGROUND_ARC_SIZE);
|
||||
background.setFill(new Color(1, 1, 1, 0.75));
|
||||
background.setStroke(theme);
|
||||
background.setStrokeWidth(2);
|
||||
background.setCache(true);
|
||||
background.setCacheHint(CacheHint.SCALE);
|
||||
this.getChildren().add(background);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an annotation to the box. Use the name to reference the annotation for removal or\
|
||||
* changing visibility.
|
||||
* @param annotationName the name of the annotation.
|
||||
* @param annotation the annotation.
|
||||
*/
|
||||
public void addAnnotation (String annotationName, Annotation annotation) {
|
||||
annotationsByName.put(annotationName, annotation);
|
||||
Platform.runLater(() -> {
|
||||
this.getChildren().add(annotation.getText());
|
||||
visibleAnnotations++;
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an annotation with a constant text.
|
||||
* @param annotationName The name of the annotation. Will be used to reference it later.
|
||||
* @param annotationText The desired text.
|
||||
*/
|
||||
public void addAnnotation (String annotationName, String annotationText) {
|
||||
Text text = getTextObject();
|
||||
addAnnotation(annotationName, new Annotation(text, annotationText));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an annotation with the given name. The annotation will contain the value of the given
|
||||
* ObservableValue. The formatter should return a String and takes an object of the same type as
|
||||
* the ObservableValue as a parameter. The String is how you want the annotation to look.
|
||||
* @param annotationName The annotation name.
|
||||
* @param observable The observable value the annotation will display.
|
||||
* @param formatter A formatting function for the observable value.
|
||||
* @param <E> The type of ObservableValue.
|
||||
*/
|
||||
public <E> void addAnnotation (String annotationName, ObservableValue<E> observable,
|
||||
AnnotationFormatter<E> formatter) {
|
||||
Text newText = getTextObject();
|
||||
addAnnotation(annotationName, new Annotation<>(newText, observable, formatter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the visibility of the annotation with the given name if it exists.
|
||||
* @param annotationName The name of the annotation
|
||||
* @param visibility the desired visibility
|
||||
*/
|
||||
public void setAnnotationVisibility (String annotationName, boolean visibility) {
|
||||
if (annotationsByName.containsKey(annotationName)) {
|
||||
Text textField = annotationsByName.get(annotationName).text;
|
||||
boolean currentState = textField.visibleProperty().get();
|
||||
if (visibility != currentState) {
|
||||
if (visibility)
|
||||
visibleAnnotations++;
|
||||
else
|
||||
visibleAnnotations--;
|
||||
}
|
||||
textField.setVisible(visibility);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the annotation with the given name if it exits.
|
||||
* @param annotationName The name given when the annotation was created.
|
||||
*/
|
||||
public void removeAnnotation (String annotationName) {
|
||||
if (annotationName.contains(annotationName)) {
|
||||
Platform.runLater(() -> {
|
||||
this.getChildren().remove(annotationsByName.remove(annotationName).getText());
|
||||
visibleAnnotations--;
|
||||
update();
|
||||
});
|
||||
annotationsByName.remove(annotationName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the annotation.
|
||||
* @param x x location
|
||||
* @param y y location
|
||||
*/
|
||||
public void setLocation (double x, double y) {
|
||||
Platform.runLater(()-> this.relocate(x + BACKGROUND_X, y + BACKGROUND_Y));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the width of the annotation box. Default is 145.
|
||||
* @param width new width.
|
||||
*/
|
||||
public void setWidth (double width) {
|
||||
backgroundWidth = width;
|
||||
Platform.runLater(() -> background.setWidth(backgroundWidth));
|
||||
}
|
||||
|
||||
private void update () {
|
||||
background.setVisible(visibleAnnotations != 0);
|
||||
background.setHeight(Math.abs(BACKGROUND_X) + TEXT_BUFFER + BACKGROUND_H_PER_TEXT * visibleAnnotations);
|
||||
for (int i = 1; i <= visibleAnnotations; i++) {
|
||||
Text text = (Text) this.getChildren().get(i);
|
||||
if (text.visibleProperty().get()) {
|
||||
text.setX(X_OFFSET_TEXT);
|
||||
text.setY(Y_OFFSET_TEXT_INIT + Y_OFFSET_PER_TEXT * i);
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a text object for an annotation.
|
||||
* @return The text object
|
||||
*/
|
||||
private Text getTextObject() {
|
||||
Text text = new Text();
|
||||
text.setFill(theme);
|
||||
text.setStrokeWidth(2);
|
||||
// text.setCacheHint(CacheHint.QUALITY);
|
||||
text.setCache(true);
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the colour of the annotation box's border and text colour.
|
||||
* @param value desired colour.
|
||||
*/
|
||||
public void setFill (Paint value) {
|
||||
theme = value;
|
||||
background.setStroke(theme);
|
||||
annotationsByName.forEach((name, annotation) -> annotation.getText().setFill(theme));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package seng302.visualiser.fxObjects.assets_2D;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Group;
|
||||
@@ -8,18 +7,16 @@ import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Circle;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory.RoundingSide;
|
||||
import seng302.visualiser.fxObjects.Marker;
|
||||
|
||||
/**
|
||||
* Visual object for a mark. Contains a coloured circle and any specified arrows.
|
||||
*/
|
||||
public class Marker2D extends Group {
|
||||
public class Marker2D extends Marker {
|
||||
|
||||
private Circle mark = new Circle();
|
||||
private Paint colour = Color.BLACK;
|
||||
private List<Group> enterArrows = new ArrayList<>();
|
||||
private List<Group> exitArrows = new ArrayList<>();
|
||||
private int enterArrowIndex = 0;
|
||||
private int exitArrowIndex = 0;
|
||||
|
||||
/**
|
||||
* Creates a new Marker containing only a circle. The default colour is black.
|
||||
@@ -61,6 +58,14 @@ public class Marker2D extends Group {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFinishArrow(RoundingSide roundingSide, double entryAngle, double exitAngle){
|
||||
enterArrows.add(
|
||||
MarkArrowFactory.constructInteriorArrow(roundingSide, entryAngle, exitAngle, Color.RED)
|
||||
);
|
||||
exitArrows.add(new Group());
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the next EnterArrow. Does nothing if there are no more enter arrows. Other arrows
|
||||
* become hidden.
|
||||
@@ -79,7 +84,8 @@ public class Marker2D extends Group {
|
||||
exitArrowIndex++;
|
||||
}
|
||||
|
||||
private void showArrow(List<Group> arrowList, int arrowListIndex) {
|
||||
@Override
|
||||
protected void showArrow(List<Group> arrowList, int arrowListIndex) {
|
||||
if (arrowListIndex < arrowList.size()) {
|
||||
Platform.runLater(() ->
|
||||
this.getChildren().setAll(mark, arrowList.get(arrowListIndex))
|
||||
|
||||
@@ -16,10 +16,6 @@ public class Wake extends Group {
|
||||
|
||||
//The number of wakes
|
||||
private int numWakes = 8;
|
||||
//The total possible difference between the first wake and the last. Increasing/Decreasing this will make wakes fan out more/less.
|
||||
private final double MAX_DIFF = 75;
|
||||
//Increasing/decreasing this will alter the speed that wakes converge when the heading stop changing. Anything over about 1500 may cause oscillation.
|
||||
private final int UNIFICATION_SPEED = 45;
|
||||
|
||||
|
||||
private Arc[] arcs = new Arc[numWakes];
|
||||
@@ -69,34 +65,6 @@ public class Wake extends Group {
|
||||
rad += (14 / numWakes) + (velocity / 2.5);
|
||||
}
|
||||
});
|
||||
// } else {
|
||||
// rotations[0] = rotation;
|
||||
// ((Rotate) arcs[0].getTransforms().get(0)).setAngle(rotation);
|
||||
// for (int i = 1; i < numWakes; i++) {
|
||||
// double wakeSeparationRad = Math.toRadians(rotations[i - 1] - rotations[i]);
|
||||
// double shortestDistance = Math.atan2(
|
||||
// Math.sin(wakeSeparationRad),
|
||||
// Math.cos(wakeSeparationRad)
|
||||
// );
|
||||
// double distDeg = Math.toDegrees(shortestDistance);
|
||||
// if (rotationalVelocities[i - 1] < 0.01 && rotationalVelocities[i - 1] > -0.01) {
|
||||
// rotationalVelocities[i] = distDeg / UNIFICATION_SPEED * 2 * Math.log(Math.abs(distDeg) + 1) / Math.log(MAX_DIFF / numWakes);
|
||||
//
|
||||
// } else {
|
||||
// if (distDeg < (MAX_DIFF / numWakes)) {
|
||||
// rotationalVelocities[i] = distDeg / UNIFICATION_SPEED * Math.log(Math.abs(distDeg) + 1) / Math.log(MAX_DIFF / numWakes);
|
||||
// } else
|
||||
// rotationalVelocities[i] = rotationalVelocities[i - 1];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// double rad = (14 / numWakes) + velocity;
|
||||
// for (Arc arc : arcs) {
|
||||
// arc.setRadiusX(rad);
|
||||
// arc.setRadiusY(rad);
|
||||
// rad += (14 / numWakes) + (velocity / 2.5);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package seng302.visualiser.fxObjects.assets_2D;
|
||||
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Polyline;
|
||||
import javafx.scene.shape.StrokeLineCap;
|
||||
import javafx.scene.shape.StrokeLineJoin;
|
||||
|
||||
/**
|
||||
* Created by cir27 on 5/09/17.
|
||||
*/
|
||||
public class WindArrow extends Polyline {
|
||||
public WindArrow(Paint fill) {
|
||||
this.getPoints().addAll(
|
||||
-10d, 15d,
|
||||
0d, 25d,
|
||||
0d, -25d,
|
||||
0d, 25d,
|
||||
10d, 15d
|
||||
);
|
||||
this.setStrokeLineCap(StrokeLineCap.ROUND);
|
||||
this.setStroke(fill);
|
||||
this.setStrokeWidth(5);
|
||||
this.setStrokeLineJoin(StrokeLineJoin.ROUND);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public enum BoatMeshType {
|
||||
PIRATE_SHIP("pirateship_hull.stl", "pirateship_mast.stl", -0.5415, "pirateship_mainsail.stl",
|
||||
-0.5415, "pirateship_frontsail.stl", true, 1.2, 1.6, 1.2),
|
||||
DUCKY("ducky_hull.stl", "ducky_mast.stl", -2.18539, "ducky_sail.stl", -2.18539, "ducky_eyes.stl", false, 1.2, 1.1, 1.4),
|
||||
PARROT("parrot_hull.stl", null, 0, "parrot_sail.stl", 0, "parrot_features.stl", true, 1, 1, 1),
|
||||
PARROT("parrot_hull.stl", null, 0, "parrot_features.stl", 0, "parrot_sail.stl", true, 1, 1, 1),
|
||||
WAKA("waka_hull.stl", "waka_mast.stl", 0, "waka_sail.stl", 0, null, true, 1.7, 0.5, 1.5);
|
||||
|
||||
final String hullFile, mastFile, sailFile, jibFile;
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
package seng302.visualiser.fxObjects.assets_3D;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Group;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory.RoundingSide;
|
||||
import seng302.visualiser.fxObjects.Marker;
|
||||
|
||||
/**
|
||||
* Visual object for a mark. Contains a coloured circle and any specified arrows.
|
||||
*/
|
||||
public class Marker3D extends Group {
|
||||
public class Marker3D extends Marker {
|
||||
|
||||
private Model mark;
|
||||
private List<Group> enterArrows = new ArrayList<>();
|
||||
private List<Group> exitArrows = new ArrayList<>();
|
||||
private int enterArrowIndex = 0;
|
||||
private int exitArrowIndex = 0;
|
||||
private ModelType markType;
|
||||
private ModelType arrowType;
|
||||
|
||||
@@ -60,23 +55,18 @@ public class Marker3D extends Group {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the next EnterArrow. Does nothing if there are no more enter arrows. Other arrows become hidden.
|
||||
*/
|
||||
public void showNextEnterArrow() {
|
||||
showArrow(enterArrows, enterArrowIndex);
|
||||
enterArrowIndex++;
|
||||
public void addFinishArrow(RoundingSide roundingSide, double entryAngle,
|
||||
double exitAngle) {
|
||||
enterArrows.add(
|
||||
MarkArrowFactory.constructEntryArrow3D(roundingSide, entryAngle, ModelType.FINISH_ARROW).getAssets()
|
||||
);
|
||||
exitArrows.add(
|
||||
MarkArrowFactory.constructExitArrow3D(roundingSide, exitAngle, ModelType.FINISH_ARROW).getAssets()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the next ExitArrow. Does nothing if there are no more enter arrows. Other arrows become hidden.
|
||||
*/
|
||||
public void showNextExitArrow() {
|
||||
showArrow(exitArrows, exitArrowIndex);
|
||||
exitArrowIndex++;
|
||||
}
|
||||
|
||||
private void showArrow(List<Group> arrowList, int arrowListIndex) {
|
||||
@Override
|
||||
protected void showArrow(List<Group> arrowList, int arrowListIndex) {
|
||||
if (arrowListIndex < arrowList.size()) {
|
||||
Platform.runLater(() ->
|
||||
this.getChildren().setAll(mark.getAssets(), arrowList.get(arrowListIndex))
|
||||
|
||||
@@ -16,7 +16,6 @@ import javafx.scene.transform.Scale;
|
||||
import javafx.scene.transform.Translate;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Factory class for creating 3D models of boatTypes.
|
||||
*/
|
||||
@@ -100,19 +99,19 @@ public class ModelFactory {
|
||||
mast.setMaterial(new PhongMaterial(primaryColour));
|
||||
boatAssets.getChildren().add(mast);
|
||||
} else {
|
||||
boatAssets.getChildren().add(new Group());
|
||||
boatAssets.getChildren().add(new MeshView());
|
||||
}
|
||||
|
||||
MeshView sail = importBoatSTL(boatType.sailFile);
|
||||
sail.setMaterial(
|
||||
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.DARKGRAY : Color.WHITE)
|
||||
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.BLACK : Color.WHITE)
|
||||
);
|
||||
boatAssets.getChildren().add(sail);
|
||||
|
||||
if (boatType.jibFile != null) {
|
||||
MeshView jib = importBoatSTL(boatType.jibFile);
|
||||
jib.setMaterial(
|
||||
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.BLACK : Color.WHITE)
|
||||
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.DARKGRAY : Color.WHITE)
|
||||
);
|
||||
boatAssets.getChildren().add(jib);
|
||||
}
|
||||
@@ -276,4 +275,31 @@ public class ModelFactory {
|
||||
);
|
||||
return new Model(new Group(assets), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a 3D wind arrow.
|
||||
*
|
||||
* @return 3D wind arrow object
|
||||
*/
|
||||
public static Model makeWindArrow() {
|
||||
ColModelImporter importer = new ColModelImporter();
|
||||
importer.read(ModelFactory.class.getResource("/meshes/" + ModelType.WIND_ARROW.filename));
|
||||
Group assets = new Group(importer.getImport());
|
||||
assets.setCache(true);
|
||||
assets.setCacheHint(CacheHint.SCALE_AND_ROTATE);
|
||||
|
||||
Rotate animationRotate = new Rotate(0, new Point3D(0, 1, 0));
|
||||
assets.getTransforms().addAll(
|
||||
new Translate(0, 0, 0),
|
||||
new Scale(5, 5, 5),
|
||||
new Rotate(270, new Point3D(1, 0, 0)),
|
||||
animationRotate
|
||||
);
|
||||
|
||||
assets.getChildren().addAll(
|
||||
new AmbientLight()
|
||||
);
|
||||
|
||||
return new Model(new Group(assets), null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ public enum ModelType {
|
||||
LAND("land.dae"),
|
||||
LAND_SMOOTH("land_smooth.dae"),
|
||||
NEXT_MARK_INDICATOR("indicator_arrow.dae"),
|
||||
PLAYER_IDENTIFIER_TORUS("torus.dae");
|
||||
PLAYER_IDENTIFIER_TORUS("torus.dae"),
|
||||
WIND_ARROW("windFiles/arrow56.dae"); // change filename
|
||||
|
||||
final String filename;
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package seng302.visualiser.map;
|
||||
|
||||
/**
|
||||
* The Boundary class represents a rectangle territorial boundary on a map. It
|
||||
* contains four extremity double values(N, E, S, W). N and S are represented as
|
||||
* latitudes in radians. E and W are represented as longitudes in radians.
|
||||
*
|
||||
* Created by Haoming on 10/5/17
|
||||
*/
|
||||
public class Boundary {
|
||||
|
||||
private double northLat, eastLng, southLat, westLng;
|
||||
|
||||
public Boundary(double northLat, double eastLng, double southLat, double westLng) {
|
||||
this.northLat = northLat;
|
||||
this.eastLng = eastLng;
|
||||
this.southLat = southLat;
|
||||
this.westLng = westLng;
|
||||
}
|
||||
|
||||
double getCentreLat() {
|
||||
return (northLat + southLat) / 2;
|
||||
}
|
||||
|
||||
double getCentreLng() {
|
||||
return (eastLng + westLng) / 2;
|
||||
}
|
||||
|
||||
double getNorthLat() {
|
||||
return northLat;
|
||||
}
|
||||
|
||||
double getEastLng() {
|
||||
return eastLng;
|
||||
}
|
||||
|
||||
double getSouthLat() {
|
||||
return southLat;
|
||||
}
|
||||
|
||||
double getWestLng() {
|
||||
return westLng;
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package seng302.visualiser.map;
|
||||
|
||||
import java.net.URL;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.image.Image;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import seng302.model.GeoPoint;
|
||||
|
||||
/**
|
||||
* CanvasMap retrieves a map image with given geo boundary from Google Map server.
|
||||
* By passing a rectangle like geo boundary, it returns a map image with the
|
||||
* highest resolution. However, due to free quote account usage limit, the maximum
|
||||
* resolution is only 1280 * 1280.
|
||||
*
|
||||
* Created by Haoming on 15/5/2017
|
||||
*/
|
||||
public class CanvasMap {
|
||||
|
||||
private Boundary boundary;
|
||||
private long width, height; // desired image size
|
||||
private int zoom;
|
||||
|
||||
private String KEY = "AIzaSyC-5oOShMCY5Oy_9L7guYMPUPFHDMr37wE";
|
||||
|
||||
public CanvasMap(Boundary boundary) {
|
||||
this.boundary = boundary;
|
||||
calculateOptimalMapSize();
|
||||
}
|
||||
|
||||
public Image getMapImage() {
|
||||
try {
|
||||
URL url = new URL(getRequest());
|
||||
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
||||
|
||||
return new Image(connection.getInputStream());
|
||||
} catch (Exception e) {
|
||||
System.out.println("[CanvasMap] Exception");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String getRequest() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("https://maps.googleapis.com/maps/api/staticmap?");
|
||||
sb.append(String.format("center=%f,%f", boundary.getCentreLat(), boundary.getCentreLng()));
|
||||
sb.append(String.format("&zoom=%d", zoom));
|
||||
sb.append(String.format("&size=%dx%d&scale=2", width, height));
|
||||
sb.append("&style=feature:all|element:labels|visibility:off"); // hide all labels on map
|
||||
// sb.append(String.format("&markers=%f,%f", boundary.getSouthLat(), boundary.getWestLng()));
|
||||
// sb.append(String.format("&key=%s", KEY));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void calculateOptimalMapSize() {
|
||||
for (int z = 20; z > 0; z--) {
|
||||
MapSize mapSize = getMapSize(z, boundary);
|
||||
zoom = z;
|
||||
width = mapSize.width;
|
||||
height = mapSize.height;
|
||||
// if map size is valid, exit the loop as we have the highest resolution
|
||||
if (mapSize.isValid()) break;
|
||||
}
|
||||
}
|
||||
|
||||
private MapSize getMapSize(int zoom, Boundary boundary) {
|
||||
double scale = Math.pow(2, zoom);
|
||||
GeoPoint geoSW = new GeoPoint(boundary.getSouthLat(), boundary.getWestLng());
|
||||
GeoPoint geoNE = new GeoPoint(boundary.getNorthLat(), boundary.getEastLng());
|
||||
Point2D pointSW = MercatorProjection.toMapPoint(geoSW);
|
||||
Point2D pointNE = MercatorProjection.toMapPoint(geoNE);
|
||||
return new MapSize(Math.abs(pointNE.getX() - pointSW.getX()) * scale,
|
||||
Math.abs(pointNE.getY() - pointSW.getY()) * scale);
|
||||
}
|
||||
|
||||
class MapSize {
|
||||
long width, height;
|
||||
|
||||
MapSize(double width, double height) {
|
||||
this.width = Math.round(width);
|
||||
this.height = Math.round(height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map size is valid when width and height are both less than 640 pixels
|
||||
* @return true if both dimensions are less than 640px
|
||||
*/
|
||||
boolean isValid() {
|
||||
return Math.max(width, height) <= 640;
|
||||
}
|
||||
}
|
||||
|
||||
public long getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public long getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getZoom() {
|
||||
return zoom;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package seng302.visualiser.map;
|
||||
|
||||
import javafx.geometry.Point2D;
|
||||
import seng302.model.GeoPoint;
|
||||
|
||||
/**
|
||||
* An utility class useful to convert between Geo locations and Mercator projection
|
||||
* planar coordinates.
|
||||
* Created by Haoming on 15/5/2017
|
||||
*/
|
||||
public class MercatorProjection {
|
||||
|
||||
private static final double MERCATOR_RANGE = 256;
|
||||
private static final double pixelsPerLngDegree = MERCATOR_RANGE / 360.0;
|
||||
private static final double pixelsPerLngRadian = MERCATOR_RANGE / (2 * Math.PI);
|
||||
|
||||
/**
|
||||
* A help function keeps the value in bound between -0.9999 and 0.9999.
|
||||
* @param value in bound value
|
||||
* @return the value in bound
|
||||
*/
|
||||
private static double bound(double value) {
|
||||
return Math.min(Math.max(value, -0.9999), 0.9999);
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects a Geo Location (lat, lng) on a planar
|
||||
* @param geo GeoPoint (lat, lng) location to be projected
|
||||
* @return the projection Point2D (x, y) on planar
|
||||
*/
|
||||
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);
|
||||
|
||||
// NOTE(appleton): Truncating to 0.9999 effectively limits latitude to
|
||||
// 89.189. This is about a third of a tile past the edge of the world tile.
|
||||
double sinY = bound(Math.sin(Math.toRadians(geo.getLat())));
|
||||
y = origin.getY() + 0.5 * Math.log((1 + sinY) / (1 - sinY)) * (-pixelsPerLngRadian);
|
||||
return new Point2D(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the planar projection (x, y) back to Geo Location (lat, lng)
|
||||
* @param point Point2D (x, y) to be converted back
|
||||
* @return the original Geo location converted from the given projection point
|
||||
*/
|
||||
public static GeoPoint toMapGeo(Point2D point) {
|
||||
Point2D origin = new Point2D(MERCATOR_RANGE / 2.0, MERCATOR_RANGE / 2.0);
|
||||
double lng = (point.getX() - origin.getX()) / pixelsPerLngDegree;
|
||||
double latRadians = (point.getY() - origin.getY()) / (-pixelsPerLngRadian);
|
||||
double lat = Math.toDegrees(2 * Math.atan(Math.exp(latRadians)) - Math.PI / 2.0);
|
||||
return new GeoPoint(lat, lng);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package seng302.visualiser.map;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
|
||||
public class TestMapController implements Initializable{
|
||||
|
||||
@FXML
|
||||
private Canvas mapCanvas;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
GraphicsContext gc = mapCanvas.getGraphicsContext2D();
|
||||
Boundary bound = new Boundary(57.662943, 11.848501, 57.673945, 11.824966);
|
||||
CanvasMap canvasMap = new CanvasMap(bound);
|
||||
gc.drawImage(canvasMap.getMapImage(), 0, 0, canvasMap.getWidth(), canvasMap.getHeight());
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#timerGrid{
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-effect: -fx-pp-dropshadow-light;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
GridPane .timer * {
|
||||
@@ -27,20 +28,24 @@ GridPane .timer * {
|
||||
#chatHistoryHolder {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-effect: -fx-pp-dropshadow-light;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
#chatInputHolder {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-effect: -fx-pp-dropshadow-light;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
#windGridPane {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-effect: -fx-pp-dropshadow-light;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
#windHolder {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.5);
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
#chatSend {
|
||||
@@ -61,6 +66,25 @@ GridPane .timer * {
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
#chatToggleButton {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-background-radius: 5;
|
||||
-fx-min-width: 30;
|
||||
-fx-min-height: 30;
|
||||
}
|
||||
|
||||
#windImageView {
|
||||
-fx-image: url("/images/wind-180.png");
|
||||
}
|
||||
|
||||
#miniMapPane {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
#miniMapButton {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.6);
|
||||
-fx-background-radius: 5;
|
||||
-fx-min-width: 30;
|
||||
-fx-min-height: 30;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#windPane {
|
||||
-fx-background-color: rgba(255, 255, 255, 0);
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
<CentralLat> 57.6679590 </CentralLat>
|
||||
<CentralLng> 11.8503233 </CentralLng>
|
||||
|
||||
<MaxPlayers> 10 </MaxPlayers>
|
||||
<MaxPlayers> 8 </MaxPlayers>
|
||||
|
||||
<Marks>
|
||||
<CompoundMark CompoundMarkID="1">
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
<CentralLat> -14.6457 </CentralLat>
|
||||
<CentralLng> 47.612855 </CentralLng>
|
||||
|
||||
<MaxPlayers> 5 </MaxPlayers>
|
||||
<MaxPlayers> 8 </MaxPlayers>
|
||||
|
||||
<Marks>
|
||||
<CompoundMark CompoundMarkID="1">
|
||||
<Mark Lat="-14.071412" Lng="47.05756"/>
|
||||
<Mark Lat="-14.069914" Lng="47.058541"/>
|
||||
<Mark Lat="-14.070412" Lng="47.05746"/>
|
||||
<Mark Lat="-14.068014" Lng="47.057541"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="2">
|
||||
<Mark Lat="-14.067194" Lng="47.053818" />
|
||||
@@ -64,7 +64,7 @@
|
||||
<CourseLimit>
|
||||
<Limit Lat="-14.073371" Lng="47.058213" />
|
||||
<Limit Lat="-14.06453" Lng="47.050003" />
|
||||
<Limit Lat="-14.059022" Lng="47.057286" />
|
||||
<Limit Lat="-14.057022" Lng="47.057286" />
|
||||
<Limit Lat="-14.058723" Lng="47.064358" />
|
||||
<Limit Lat="-14.06261" Lng="47.071293" />
|
||||
<Limit Lat="-14.070814" Lng="47.06762" />
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<CentralLat> 57.6679590 </CentralLat>
|
||||
<CentralLng> 11.8503233 </CentralLng>
|
||||
|
||||
<MaxPlayers> 5 </MaxPlayers>
|
||||
<MaxPlayers> 8 </MaxPlayers>
|
||||
|
||||
<Marks>
|
||||
<CompoundMark CompoundMarkID="1">
|
||||
@@ -15,7 +15,6 @@
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="2">
|
||||
<Mark Lat="57.670914" Lng="11.835263"/>
|
||||
<Mark Lat="57.6699024" Lng="11.8353195"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="3">
|
||||
<Mark Lat="57.6674596" Lng="11.8417500"/>
|
||||
@@ -29,21 +28,27 @@
|
||||
<Mark Lat="57.667311" Lng="11.828857"/>
|
||||
<Mark Lat="57.667334" Lng="11.825853"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="6">
|
||||
<Mark Lat="57.6675700" Lng="11.8359880"/>
|
||||
<Mark Lat="57.667610" Lng="11.833473"/>
|
||||
</CompoundMark>
|
||||
</Marks>
|
||||
|
||||
<Course>
|
||||
<OpeningSegment>
|
||||
<Corner CompoundMarkID="1" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="2" Rounding="P"/>
|
||||
<Corner CompoundMarkID="2" Rounding="S"/>
|
||||
</OpeningSegment>
|
||||
|
||||
<RepeatingSegment>
|
||||
<Corner CompoundMarkID="3" Rounding="SP"/>
|
||||
<Corner CompoundMarkID="4" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="5" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="2" Rounding="S"/>
|
||||
</RepeatingSegment>
|
||||
|
||||
<ClosingSegment>
|
||||
<Corner CompoundMarkID="5" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="6" Rounding="PS"/>
|
||||
</ClosingSegment>
|
||||
</Course>
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RaceDefinition>
|
||||
|
||||
<CourseName>Madagascar</CourseName>
|
||||
|
||||
<CentralLat>-15.67707</CentralLat>
|
||||
<CentralLng>49.79338</CentralLng>
|
||||
|
||||
<MaxPlayers> 5 </MaxPlayers>
|
||||
|
||||
<Marks>
|
||||
<CompoundMark CompoundMarkID="1">
|
||||
<Mark Lat="-15.67466" Lng="49.79104"/>
|
||||
<Mark Lat="-15.67408" Lng="49.79224"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="2">
|
||||
<Mark Lat="-15.67548" Lng="49.79271"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="3">
|
||||
<Mark Lat="-15.67744" Lng="49.79235"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="4">
|
||||
<Mark Lat="-15.67691" Lng="49.79501"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="5">
|
||||
<Mark Lat="-15.67775" Lng="49.79619"/>
|
||||
<Mark Lat="-15.67827" Lng="49.79713"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="6">
|
||||
<Mark Lat="-15.67922" Lng="49.79318"/>
|
||||
<Mark Lat="-15.67972" Lng="49.79393"/>
|
||||
</CompoundMark>
|
||||
</Marks>
|
||||
|
||||
<Course>
|
||||
<OpeningSegment>
|
||||
<Corner CompoundMarkID="1" Rounding="PS"/>
|
||||
</OpeningSegment>
|
||||
|
||||
<RepeatingSegment>
|
||||
<Corner CompoundMarkID="2" Rounding="P"/>
|
||||
<Corner CompoundMarkID="3" Rounding="S"/>
|
||||
<Corner CompoundMarkID="4" Rounding="S"/>
|
||||
<Corner CompoundMarkID="3" Rounding="P"/>
|
||||
</RepeatingSegment>
|
||||
|
||||
<ClosingSegment>
|
||||
<Corner CompoundMarkID="5" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="6" Rounding="PS"/>
|
||||
</ClosingSegment>
|
||||
</Course>
|
||||
|
||||
<CourseLimit>
|
||||
<Limit Lat="-15.67571" Lng="49.78984"/>
|
||||
<Limit Lat="-15.6787" Lng="49.79024"/>
|
||||
<Limit Lat="-15.68046" Lng="49.79247"/>
|
||||
<Limit Lat="-15.68073" Lng="49.79599"/>
|
||||
<Limit Lat="-15.67939" Lng="49.79855"/>
|
||||
<Limit Lat="-15.67662" Lng="49.79855"/>
|
||||
<Limit Lat="-15.67474" Lng="49.79694"/>
|
||||
<Limit Lat="-15.67271" Lng="49.79355"/>
|
||||
<Limit Lat="-15.67333" Lng="49.79071"/>
|
||||
</CourseLimit>
|
||||
|
||||
</RaceDefinition>
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RaceDefinition>
|
||||
|
||||
<CourseName>Waiheke</CourseName>
|
||||
|
||||
<CentralLat>-36.80008</CentralLat>
|
||||
<CentralLng>175.012225</CentralLng>
|
||||
|
||||
<MaxPlayers> 6 </MaxPlayers>
|
||||
|
||||
<Marks>
|
||||
<CompoundMark CompoundMarkID="1">
|
||||
<Mark Lat="-36.79512" Lng="175.0116"/>
|
||||
<Mark Lat="-36.79468" Lng="175.01312"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="2">
|
||||
<Mark Lat="-36.80069" Lng="175.01495"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="3">
|
||||
<Mark Lat="-36.79892" Lng="175.01832"/>
|
||||
<Mark Lat="-36.79988" Lng="175.01913"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="4">
|
||||
<Mark Lat="-36.80064" Lng="175.01171"/>
|
||||
<Mark Lat="-36.80186" Lng="175.0124"/>
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="5">
|
||||
<Mark Lat="-36.79579" Lng="175.01194"/>
|
||||
<Mark Lat="-36.79545" Lng="175.01349"/>
|
||||
</CompoundMark>
|
||||
</Marks>
|
||||
|
||||
<Course>
|
||||
<OpeningSegment>
|
||||
<Corner CompoundMarkID="1" Rounding="SP"/>
|
||||
<Corner CompoundMarkID="2" Rounding="P"/>
|
||||
</OpeningSegment>
|
||||
|
||||
<RepeatingSegment>
|
||||
<Corner CompoundMarkID="3" Rounding="PS"/>
|
||||
<Corner CompoundMarkID="4" Rounding="SP"/>
|
||||
</RepeatingSegment>
|
||||
|
||||
<ClosingSegment>
|
||||
<Corner CompoundMarkID="5" Rounding="PS"/>
|
||||
</ClosingSegment>
|
||||
</Course>
|
||||
|
||||
<CourseLimit>
|
||||
<Limit Lat="-36.79350" Lng="175.01194"/>
|
||||
<Limit Lat="-36.79411" Lng="175.01455"/>
|
||||
<Limit Lat="-36.79765" Lng="175.01898"/>
|
||||
<Limit Lat="-36.79909" Lng="175.02149"/>
|
||||
<Limit Lat="-36.80163" Lng="175.02014"/>
|
||||
<Limit Lat="-36.80292" Lng="175.0175"/>
|
||||
<Limit Lat="-36.80295" Lng="175.01008"/>
|
||||
<Limit Lat="-36.80107" Lng="175.00960"/>
|
||||
<Limit Lat="-36.79567" Lng="175.00961"/>
|
||||
</CourseLimit>
|
||||
|
||||
</RaceDefinition>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,518 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<asset>
|
||||
<contributor>
|
||||
<author>Blender User</author>
|
||||
<authoring_tool>Blender 2.79.0 commit date:2017-09-11, commit time:10:43, hash:5bd8ac9</authoring_tool>
|
||||
</contributor>
|
||||
<created>2017-09-28T02:22:29</created>
|
||||
<modified>2017-09-28T02:22:29</modified>
|
||||
<unit name="meter" meter="1"/>
|
||||
<up_axis>Z_UP</up_axis>
|
||||
</asset>
|
||||
<library_cameras>
|
||||
<camera id="Camera-camera" name="Camera">
|
||||
<optics>
|
||||
<technique_common>
|
||||
<perspective>
|
||||
<xfov sid="xfov">49.13434</xfov>
|
||||
<aspect_ratio>1.777778</aspect_ratio>
|
||||
<znear sid="znear">0.1</znear>
|
||||
<zfar sid="zfar">100</zfar>
|
||||
</perspective>
|
||||
</technique_common>
|
||||
</optics>
|
||||
<extra>
|
||||
<technique profile="blender">
|
||||
<shiftx sid="shiftx" type="float">0</shiftx>
|
||||
<shifty sid="shifty" type="float">0</shifty>
|
||||
<YF_dofdist sid="YF_dofdist" type="float">0</YF_dofdist>
|
||||
</technique>
|
||||
</extra>
|
||||
</camera>
|
||||
<camera id="Camera_001-camera" name="Camera.001">
|
||||
<optics>
|
||||
<technique_common>
|
||||
<perspective>
|
||||
<xfov sid="xfov">49.13434</xfov>
|
||||
<aspect_ratio>1.777778</aspect_ratio>
|
||||
<znear sid="znear">0.1</znear>
|
||||
<zfar sid="zfar">100</zfar>
|
||||
</perspective>
|
||||
</technique_common>
|
||||
</optics>
|
||||
<extra>
|
||||
<technique profile="blender">
|
||||
<shiftx sid="shiftx" type="float">0</shiftx>
|
||||
<shifty sid="shifty" type="float">0</shifty>
|
||||
<YF_dofdist sid="YF_dofdist" type="float">0</YF_dofdist>
|
||||
</technique>
|
||||
</extra>
|
||||
</camera>
|
||||
<camera id="Camera_001-camera" name="Camera.003">
|
||||
<optics>
|
||||
<technique_common>
|
||||
<perspective>
|
||||
<xfov sid="xfov">49.13434</xfov>
|
||||
<aspect_ratio>1.777778</aspect_ratio>
|
||||
<znear sid="znear">0.1</znear>
|
||||
<zfar sid="zfar">100</zfar>
|
||||
</perspective>
|
||||
</technique_common>
|
||||
</optics>
|
||||
<extra>
|
||||
<technique profile="blender">
|
||||
<shiftx sid="shiftx" type="float">0</shiftx>
|
||||
<shifty sid="shifty" type="float">0</shifty>
|
||||
<YF_dofdist sid="YF_dofdist" type="float">0</YF_dofdist>
|
||||
</technique>
|
||||
</extra>
|
||||
</camera>
|
||||
<camera id="Camera_001_001-camera" name="Camera.003">
|
||||
<optics>
|
||||
<technique_common>
|
||||
<perspective>
|
||||
<xfov sid="xfov">49.13434</xfov>
|
||||
<aspect_ratio>1.777778</aspect_ratio>
|
||||
<znear sid="znear">0.1</znear>
|
||||
<zfar sid="zfar">100</zfar>
|
||||
</perspective>
|
||||
</technique_common>
|
||||
</optics>
|
||||
<extra>
|
||||
<technique profile="blender">
|
||||
<shiftx sid="shiftx" type="float">0</shiftx>
|
||||
<shifty sid="shifty" type="float">0</shifty>
|
||||
<YF_dofdist sid="YF_dofdist" type="float">0</YF_dofdist>
|
||||
</technique>
|
||||
</extra>
|
||||
</camera>
|
||||
</library_cameras>
|
||||
<library_lights>
|
||||
<light id="Lamp-light" name="Lamp">
|
||||
<technique_common>
|
||||
<point>
|
||||
<color sid="color">1 1 1</color>
|
||||
<constant_attenuation>1</constant_attenuation>
|
||||
<linear_attenuation>0</linear_attenuation>
|
||||
<quadratic_attenuation>0.00111109</quadratic_attenuation>
|
||||
</point>
|
||||
</technique_common>
|
||||
<extra>
|
||||
<technique profile="blender">
|
||||
<type sid="type" type="int">0</type>
|
||||
<flag sid="flag" type="int">0</flag>
|
||||
<mode sid="mode" type="int">8192</mode>
|
||||
<gamma sid="blender_gamma" type="float">1</gamma>
|
||||
<red sid="red" type="float">1</red>
|
||||
<green sid="green" type="float">1</green>
|
||||
<blue sid="blue" type="float">1</blue>
|
||||
<shadow_r sid="blender_shadow_r" type="float">0</shadow_r>
|
||||
<shadow_g sid="blender_shadow_g" type="float">0</shadow_g>
|
||||
<shadow_b sid="blender_shadow_b" type="float">0</shadow_b>
|
||||
<energy sid="blender_energy" type="float">1</energy>
|
||||
<dist sid="blender_dist" type="float">29.99998</dist>
|
||||
<spotsize sid="spotsize" type="float">75</spotsize>
|
||||
<spotblend sid="spotblend" type="float">0.15</spotblend>
|
||||
<halo_intensity sid="blnder_halo_intensity" type="float">1</halo_intensity>
|
||||
<att1 sid="att1" type="float">0</att1>
|
||||
<att2 sid="att2" type="float">1</att2>
|
||||
<falloff_type sid="falloff_type" type="int">2</falloff_type>
|
||||
<clipsta sid="clipsta" type="float">1.000799</clipsta>
|
||||
<clipend sid="clipend" type="float">30.002</clipend>
|
||||
<bias sid="bias" type="float">1</bias>
|
||||
<soft sid="soft" type="float">3</soft>
|
||||
<compressthresh sid="compressthresh" type="float">0.04999995</compressthresh>
|
||||
<bufsize sid="bufsize" type="int">2880</bufsize>
|
||||
<samp sid="samp" type="int">3</samp>
|
||||
<buffers sid="buffers" type="int">1</buffers>
|
||||
<filtertype sid="filtertype" type="int">0</filtertype>
|
||||
<bufflag sid="bufflag" type="int">0</bufflag>
|
||||
<buftype sid="buftype" type="int">2</buftype>
|
||||
<ray_samp sid="ray_samp" type="int">1</ray_samp>
|
||||
<ray_sampy sid="ray_sampy" type="int">1</ray_sampy>
|
||||
<ray_sampz sid="ray_sampz" type="int">1</ray_sampz>
|
||||
<ray_samp_type sid="ray_samp_type" type="int">0</ray_samp_type>
|
||||
<area_shape sid="area_shape" type="int">1</area_shape>
|
||||
<area_size sid="area_size" type="float">0.1</area_size>
|
||||
<area_sizey sid="area_sizey" type="float">0.1</area_sizey>
|
||||
<area_sizez sid="area_sizez" type="float">1</area_sizez>
|
||||
<adapt_thresh sid="adapt_thresh" type="float">0.000999987</adapt_thresh>
|
||||
<ray_samp_method sid="ray_samp_method" type="int">1</ray_samp_method>
|
||||
<shadhalostep sid="shadhalostep" type="int">0</shadhalostep>
|
||||
<sun_effect_type sid="sun_effect_type" type="int">0</sun_effect_type>
|
||||
<skyblendtype sid="skyblendtype" type="int">1</skyblendtype>
|
||||
<horizon_brightness sid="horizon_brightness" type="float">1</horizon_brightness>
|
||||
<spread sid="spread" type="float">1</spread>
|
||||
<sun_brightness sid="sun_brightness" type="float">1</sun_brightness>
|
||||
<sun_size sid="sun_size" type="float">1</sun_size>
|
||||
<backscattered_light sid="backscattered_light" type="float">1</backscattered_light>
|
||||
<sun_intensity sid="sun_intensity" type="float">1</sun_intensity>
|
||||
<atm_turbidity sid="atm_turbidity" type="float">2</atm_turbidity>
|
||||
<atm_extinction_factor sid="atm_extinction_factor" type="float">1</atm_extinction_factor>
|
||||
<atm_distance_factor sid="atm_distance_factor" type="float">1</atm_distance_factor>
|
||||
<skyblendfac sid="skyblendfac" type="float">1</skyblendfac>
|
||||
<sky_exposure sid="sky_exposure" type="float">1</sky_exposure>
|
||||
<sky_colorspace sid="sky_colorspace" type="int">0</sky_colorspace>
|
||||
</technique>
|
||||
</extra>
|
||||
</light>
|
||||
<light id="Lamp_001-light" name="Lamp.001">
|
||||
<technique_common>
|
||||
<point>
|
||||
<color sid="color">1 1 1</color>
|
||||
<constant_attenuation>1</constant_attenuation>
|
||||
<linear_attenuation>0</linear_attenuation>
|
||||
<quadratic_attenuation>0.00111109</quadratic_attenuation>
|
||||
</point>
|
||||
</technique_common>
|
||||
<extra>
|
||||
<technique profile="blender">
|
||||
<type sid="type" type="int">0</type>
|
||||
<flag sid="flag" type="int">0</flag>
|
||||
<mode sid="mode" type="int">8192</mode>
|
||||
<gamma sid="blender_gamma" type="float">1</gamma>
|
||||
<red sid="red" type="float">1</red>
|
||||
<green sid="green" type="float">1</green>
|
||||
<blue sid="blue" type="float">1</blue>
|
||||
<shadow_r sid="blender_shadow_r" type="float">0</shadow_r>
|
||||
<shadow_g sid="blender_shadow_g" type="float">0</shadow_g>
|
||||
<shadow_b sid="blender_shadow_b" type="float">0</shadow_b>
|
||||
<energy sid="blender_energy" type="float">1</energy>
|
||||
<dist sid="blender_dist" type="float">29.99998</dist>
|
||||
<spotsize sid="spotsize" type="float">75</spotsize>
|
||||
<spotblend sid="spotblend" type="float">0.15</spotblend>
|
||||
<halo_intensity sid="blnder_halo_intensity" type="float">1</halo_intensity>
|
||||
<att1 sid="att1" type="float">0</att1>
|
||||
<att2 sid="att2" type="float">1</att2>
|
||||
<falloff_type sid="falloff_type" type="int">2</falloff_type>
|
||||
<clipsta sid="clipsta" type="float">1.000799</clipsta>
|
||||
<clipend sid="clipend" type="float">30.002</clipend>
|
||||
<bias sid="bias" type="float">1</bias>
|
||||
<soft sid="soft" type="float">3</soft>
|
||||
<compressthresh sid="compressthresh" type="float">0.04999995</compressthresh>
|
||||
<bufsize sid="bufsize" type="int">2880</bufsize>
|
||||
<samp sid="samp" type="int">3</samp>
|
||||
<buffers sid="buffers" type="int">1</buffers>
|
||||
<filtertype sid="filtertype" type="int">0</filtertype>
|
||||
<bufflag sid="bufflag" type="int">0</bufflag>
|
||||
<buftype sid="buftype" type="int">2</buftype>
|
||||
<ray_samp sid="ray_samp" type="int">1</ray_samp>
|
||||
<ray_sampy sid="ray_sampy" type="int">1</ray_sampy>
|
||||
<ray_sampz sid="ray_sampz" type="int">1</ray_sampz>
|
||||
<ray_samp_type sid="ray_samp_type" type="int">0</ray_samp_type>
|
||||
<area_shape sid="area_shape" type="int">1</area_shape>
|
||||
<area_size sid="area_size" type="float">0.1</area_size>
|
||||
<area_sizey sid="area_sizey" type="float">0.1</area_sizey>
|
||||
<area_sizez sid="area_sizez" type="float">1</area_sizez>
|
||||
<adapt_thresh sid="adapt_thresh" type="float">9.99987e-4</adapt_thresh>
|
||||
<ray_samp_method sid="ray_samp_method" type="int">1</ray_samp_method>
|
||||
<shadhalostep sid="shadhalostep" type="int">0</shadhalostep>
|
||||
<sun_effect_type sid="sun_effect_type" type="int">0</sun_effect_type>
|
||||
<skyblendtype sid="skyblendtype" type="int">1</skyblendtype>
|
||||
<horizon_brightness sid="horizon_brightness" type="float">1</horizon_brightness>
|
||||
<spread sid="spread" type="float">1</spread>
|
||||
<sun_brightness sid="sun_brightness" type="float">1</sun_brightness>
|
||||
<sun_size sid="sun_size" type="float">1</sun_size>
|
||||
<backscattered_light sid="backscattered_light" type="float">1</backscattered_light>
|
||||
<sun_intensity sid="sun_intensity" type="float">1</sun_intensity>
|
||||
<atm_turbidity sid="atm_turbidity" type="float">2</atm_turbidity>
|
||||
<atm_extinction_factor sid="atm_extinction_factor" type="float">1</atm_extinction_factor>
|
||||
<atm_distance_factor sid="atm_distance_factor" type="float">1</atm_distance_factor>
|
||||
<skyblendfac sid="skyblendfac" type="float">1</skyblendfac>
|
||||
<sky_exposure sid="sky_exposure" type="float">1</sky_exposure>
|
||||
<sky_colorspace sid="sky_colorspace" type="int">0</sky_colorspace>
|
||||
</technique>
|
||||
</extra>
|
||||
</light>
|
||||
<light id="Lamp_001-light" name="Lamp.003">
|
||||
<technique_common>
|
||||
<point>
|
||||
<color sid="color">1 1 1</color>
|
||||
<constant_attenuation>1</constant_attenuation>
|
||||
<linear_attenuation>0</linear_attenuation>
|
||||
<quadratic_attenuation>0.00111109</quadratic_attenuation>
|
||||
</point>
|
||||
</technique_common>
|
||||
<extra>
|
||||
<technique profile="blender">
|
||||
<type sid="type" type="int">0</type>
|
||||
<flag sid="flag" type="int">0</flag>
|
||||
<mode sid="mode" type="int">8192</mode>
|
||||
<gamma sid="blender_gamma" type="float">1</gamma>
|
||||
<red sid="red" type="float">1</red>
|
||||
<green sid="green" type="float">1</green>
|
||||
<blue sid="blue" type="float">1</blue>
|
||||
<shadow_r sid="blender_shadow_r" type="float">0</shadow_r>
|
||||
<shadow_g sid="blender_shadow_g" type="float">0</shadow_g>
|
||||
<shadow_b sid="blender_shadow_b" type="float">0</shadow_b>
|
||||
<energy sid="blender_energy" type="float">1</energy>
|
||||
<dist sid="blender_dist" type="float">29.99998</dist>
|
||||
<spotsize sid="spotsize" type="float">75</spotsize>
|
||||
<spotblend sid="spotblend" type="float">0.15</spotblend>
|
||||
<halo_intensity sid="blnder_halo_intensity" type="float">1</halo_intensity>
|
||||
<att1 sid="att1" type="float">0</att1>
|
||||
<att2 sid="att2" type="float">1</att2>
|
||||
<falloff_type sid="falloff_type" type="int">2</falloff_type>
|
||||
<clipsta sid="clipsta" type="float">1.000799</clipsta>
|
||||
<clipend sid="clipend" type="float">30.002</clipend>
|
||||
<bias sid="bias" type="float">1</bias>
|
||||
<soft sid="soft" type="float">3</soft>
|
||||
<compressthresh sid="compressthresh" type="float">0.04999995</compressthresh>
|
||||
<bufsize sid="bufsize" type="int">2880</bufsize>
|
||||
<samp sid="samp" type="int">3</samp>
|
||||
<buffers sid="buffers" type="int">1</buffers>
|
||||
<filtertype sid="filtertype" type="int">0</filtertype>
|
||||
<bufflag sid="bufflag" type="int">0</bufflag>
|
||||
<buftype sid="buftype" type="int">2</buftype>
|
||||
<ray_samp sid="ray_samp" type="int">1</ray_samp>
|
||||
<ray_sampy sid="ray_sampy" type="int">1</ray_sampy>
|
||||
<ray_sampz sid="ray_sampz" type="int">1</ray_sampz>
|
||||
<ray_samp_type sid="ray_samp_type" type="int">0</ray_samp_type>
|
||||
<area_shape sid="area_shape" type="int">1</area_shape>
|
||||
<area_size sid="area_size" type="float">0.1</area_size>
|
||||
<area_sizey sid="area_sizey" type="float">0.1</area_sizey>
|
||||
<area_sizez sid="area_sizez" type="float">1</area_sizez>
|
||||
<adapt_thresh sid="adapt_thresh" type="float">9.99987e-4</adapt_thresh>
|
||||
<ray_samp_method sid="ray_samp_method" type="int">1</ray_samp_method>
|
||||
<shadhalostep sid="shadhalostep" type="int">0</shadhalostep>
|
||||
<sun_effect_type sid="sun_effect_type" type="int">0</sun_effect_type>
|
||||
<skyblendtype sid="skyblendtype" type="int">1</skyblendtype>
|
||||
<horizon_brightness sid="horizon_brightness" type="float">1</horizon_brightness>
|
||||
<spread sid="spread" type="float">1</spread>
|
||||
<sun_brightness sid="sun_brightness" type="float">1</sun_brightness>
|
||||
<sun_size sid="sun_size" type="float">1</sun_size>
|
||||
<backscattered_light sid="backscattered_light" type="float">1</backscattered_light>
|
||||
<sun_intensity sid="sun_intensity" type="float">1</sun_intensity>
|
||||
<atm_turbidity sid="atm_turbidity" type="float">2</atm_turbidity>
|
||||
<atm_extinction_factor sid="atm_extinction_factor" type="float">1</atm_extinction_factor>
|
||||
<atm_distance_factor sid="atm_distance_factor" type="float">1</atm_distance_factor>
|
||||
<skyblendfac sid="skyblendfac" type="float">1</skyblendfac>
|
||||
<sky_exposure sid="sky_exposure" type="float">1</sky_exposure>
|
||||
<sky_colorspace sid="sky_colorspace" type="int">0</sky_colorspace>
|
||||
</technique>
|
||||
</extra>
|
||||
</light>
|
||||
<light id="Lamp_001_001-light" name="Lamp.003">
|
||||
<technique_common>
|
||||
<point>
|
||||
<color sid="color">1 1 1</color>
|
||||
<constant_attenuation>1</constant_attenuation>
|
||||
<linear_attenuation>0</linear_attenuation>
|
||||
<quadratic_attenuation>0.00111109</quadratic_attenuation>
|
||||
</point>
|
||||
</technique_common>
|
||||
<extra>
|
||||
<technique profile="blender">
|
||||
<type sid="type" type="int">0</type>
|
||||
<flag sid="flag" type="int">0</flag>
|
||||
<mode sid="mode" type="int">8192</mode>
|
||||
<gamma sid="blender_gamma" type="float">1</gamma>
|
||||
<red sid="red" type="float">1</red>
|
||||
<green sid="green" type="float">1</green>
|
||||
<blue sid="blue" type="float">1</blue>
|
||||
<shadow_r sid="blender_shadow_r" type="float">0</shadow_r>
|
||||
<shadow_g sid="blender_shadow_g" type="float">0</shadow_g>
|
||||
<shadow_b sid="blender_shadow_b" type="float">0</shadow_b>
|
||||
<energy sid="blender_energy" type="float">1</energy>
|
||||
<dist sid="blender_dist" type="float">29.99998</dist>
|
||||
<spotsize sid="spotsize" type="float">75</spotsize>
|
||||
<spotblend sid="spotblend" type="float">0.15</spotblend>
|
||||
<halo_intensity sid="blnder_halo_intensity" type="float">1</halo_intensity>
|
||||
<att1 sid="att1" type="float">0</att1>
|
||||
<att2 sid="att2" type="float">1</att2>
|
||||
<falloff_type sid="falloff_type" type="int">2</falloff_type>
|
||||
<clipsta sid="clipsta" type="float">1.000799</clipsta>
|
||||
<clipend sid="clipend" type="float">30.002</clipend>
|
||||
<bias sid="bias" type="float">1</bias>
|
||||
<soft sid="soft" type="float">3</soft>
|
||||
<compressthresh sid="compressthresh" type="float">0.04999995</compressthresh>
|
||||
<bufsize sid="bufsize" type="int">2880</bufsize>
|
||||
<samp sid="samp" type="int">3</samp>
|
||||
<buffers sid="buffers" type="int">1</buffers>
|
||||
<filtertype sid="filtertype" type="int">0</filtertype>
|
||||
<bufflag sid="bufflag" type="int">0</bufflag>
|
||||
<buftype sid="buftype" type="int">2</buftype>
|
||||
<ray_samp sid="ray_samp" type="int">1</ray_samp>
|
||||
<ray_sampy sid="ray_sampy" type="int">1</ray_sampy>
|
||||
<ray_sampz sid="ray_sampz" type="int">1</ray_sampz>
|
||||
<ray_samp_type sid="ray_samp_type" type="int">0</ray_samp_type>
|
||||
<area_shape sid="area_shape" type="int">1</area_shape>
|
||||
<area_size sid="area_size" type="float">0.1</area_size>
|
||||
<area_sizey sid="area_sizey" type="float">0.1</area_sizey>
|
||||
<area_sizez sid="area_sizez" type="float">1</area_sizez>
|
||||
<adapt_thresh sid="adapt_thresh" type="float">9.99987e-4</adapt_thresh>
|
||||
<ray_samp_method sid="ray_samp_method" type="int">1</ray_samp_method>
|
||||
<shadhalostep sid="shadhalostep" type="int">0</shadhalostep>
|
||||
<sun_effect_type sid="sun_effect_type" type="int">0</sun_effect_type>
|
||||
<skyblendtype sid="skyblendtype" type="int">1</skyblendtype>
|
||||
<horizon_brightness sid="horizon_brightness" type="float">1</horizon_brightness>
|
||||
<spread sid="spread" type="float">1</spread>
|
||||
<sun_brightness sid="sun_brightness" type="float">1</sun_brightness>
|
||||
<sun_size sid="sun_size" type="float">1</sun_size>
|
||||
<backscattered_light sid="backscattered_light" type="float">1</backscattered_light>
|
||||
<sun_intensity sid="sun_intensity" type="float">1</sun_intensity>
|
||||
<atm_turbidity sid="atm_turbidity" type="float">2</atm_turbidity>
|
||||
<atm_extinction_factor sid="atm_extinction_factor" type="float">1</atm_extinction_factor>
|
||||
<atm_distance_factor sid="atm_distance_factor" type="float">1</atm_distance_factor>
|
||||
<skyblendfac sid="skyblendfac" type="float">1</skyblendfac>
|
||||
<sky_exposure sid="sky_exposure" type="float">1</sky_exposure>
|
||||
<sky_colorspace sid="sky_colorspace" type="int">0</sky_colorspace>
|
||||
</technique>
|
||||
</extra>
|
||||
</light>
|
||||
</library_lights>
|
||||
<library_images/>
|
||||
<library_effects>
|
||||
<effect id="Material_004-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.8 0 0 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.125 0.125 0.125 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
<effect id="Material_002-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0 0 0.8 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.125 0.125 0.125 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
</library_effects>
|
||||
<library_materials>
|
||||
<material id="Material_004-material" name="Material_004">
|
||||
<instance_effect url="#Material_004-effect"/>
|
||||
</material>
|
||||
<material id="Material_002-material" name="Material_002">
|
||||
<instance_effect url="#Material_002-effect"/>
|
||||
</material>
|
||||
</library_materials>
|
||||
<library_geometries>
|
||||
<geometry id="Cone_003-mesh" name="Cone.003">
|
||||
<mesh>
|
||||
<source id="Cone_003-mesh-positions">
|
||||
<float_array id="Cone_003-mesh-positions-array" count="198">0 -0.6151299 -0.05701982 -1.77995e-7 -1.7983e-7 -2.05702 0.1200059 -0.6033104 -0.05701982 0.2354 -0.5683059 -0.05701982 0.3417478 -0.5114619 -0.05701982 0.4349624 -0.4349625 -0.05701982 0.5114617 -0.3417478 -0.05701982 0.5683057 -0.2354 -0.05701982 0.6033101 -0.120006 -0.05701988 0.6151297 -1.61108e-7 -0.05701988 0.6033102 0.1200057 -0.05701988 0.5683057 0.2353997 -0.05701988 0.5114617 0.3417476 -0.05701988 0.4349624 0.4349623 -0.05701988 0.3417478 0.5114615 -0.05701988 0.2353999 0.5683056 -0.05701988 0.1200057 0.60331 -0.05701988 -1.59668e-7 0.6151295 -0.05701988 -0.120006 0.6033099 -0.05701988 -0.2354001 0.5683054 -0.05701982 -0.341748 0.5114613 -0.05701982 -0.4349626 0.434962 -0.05701982 -0.5114619 0.3417473 -0.05701982 -0.568306 0.2353994 -0.05701982 -0.6033103 0.1200052 -0.05701982 -0.6151297 -7.08636e-7 -0.05701982 -0.6033101 -0.1200066 -0.05701977 -0.5683055 -0.2354007 -0.05701977 -0.5114613 -0.3417485 -0.05701977 -0.4349618 -0.4349631 -0.05701977 -0.341747 -0.5114623 -0.05701977 -0.235399 -0.5683063 -0.05701977 -0.1200048 -0.6033105 -0.05701977 0 0.6151295 -0.06060606 0 -2.89444e-7 1.939394 0.1200058 0.60331 -0.06060606 0.2353999 0.5683056 -0.06060606 0.3417478 0.5114615 -0.06060606 0.4349623 0.4349622 -0.06060606 0.5114616 0.3417475 -0.06060606 0.5683057 0.2353997 -0.06060606 0.6033101 0.1200057 -0.06060606 0.6151297 -1.40432e-7 -0.06060606 0.6033102 -0.1200059 -0.06060606 0.5683057 -0.2354 -0.06060606 0.5114616 -0.3417478 -0.06060606 0.4349623 -0.4349626 -0.06060606 0.3417477 -0.5114619 -0.06060606 0.2353998 -0.568306 -0.06060606 0.1200056 -0.6033104 -0.06060606 -2.4745e-7 -0.6151298 -0.06060606 -0.1200062 -0.6033103 -0.06060606 -0.2354003 -0.5683058 -0.06060606 -0.3417481 -0.5114617 -0.06060606 -0.4349627 -0.4349622 -0.06060606 -0.511462 -0.3417476 -0.06060606 -0.568306 -0.2353997 -0.06060606 -0.6033104 -0.1200055 -0.06060606 -0.6151298 4.10911e-7 -0.06060606 -0.6033101 0.1200063 -0.06060606 -0.5683056 0.2354003 -0.06060606 -0.5114613 0.3417482 -0.06060606 -0.4349619 0.4349627 -0.06060606 -0.3417471 0.511462 -0.06060606 -0.2353991 0.5683059 -0.06060606 -0.120005 0.6033102 -0.06060606</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Cone_003-mesh-positions-array" count="66" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="Cone_003-mesh-normals">
|
||||
<float_array id="Cone_003-mesh-normals-array" count="198">0 0.8207646 -0.5712665 0 0 1 0.1601035 0.8050041 -0.5712578 0.3140783 0.7582927 -0.5712679 0.4559909 0.6824451 -0.5712627 0.5803661 0.5803661 -0.5712711 0.6824451 0.4559909 -0.5712627 0.7582927 0.3140783 -0.5712679 0.8050041 0.1601035 -0.5712578 0.8207646 0 -0.5712665 0.8050041 -0.1601035 -0.5712578 0.7582927 -0.3140783 -0.5712679 0.6824451 -0.4559909 -0.5712627 0.5803661 -0.5803661 -0.5712711 0.4559909 -0.6824451 -0.5712627 0.3140783 -0.7582927 -0.5712679 0.1601035 -0.8050041 -0.5712578 0 -0.8207646 -0.5712665 -0.1601035 -0.8050041 -0.5712578 -0.3140783 -0.7582927 -0.5712679 -0.4559909 -0.6824451 -0.5712627 -0.5803661 -0.5803661 -0.5712711 -0.6824451 -0.4559909 -0.5712627 -0.7582927 -0.3140783 -0.5712679 -0.8050041 -0.1601035 -0.5712578 -0.8207646 0 -0.5712665 -0.8050041 0.1601035 -0.5712578 -0.7582927 0.3140783 -0.5712679 -0.6824451 0.4559909 -0.5712627 -0.5803661 0.5803661 -0.5712711 -0.4559909 0.6824451 -0.5712627 -0.3140783 0.7582927 -0.5712679 -0.1601035 0.8050041 -0.5712578 0 -0.8207646 0.5712665 0 0 -1 0.1601035 -0.8050041 0.5712578 0.3140783 -0.7582927 0.5712679 0.4559909 -0.6824451 0.5712627 0.5803661 -0.5803661 0.5712711 0.6824451 -0.4559909 0.5712627 0.7582927 -0.3140783 0.5712679 0.8050041 -0.1601035 0.5712578 0.8207646 0 0.5712665 0.8050041 0.1601035 0.5712578 0.7582927 0.3140783 0.5712679 0.6824451 0.4559909 0.5712627 0.5803661 0.5803661 0.5712711 0.4559909 0.6824451 0.5712627 0.3140783 0.7582927 0.5712679 0.1601035 0.8050041 0.5712578 0 0.8207646 0.5712665 -0.1601035 0.8050041 0.5712578 -0.3140783 0.7582927 0.5712679 -0.4559909 0.6824451 0.5712627 -0.5803661 0.5803661 0.5712711 -0.6824451 0.4559909 0.5712627 -0.7582927 0.3140783 0.5712679 -0.8050041 0.1601035 0.5712578 -0.8207646 0 0.5712665 -0.8050041 -0.1601035 0.5712578 -0.7582927 -0.3140783 0.5712679 -0.6824451 -0.4559909 0.5712627 -0.5803661 -0.5803661 0.5712711 -0.4559909 -0.6824451 0.5712627 -0.3140783 -0.7582927 0.5712679 -0.1601035 -0.8050041 0.5712578</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Cone_003-mesh-normals-array" count="66" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<vertices id="Cone_003-mesh-vertices">
|
||||
<input semantic="POSITION" source="#Cone_003-mesh-positions"/>
|
||||
</vertices>
|
||||
<triangles material="Material_004-material" count="62">
|
||||
<input semantic="VERTEX" source="#Cone_003-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Cone_003-mesh-normals" offset="1"/>
|
||||
<p>33 0 34 1 35 2 35 2 34 1 36 3 36 3 34 1 37 4 37 4 34 1 38 5 38 5 34 1 39 6 39 6 34 1 40 7 40 7 34 1 41 8 41 8 34 1 42 9 42 9 34 1 43 10 43 10 34 1 44 11 44 11 34 1 45 12 45 12 34 1 46 13 46 13 34 1 47 14 47 14 34 1 48 15 48 15 34 1 49 16 49 16 34 1 50 17 50 17 34 1 51 18 51 18 34 1 52 19 52 19 34 1 53 20 53 20 34 1 54 21 54 21 34 1 55 22 55 22 34 1 56 23 56 23 34 1 57 24 57 24 34 1 58 25 58 25 34 1 59 26 59 26 34 1 60 27 60 27 34 1 61 28 61 28 34 1 62 29 62 29 34 1 63 30 63 30 34 1 64 31 64 31 34 1 65 32 65 32 34 1 33 0 49 16 57 24 65 32 65 32 33 0 35 2 35 2 36 3 65 32 37 4 38 5 39 6 39 6 40 7 41 8 41 8 42 9 43 10 43 10 44 11 41 8 45 12 46 13 47 14 47 14 48 15 45 12 49 16 50 17 53 20 51 18 52 19 53 20 53 20 54 21 57 24 55 22 56 23 57 24 57 24 58 25 59 26 59 26 60 27 61 28 61 28 62 29 65 32 63 30 64 31 65 32 65 32 36 3 37 4 37 4 39 6 41 8 41 8 44 11 45 12 45 12 48 15 49 16 50 17 51 18 53 20 54 21 55 22 57 24 57 24 59 26 65 32 62 29 63 30 65 32 65 32 37 4 41 8 41 8 45 12 65 32 49 16 53 20 57 24 59 26 61 28 65 32 65 32 45 12 49 16</p>
|
||||
</triangles>
|
||||
<triangles material="Material_002-material" count="62">
|
||||
<input semantic="VERTEX" source="#Cone_003-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Cone_003-mesh-normals" offset="1"/>
|
||||
<p>0 33 1 34 2 35 2 35 1 34 3 36 3 36 1 34 4 37 4 37 1 34 5 38 5 38 1 34 6 39 6 39 1 34 7 40 7 40 1 34 8 41 8 41 1 34 9 42 9 42 1 34 10 43 10 43 1 34 11 44 11 44 1 34 12 45 12 45 1 34 13 46 13 46 1 34 14 47 14 47 1 34 15 48 15 48 1 34 16 49 16 49 1 34 17 50 17 50 1 34 18 51 18 51 1 34 19 52 19 52 1 34 20 53 20 53 1 34 21 54 21 54 1 34 22 55 22 55 1 34 23 56 23 56 1 34 24 57 24 57 1 34 25 58 25 58 1 34 26 59 26 59 1 34 27 60 27 60 1 34 28 61 28 61 1 34 29 62 29 62 1 34 30 63 30 63 1 34 31 64 31 64 1 34 32 65 32 65 1 34 0 33 16 49 24 57 8 41 32 65 0 33 2 35 2 35 3 36 4 37 4 37 5 38 8 41 6 39 7 40 8 41 8 41 9 42 10 43 10 43 11 44 8 41 12 45 13 46 14 47 14 47 15 48 16 49 16 49 17 50 20 53 18 51 19 52 20 53 20 53 21 54 22 55 22 55 23 56 24 57 24 57 25 58 26 59 26 59 27 60 24 57 28 61 29 62 32 65 30 63 31 64 32 65 32 65 2 35 8 41 5 38 6 39 8 41 8 41 11 44 12 45 12 45 14 47 16 49 17 50 18 51 20 53 20 53 22 55 24 57 24 57 27 60 28 61 29 62 30 63 32 65 2 35 4 37 8 41 8 41 12 45 16 49 16 49 20 53 24 57 24 57 28 61 32 65 32 65 8 41 24 57</p>
|
||||
</triangles>
|
||||
</mesh>
|
||||
</geometry>
|
||||
</library_geometries>
|
||||
<library_controllers/>
|
||||
<library_visual_scenes>
|
||||
<visual_scene id="Scene" name="Scene">
|
||||
<node id="Camera" name="Camera" type="NODE">
|
||||
<matrix sid="transform">0.6859207 -0.3240135 0.6515582 7.481132 0.7276763 0.3054208 -0.6141704 -6.50764 0 0.8953956 0.4452714 5.343665 0 0 0 1</matrix>
|
||||
<instance_camera url="#Camera-camera"/>
|
||||
</node>
|
||||
<node id="Lamp" name="Lamp" type="NODE">
|
||||
<matrix sid="transform">-0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1</matrix>
|
||||
<instance_light url="#Lamp-light"/>
|
||||
</node>
|
||||
<node id="Camera_001" name="Camera_001" type="NODE">
|
||||
<matrix sid="transform">1.371841 -0.648027 1.303116 10.0091 1.455353 0.6108412 -1.228341 -10.6572 3.76898e-7 1.790791 0.8905425 5.77815 0 0 0 1</matrix>
|
||||
<instance_camera url="#Camera_001-camera"/>
|
||||
</node>
|
||||
<node id="Lamp_001" name="Lamp_001" type="NODE">
|
||||
<matrix sid="transform">-0.5817292 -1.542202 1.132786 3.199329 1.910342 -0.3997671 0.4367821 4.368987 -0.1103777 1.209049 1.589345 6.898543 0 0 0 1</matrix>
|
||||
<instance_light url="#Lamp_001-light"/>
|
||||
</node>
|
||||
<node id="Cone_000" name="Cone_000" type="NODE">
|
||||
<matrix sid="transform">0.1515022 -3.01129e-7 -1.994254 0.004837528 -3.54228e-13 -2 3.01996e-7 -0.04310748 -1.994254 -2.28762e-8 -0.1515022 -0.001579307 0 0 0 1</matrix>
|
||||
<instance_geometry url="#Cone_003-mesh" name="Cone_000">
|
||||
<bind_material>
|
||||
<technique_common>
|
||||
<instance_material symbol="Material_004-material" target="#Material_004-material"/>
|
||||
<instance_material symbol="Material_002-material" target="#Material_002-material"/>
|
||||
</technique_common>
|
||||
</bind_material>
|
||||
</instance_geometry>
|
||||
</node>
|
||||
<node id="Lamp_001" name="Lamp_001" type="NODE">
|
||||
<matrix sid="transform">-0.5817294 -1.542202 1.132787 3.199328 1.910342 -0.3997668 0.4367828 4.368987 -0.1103783 1.209049 1.589345 6.898543 0 0 0 1</matrix>
|
||||
<instance_light url="#Lamp_001-light"/>
|
||||
</node>
|
||||
<node id="Camera_001" name="Camera_001" type="NODE">
|
||||
<matrix sid="transform">1.371841 -0.648027 1.303116 10.0091 1.455353 0.6108412 -1.228341 -10.6572 3.76898e-7 1.790791 0.8905425 5.77815 0 0 0 1</matrix>
|
||||
<instance_camera url="#Camera_001-camera"/>
|
||||
</node>
|
||||
<node id="Camera_001_001" name="Camera_001_001" type="NODE">
|
||||
<matrix sid="transform">1.371841 -0.648027 1.303116 10.0091 1.455353 0.6108412 -1.228341 -10.6572 3.76898e-7 1.790791 0.8905425 5.77815 0 0 0 1</matrix>
|
||||
<instance_camera url="#Camera_001_001-camera"/>
|
||||
</node>
|
||||
<node id="Lamp_001_001" name="Lamp_001_001" type="NODE">
|
||||
<matrix sid="transform">-0.5817294 -1.542202 1.132787 3.199328 1.910342 -0.3997668 0.4367828 4.368987 -0.1103783 1.209049 1.589345 6.898543 0 0 0 1</matrix>
|
||||
<instance_light url="#Lamp_001_001-light"/>
|
||||
</node>
|
||||
</visual_scene>
|
||||
</library_visual_scenes>
|
||||
<scene>
|
||||
<instance_visual_scene url="#Scene"/>
|
||||
</scene>
|
||||
</COLLADA>
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
File diff suppressed because one or more lines are too long
@@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<GridPane fx:id="finishScreenGridPane" maxHeight="837.0" maxWidth="837.0" minHeight="837.0" minWidth="837.0" nodeOrientation="LEFT_TO_RIGHT" prefHeight="837.0" prefWidth="837.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.FinishScreenViewController">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="259.0" minHeight="259.0" prefHeight="259.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="64.0" minHeight="64.0" prefHeight="64.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="257.0" minHeight="257.0" prefHeight="257.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="257.0" minHeight="257.0" prefHeight="257.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label alignment="CENTER" text="Race Finished!" textFill="WHITE" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||
<font>
|
||||
<Font size="40.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label alignment="CENTER" text="Race Result:" textFill="WHITE" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<font>
|
||||
<Font size="28.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<TableView fx:id="finishOrderTable" maxWidth="661.0" prefHeight="324.0" prefWidth="629.0" styleClass="ui-table" GridPane.halignment="CENTER" GridPane.rowIndex="2">
|
||||
<columns>
|
||||
<TableColumn fx:id="posCol" editable="false" maxWidth="74.0" minWidth="74.0" prefWidth="74.0" resizable="false" sortable="false" text="Position" />
|
||||
<TableColumn fx:id="boatNameCol" editable="false" maxWidth="171.0" minWidth="171.0" prefWidth="171.0" resizable="false" sortable="false" text="Boat Name" />
|
||||
<TableColumn fx:id="shortNameCol" editable="false" maxWidth="155.18472290039062" minWidth="107.0" prefWidth="155.18472290039062" resizable="false" sortable="false" text="Short Name" />
|
||||
<TableColumn fx:id="countryCol" editable="false" maxWidth="258.9999694824219" minWidth="147.0" prefWidth="258.9999694824219" resizable="false" sortable="false" text="Country" />
|
||||
</columns>
|
||||
<GridPane.margin>
|
||||
<Insets bottom="50.0" />
|
||||
</GridPane.margin>
|
||||
</TableView>
|
||||
<Button mnemonicParsing="false" onAction="#switchToStartScreenView" onMouseEntered="#playButtonHoverSound" styleClass="blue-ui-btn" text="Return to Start Screen" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="TOP" />
|
||||
</children>
|
||||
</GridPane>
|
||||
@@ -1,25 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.net.*?>
|
||||
<?import javafx.scene.*?>
|
||||
<?import com.jfoenix.controls.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import java.net.*?>
|
||||
<?import com.jfoenix.controls.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import java.lang.String?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<StackPane fx:id="serverListMainStackPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.LobbyController">
|
||||
<children>
|
||||
@@ -66,6 +53,11 @@
|
||||
<GridPane.margin>
|
||||
<Insets right="20.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<Label fx:id="portNumber" text="Port: 4191" GridPane.columnIndex="2" GridPane.halignment="RIGHT" GridPane.rowIndex="1">
|
||||
<GridPane.margin>
|
||||
<Insets right="20.0" top="-15.0" />
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
</children>
|
||||
<columnConstraints>
|
||||
@@ -80,12 +72,9 @@
|
||||
</GridPane>
|
||||
<GridPane GridPane.rowIndex="1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="NEVER" maxWidth="-Infinity" minWidth="-Infinity"
|
||||
prefWidth="115.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308"
|
||||
minWidth="337.0" prefWidth="430.0"/>
|
||||
<ColumnConstraints hgrow="NEVER" maxWidth="350.0" minWidth="350.0"
|
||||
prefWidth="350.0"/>
|
||||
<ColumnConstraints hgrow="NEVER" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="115.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="337.0" prefWidth="430.0" />
|
||||
<ColumnConstraints hgrow="NEVER" maxWidth="350.0" minWidth="350.0" prefWidth="350.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints vgrow="SOMETIMES" />
|
||||
@@ -110,116 +99,92 @@
|
||||
<Insets bottom="15.0" left="7.0" right="7.0" top="15.0" />
|
||||
</GridPane.margin>
|
||||
</AnchorPane>
|
||||
<GridPane prefHeight="370.0" prefWidth="189.0" styleClass="tokenGridView"
|
||||
vgap="5.0">
|
||||
<GridPane prefHeight="370.0" prefWidth="189.0" styleClass="tokenGridView" vgap="5.0">
|
||||
<children>
|
||||
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Tokens"
|
||||
GridPane.halignment="CENTER">
|
||||
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Tokens" GridPane.halignment="CENTER">
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0"/>
|
||||
<Font name="System Bold" size="18.0" />
|
||||
</font>
|
||||
</Text>
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0"
|
||||
GridPane.rowIndex="1">
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label alignment="BOTTOM_CENTER" text="Speed"
|
||||
StackPane.alignment="BOTTOM_CENTER">
|
||||
<Label alignment="BOTTOM_CENTER" text="Speed" StackPane.alignment="BOTTOM_CENTER">
|
||||
<font>
|
||||
<Font size="12.0"/>
|
||||
<Font size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="5.0"/>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Pane fx:id="speedTokenPane" prefHeight="999.0"
|
||||
prefWidth="200.0" styleClass="tokenView"/>
|
||||
<Pane fx:id="speedTokenPane" prefHeight="999.0" prefWidth="200.0" styleClass="tokenView" />
|
||||
</children>
|
||||
</StackPane>
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0"
|
||||
GridPane.rowIndex="2">
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label alignment="BOTTOM_CENTER" text="Handling"
|
||||
StackPane.alignment="BOTTOM_CENTER">
|
||||
<Label alignment="BOTTOM_CENTER" text="Handling" StackPane.alignment="BOTTOM_CENTER">
|
||||
<font>
|
||||
<Font size="12.0"/>
|
||||
<Font size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="5.0"/>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Pane fx:id="handlingTokenPane" prefHeight="999.0"
|
||||
prefWidth="200.0" styleClass="tokenView"/>
|
||||
<Pane fx:id="handlingTokenPane" prefHeight="999.0" prefWidth="200.0" styleClass="tokenView" />
|
||||
</children>
|
||||
</StackPane>
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0"
|
||||
GridPane.rowIndex="3">
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label alignment="BOTTOM_CENTER" text="Wind Walker"
|
||||
StackPane.alignment="BOTTOM_CENTER">
|
||||
<Label alignment="BOTTOM_CENTER" text="Wind Walker" StackPane.alignment="BOTTOM_CENTER">
|
||||
<font>
|
||||
<Font size="12.0"/>
|
||||
<Font size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="5.0"/>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Pane fx:id="windWalkerTokenPane" prefHeight="999.0"
|
||||
prefWidth="200.0" styleClass="tokenView"/>
|
||||
<Pane fx:id="windWalkerTokenPane" prefHeight="999.0" prefWidth="200.0" styleClass="tokenView" />
|
||||
</children>
|
||||
</StackPane>
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0"
|
||||
GridPane.rowIndex="4">
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Label alignment="BOTTOM_CENTER" text="Bumper"
|
||||
StackPane.alignment="BOTTOM_CENTER">
|
||||
<Label alignment="BOTTOM_CENTER" text="Bumper" StackPane.alignment="BOTTOM_CENTER">
|
||||
<font>
|
||||
<Font size="12.0"/>
|
||||
<Font size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="5.0"/>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Pane fx:id="bumperTokenPane" prefHeight="999.0"
|
||||
prefWidth="200.0" styleClass="tokenView"/>
|
||||
<Pane fx:id="bumperTokenPane" prefHeight="999.0" prefWidth="200.0" styleClass="tokenView" />
|
||||
</children>
|
||||
</StackPane>
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0"
|
||||
GridPane.rowIndex="5">
|
||||
<StackPane prefHeight="150.0" prefWidth="200.0" GridPane.rowIndex="5">
|
||||
<children>
|
||||
<Label alignment="BOTTOM_CENTER" text="Random"
|
||||
StackPane.alignment="BOTTOM_CENTER">
|
||||
<Label alignment="BOTTOM_CENTER" text="Random" StackPane.alignment="BOTTOM_CENTER">
|
||||
<font>
|
||||
<Font size="12.0"/>
|
||||
<Font size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="5.0"/>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Pane fx:id="randomTokenPane" prefHeight="999.0"
|
||||
prefWidth="60.0" styleClass="tokenView"/>
|
||||
<Pane fx:id="randomTokenPane" prefHeight="999.0" prefWidth="60.0" styleClass="tokenView" />
|
||||
</children>
|
||||
</StackPane>
|
||||
</children>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="80.0" minWidth="80.0"
|
||||
prefWidth="80.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="80.0" minWidth="80.0" prefWidth="80.0" />
|
||||
</columnConstraints>
|
||||
<padding>
|
||||
<Insets bottom="15.0" left="15.0" right="7.0" top="15.0"/>
|
||||
<Insets bottom="15.0" left="15.0" right="7.0" top="15.0" />
|
||||
</padding>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="116.0" minHeight="0.0" prefHeight="40.0"
|
||||
vgrow="NEVER"/>
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity"
|
||||
prefHeight="60.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity"
|
||||
prefHeight="60.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="141.0" minHeight="-Infinity"
|
||||
prefHeight="60.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity"
|
||||
prefHeight="60.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity"
|
||||
prefHeight="60.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="116.0" minHeight="0.0" prefHeight="40.0" vgrow="NEVER" />
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="141.0" minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="285.0" minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
</GridPane>
|
||||
</children>
|
||||
@@ -236,7 +201,7 @@
|
||||
</GridPane>
|
||||
</children>
|
||||
<stylesheets>
|
||||
<URL value="@../css/Master.css"/>
|
||||
<URL value="@../css/LobbyView.css"/>
|
||||
<URL value="@../css/Master.css" />
|
||||
<URL value="@../css/LobbyView.css" />
|
||||
</stylesheets>
|
||||
</StackPane>
|
||||
|
||||
@@ -2,316 +2,325 @@
|
||||
|
||||
<?import com.jfoenix.controls.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import java.net.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.image.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXSpinner?>
|
||||
<?import com.jfoenix.controls.JFXTextField?>
|
||||
<?import java.lang.String?>
|
||||
<?import java.net.URL?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.image.Image?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<StackPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1200.0" style="-fx-background-color: skyblue;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.RaceViewController">
|
||||
<children>
|
||||
<StackPane fx:id="contentStackPane" maxHeight="1.7976931348623157E308"
|
||||
maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0"
|
||||
prefWidth="1200.0" style="-fx-background-color: skyblue;" xmlns="http://javafx.com/javafx/8.0.111"
|
||||
xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
|
||||
prefHeight="800.0" prefWidth="1200.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="250.0" minWidth="250.0"
|
||||
prefWidth="250.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="400.0"
|
||||
prefWidth="400.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="70.0" minHeight="70.0" prefHeight="70.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="250.0" minHeight="250.0" prefHeight="250.0"
|
||||
valignment="BOTTOM" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<GridPane id="timerGrid" fx:id="timerGrid" prefWidth="192.0" styleClass="timer">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="50.0" minWidth="50.0"
|
||||
prefWidth="50.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="135.0" minWidth="135.0"
|
||||
prefWidth="135.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
</opaqueInsets>
|
||||
<GridPane.margin>
|
||||
<Insets left="10.0" right="200.0" top="10.0"/>
|
||||
</GridPane.margin>
|
||||
<children>
|
||||
<ImageView fitHeight="40.0" fitWidth="40.0" pickOnBounds="true"
|
||||
preserveRatio="true" GridPane.halignment="CENTER"
|
||||
GridPane.valignment="CENTER">
|
||||
<image>
|
||||
<Image url="@../images/timer.png"/>
|
||||
</image>
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin>
|
||||
</ImageView>
|
||||
<Label fx:id="timerLabel" text="00:03:34" GridPane.columnIndex="1"
|
||||
GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||
<font>
|
||||
<Font size="21.0"/>
|
||||
</font>
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</GridPane>
|
||||
<GridPane GridPane.columnIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
</GridPane>
|
||||
<GridPane fx:id="chatGridPane" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="390.0" minWidth="390.0"
|
||||
prefWidth="390.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Pane fx:id="chatHistoryHolder" prefHeight="200.0" prefWidth="200.0"
|
||||
GridPane.hgrow="ALWAYS" GridPane.valignment="BOTTOM"
|
||||
GridPane.vgrow="ALWAYS">
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
||||
</padding>
|
||||
</Pane>
|
||||
<GridPane fx:id="chatInputHolder" GridPane.rowIndex="1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity"
|
||||
minWidth="90.0" prefWidth="90.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0"
|
||||
valignment="CENTER" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<JFXButton fx:id="chatSend" alignment="CENTER" buttonType="RAISED"
|
||||
focusTraversable="false" maxHeight="-Infinity"
|
||||
maxWidth="1.7976931348623157E308" minHeight="-Infinity"
|
||||
minWidth="-Infinity" prefHeight="35.0" text="SEND"
|
||||
GridPane.columnIndex="1">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
||||
</GridPane.margin>
|
||||
</JFXButton>
|
||||
<JFXTextField fx:id="chatInput" focusTraversable="false"
|
||||
maxHeight="35.0" minHeight="-Infinity" prefHeight="35.0">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="20.0" right="10.0"/>
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets right="15.0"/>
|
||||
</padding>
|
||||
</JFXTextField>
|
||||
</children>
|
||||
<GridPane.margin>
|
||||
<Insets top="10.0"/>
|
||||
</GridPane.margin>
|
||||
</GridPane>
|
||||
</children>
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" right="10.0"/>
|
||||
</GridPane.margin>
|
||||
</GridPane>
|
||||
<GridPane fx:id="windGridPane" maxHeight="-Infinity" maxWidth="-Infinity"
|
||||
prefHeight="150.0" prefWidth="240.0" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="2" GridPane.valignment="BOTTOM">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="110.0" minWidth="110.0"
|
||||
prefWidth="110.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="132.0" minWidth="10.0"
|
||||
prefWidth="132.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="120.0" minHeight="120.0" prefHeight="120.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label fx:id="positionLabel" text="Position:" GridPane.columnIndex="1"
|
||||
GridPane.halignment="LEFT" GridPane.rowSpan="2" GridPane.valignment="TOP">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="boatSpeedLabel" text="Boat Speed:" GridPane.columnIndex="1"
|
||||
GridPane.halignment="LEFT" GridPane.rowSpan="2"
|
||||
GridPane.valignment="CENTER">
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
</opaqueInsets>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="boatHeadingLabel" text="Boat Heading:"
|
||||
GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowSpan="2"
|
||||
GridPane.valignment="BOTTOM">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<GridPane fx:id="windHolder" GridPane.rowSpan="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="120.0" minHeight="120.0"
|
||||
prefHeight="120.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<ImageView fx:id="windImageView" fitHeight="92.0" fitWidth="109.0"
|
||||
pickOnBounds="true" preserveRatio="true"
|
||||
GridPane.halignment="CENTER" GridPane.rowSpan="2"
|
||||
GridPane.valignment="CENTER"/>
|
||||
<Label fx:id="windSpeedLabel" text="0.0 Knots"
|
||||
GridPane.halignment="RIGHT" GridPane.rowIndex="1"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets right="5.0"/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<Label fx:id="windDirectionLabel" text="180.0°"
|
||||
GridPane.halignment="LEFT" GridPane.rowIndex="1"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets left="5.0"/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
</opaqueInsets>
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" top="40.0"/>
|
||||
</GridPane.margin>
|
||||
</GridPane>
|
||||
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="152.0" minHeight="10.0" prefHeight="152.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="118.0" minHeight="10.0" prefHeight="98.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<ImageView fx:id="velocityIcon" fitHeight="88.0" fitWidth="106.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.halignment="CENTER" GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/velocity.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="handlingIcon" fitHeight="87.0" fitWidth="98.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/handlingIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="windWalkerIcon" fitHeight="83.0" fitWidth="100.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="2" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/windWalkerIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="bumperIcon" fitHeight="83.0" fitWidth="88.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="3" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/bumperIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="badRandomIcon" fitHeight="69.0" fitWidth="103.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="4" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<image>
|
||||
<Image url="@../icons/slowedIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</StackPane>
|
||||
<Pane fx:id="miniMapPane" maxHeight="200.0" maxWidth="200.0" minHeight="200.0" minWidth="200.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white; -fx-opacity: 0.45; -fx-background-radius: 10;" StackPane.alignment="TOP_RIGHT">
|
||||
<StackPane.margin>
|
||||
<Insets right="15.0" top="15.0" />
|
||||
</StackPane.margin>
|
||||
</Pane>
|
||||
<JFXButton fx:id="miniMapButton" style="-fx-background-color: white; -fx-opacity: 0.45; -fx-background-radius: 10;" text="✕" StackPane.alignment="TOP_RIGHT">
|
||||
<font>
|
||||
<Font size="15.0" />
|
||||
</font>
|
||||
<StackPane.margin>
|
||||
<Insets right="15.0" top="15.0" />
|
||||
</StackPane.margin>
|
||||
</JFXButton>
|
||||
<AnchorPane fx:id="loadingScreenPane">
|
||||
<children>
|
||||
<StackPane fx:id="contentStackPane" maxHeight="1.7976931348623157E308"
|
||||
maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0"
|
||||
prefWidth="1200.0" style="-fx-background-color: skyblue;" xmlns="http://javafx.com/javafx/8.0.111"
|
||||
xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
|
||||
prefHeight="800.0" prefWidth="1200.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="250.0" minWidth="250.0"
|
||||
prefWidth="250.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="400.0"
|
||||
prefWidth="400.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="70.0" minHeight="70.0" prefHeight="70.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="250.0" minHeight="250.0" prefHeight="250.0"
|
||||
valignment="BOTTOM" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<GridPane id="timerGrid" fx:id="timerGrid" prefWidth="192.0" styleClass="timer">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="50.0" minWidth="50.0"
|
||||
prefWidth="50.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="135.0" minWidth="135.0"
|
||||
prefWidth="135.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
</opaqueInsets>
|
||||
<GridPane.margin>
|
||||
<Insets left="10.0" right="200.0" top="10.0"/>
|
||||
</GridPane.margin>
|
||||
<children>
|
||||
<ImageView fitHeight="40.0" fitWidth="40.0" pickOnBounds="true"
|
||||
preserveRatio="true" GridPane.halignment="CENTER"
|
||||
GridPane.valignment="CENTER">
|
||||
<image>
|
||||
<Image url="@../images/timer.png"/>
|
||||
</image>
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin>
|
||||
</ImageView>
|
||||
<Label fx:id="timerLabel" text="00:03:34" GridPane.columnIndex="1"
|
||||
GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||
<font>
|
||||
<Font size="21.0"/>
|
||||
</font>
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</GridPane>
|
||||
<GridPane GridPane.columnIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
</GridPane>
|
||||
<GridPane fx:id="chatGridPane" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="390.0" minWidth="390.0"
|
||||
prefWidth="390.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Pane fx:id="chatHistoryHolder" prefHeight="200.0" prefWidth="200.0"
|
||||
GridPane.hgrow="ALWAYS" GridPane.valignment="BOTTOM"
|
||||
GridPane.vgrow="ALWAYS">
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
||||
</padding>
|
||||
</Pane>
|
||||
<GridPane fx:id="chatInputHolder" GridPane.rowIndex="1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity"
|
||||
minWidth="90.0" prefWidth="90.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0"
|
||||
valignment="CENTER" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<JFXButton fx:id="chatSend" alignment="CENTER" buttonType="RAISED"
|
||||
focusTraversable="false" maxHeight="-Infinity"
|
||||
maxWidth="1.7976931348623157E308" minHeight="-Infinity"
|
||||
minWidth="-Infinity" prefHeight="35.0" text="SEND"
|
||||
GridPane.columnIndex="1">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
||||
</GridPane.margin>
|
||||
</JFXButton>
|
||||
<JFXTextField fx:id="chatInput" focusTraversable="false"
|
||||
maxHeight="35.0" minHeight="-Infinity" prefHeight="35.0">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="20.0" right="10.0"/>
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets right="15.0"/>
|
||||
</padding>
|
||||
</JFXTextField>
|
||||
</children>
|
||||
<GridPane.margin>
|
||||
<Insets top="10.0"/>
|
||||
</GridPane.margin>
|
||||
</GridPane>
|
||||
</children>
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" right="10.0"/>
|
||||
</GridPane.margin>
|
||||
</GridPane>
|
||||
<GridPane fx:id="windGridPane" maxHeight="-Infinity" maxWidth="-Infinity"
|
||||
prefHeight="150.0" prefWidth="240.0" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="2" GridPane.valignment="BOTTOM">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="110.0" minWidth="110.0"
|
||||
prefWidth="110.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="132.0" minWidth="10.0"
|
||||
prefWidth="132.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="120.0" minHeight="120.0" prefHeight="120.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label fx:id="positionLabel" text="Position:" GridPane.columnIndex="1"
|
||||
GridPane.halignment="LEFT" GridPane.rowSpan="2" GridPane.valignment="TOP">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="boatSpeedLabel" text="Boat Speed:" GridPane.columnIndex="1"
|
||||
GridPane.halignment="LEFT" GridPane.rowSpan="2"
|
||||
GridPane.valignment="CENTER">
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
</opaqueInsets>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="boatHeadingLabel" text="Boat Heading:"
|
||||
GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowSpan="2"
|
||||
GridPane.valignment="BOTTOM">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<GridPane fx:id="windHolder" GridPane.rowSpan="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="120.0" minHeight="120.0"
|
||||
prefHeight="120.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label fx:id="windSpeedLabel" text="0.0 Knots"
|
||||
GridPane.halignment="RIGHT" GridPane.rowIndex="1"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets right="5.0"/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<Label fx:id="windDirectionLabel" text="180.0°"
|
||||
GridPane.halignment="LEFT" GridPane.rowIndex="1"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets left="5.0"/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<VBox fx:id="windArrowVBox" prefHeight="200.0" prefWidth="100.0"/>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
</opaqueInsets>
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" top="40.0"/>
|
||||
</GridPane.margin>
|
||||
</GridPane>
|
||||
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="152.0" minHeight="10.0" prefHeight="152.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="118.0" minHeight="10.0" prefHeight="98.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<ImageView fx:id="velocityIcon" fitHeight="88.0" fitWidth="106.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.halignment="CENTER" GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/velocity.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="handlingIcon" fitHeight="87.0" fitWidth="98.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/handlingIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="windWalkerIcon" fitHeight="83.0" fitWidth="100.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="2" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/windWalkerIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="bumperIcon" fitHeight="83.0" fitWidth="88.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="3" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/bumperIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="badRandomIcon" fitHeight="69.0" fitWidth="103.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="4" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<image>
|
||||
<Image url="@../icons/slowedIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</StackPane>
|
||||
<Pane fx:id="miniMapPane" maxHeight="200.0" maxWidth="200.0" minHeight="200.0" minWidth="200.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white; -fx-opacity: 0.45; -fx-background-radius: 10;" StackPane.alignment="TOP_RIGHT">
|
||||
<StackPane.margin>
|
||||
<Insets right="15.0" top="15.0" />
|
||||
</StackPane.margin>
|
||||
</Pane>
|
||||
<JFXButton fx:id="miniMapButton" text="—" StackPane.alignment="TOP_RIGHT">
|
||||
<font>
|
||||
<Font size="15.0" />
|
||||
</font>
|
||||
<StackPane.margin>
|
||||
<Insets right="15.0" top="15.0" />
|
||||
</StackPane.margin>
|
||||
</JFXButton>
|
||||
<AnchorPane fx:id="loadingScreenPane">
|
||||
<ImageView fx:id="loadingScreen" fitHeight="672.0" fitWidth="1200.0" pickOnBounds="true" preserveRatio="true" />
|
||||
<JFXSpinner layoutX="566.0" layoutY="692.0" radius="30.0" />
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<JFXButton fx:id="chatToggleButton" text="—" StackPane.alignment="BOTTOM_RIGHT">
|
||||
<font>
|
||||
<Font size="15.0"/>
|
||||
</font>
|
||||
<StackPane.margin>
|
||||
<Insets bottom="70.0" right="10.0"/>
|
||||
</StackPane.margin>
|
||||
</JFXButton>
|
||||
</children>
|
||||
<stylesheets>
|
||||
<String fx:value="/css/Master.css" />
|
||||
<String fx:value="/css/RaceView.css" />
|
||||
<URL value="@../css/Master.css"/>
|
||||
<URL value="@../css/RaceView.css"/>
|
||||
</stylesheets>
|
||||
</StackPane>
|
||||
|
||||
@@ -6,18 +6,7 @@
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXTextField?>
|
||||
<?import java.lang.String?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
|
||||
<StackPane fx:id="serverListMainStackPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.ServerListController">
|
||||
<children>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<Pane fx:id="windPane" prefHeight="120.0" prefWidth="110.0"
|
||||
stylesheets="@../../css/cells/WindCell.css" xmlns="http://javafx.com/javafx/8"
|
||||
xmlns:fx="http://javafx.com/fxml/1"/>
|
||||
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.String?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<AnchorPane fx:id="annotationSelectWindow" maxHeight="270.0" maxWidth="469.0" minHeight="270.0" minWidth="469.0" prefHeight="270.0" prefWidth="469.0" styleClass="background-blue" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Text fill="WHITE" layoutX="26.0" layoutY="52.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Select important annotations">
|
||||
<font>
|
||||
<Font size="24.0" />
|
||||
</font>
|
||||
</Text>
|
||||
<CheckBox fx:id="boatWakeSelect" layoutX="26.0" layoutY="80.0" mnemonicParsing="false" style="-fx-border-width: 0; -fx-background-insets: 0;" text="Boat Wakes" textFill="#e7e7e7" />
|
||||
<CheckBox fx:id="boatSpeedSelect" layoutX="26.0" layoutY="111.0" mnemonicParsing="false" text="Boat Speed" textFill="#e7e7e7" />
|
||||
<CheckBox fx:id="boatTrackSelect" layoutX="26.0" layoutY="142.0" mnemonicParsing="false" text="Boat Tracks" textFill="#e7e7e7" />
|
||||
<CheckBox fx:id="boatNameSelect" layoutX="26.0" layoutY="173.0" mnemonicParsing="false" text="Boat Name" textFill="#e7e7e7" />
|
||||
<CheckBox fx:id="boatEstTimeToNextMarkSelect" layoutX="26.0" layoutY="204.0" mnemonicParsing="false" text="Boat Estimated Time To Next Mark" textFill="#e7e7e7" />
|
||||
<Button fx:id="closeButton" layoutX="424.0" layoutY="-1.0" mnemonicParsing="false" prefHeight="11.0" prefWidth="49.0" style=": 0;" text="X" textFill="#ffffff4e">
|
||||
<font>
|
||||
<Font size="24.0" />
|
||||
</font>
|
||||
<styleClass>
|
||||
<String fx:value="background-blue" />
|
||||
<String fx:value="clearExitButton" />
|
||||
</styleClass>
|
||||
</Button>
|
||||
<CheckBox fx:id="boatElapsedTimeSelect" layoutX="26.0" layoutY="235.0" mnemonicParsing="false" text="Boat Elapsed Time Since Last Mark" textFill="#e7e7e7" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
@@ -48,9 +48,10 @@ public class ServerTableTest {
|
||||
|
||||
serverTable.addServer(listing);
|
||||
|
||||
listing.decrementTtl();
|
||||
listing.decrementTtl();
|
||||
|
||||
Thread.sleep(1000);
|
||||
Thread.sleep(1500);
|
||||
|
||||
assertTrue(!serverTable.getAllServers().contains(listing));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package seng302.utilities;
|
||||
|
||||
/**
|
||||
* Created by cir27 on 28/09/17.
|
||||
*/
|
||||
public class MapMakerTest {
|
||||
// @Test
|
||||
|
||||
}
|
||||
@@ -12,7 +12,7 @@ public class DisconnectionTest {
|
||||
@Test
|
||||
public void testServerDisconnection () throws Exception {
|
||||
MainServerThread serverThread = new MainServerThread();
|
||||
ClientToServerThread clientThread = new ClientToServerThread("localhost", 4942);
|
||||
ClientToServerThread clientThread = new ClientToServerThread("localhost", serverThread.getPortNumber());
|
||||
Thread.sleep(1000);
|
||||
clientThread.addDisconnectionListener(message -> Assert.assertTrue(message != null));
|
||||
serverThread.terminate();
|
||||
|
||||
@@ -20,7 +20,7 @@ public class RegularPacketsTest {
|
||||
public void setup() throws Exception {
|
||||
new GameState();
|
||||
serverThread = new MainServerThread();
|
||||
clientThread = new ClientToServerThread("localhost", 4942);
|
||||
clientThread = new ClientToServerThread("localhost", serverThread.getPortNumber());
|
||||
GameState.setCurrentStage(GameStages.RACING);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package seng302.visualiser.map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import seng302.model.GeoPoint;
|
||||
|
||||
/**
|
||||
* Unit test for Mercator Project class.
|
||||
* Created by hyi25 on 15/05/17.
|
||||
*/
|
||||
public class MercatorProjectionTest {
|
||||
@Test
|
||||
public void toMapPoint() throws Exception {
|
||||
GeoPoint geo1 = new GeoPoint(12.485394, 19.38947);
|
||||
javafx.geometry.Point2D actualPoint1 = MercatorProjection.toMapPoint(geo1);
|
||||
javafx.geometry.Point2D expectedPoint1 = new javafx.geometry.Point2D(141.78806755555556, 119.0503853635612);
|
||||
assertEquals(expectedPoint1.getX(), actualPoint1.getX(), 0.0001);
|
||||
assertEquals(expectedPoint1.getY(), actualPoint1.getY(), 0.0001);
|
||||
|
||||
GeoPoint geo2 = new GeoPoint(77.456432, -23.456462);
|
||||
javafx.geometry.Point2D actualPoint2 = MercatorProjection.toMapPoint(geo2);
|
||||
javafx.geometry.Point2D expectedPoint2 = new javafx.geometry.Point2D(111.31984924444444, 38.03143323746788);
|
||||
assertEquals(expectedPoint2.getX(), actualPoint2.getX(), 0.0001);
|
||||
assertEquals(expectedPoint2.getY(), actualPoint2.getY(), 0.0001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toMapGeo() throws Exception {
|
||||
javafx.geometry.Point2D point1 = new javafx.geometry.Point2D(123.1234, 25.4565);
|
||||
GeoPoint actualGeo1 = MercatorProjection.toMapGeo(point1);
|
||||
GeoPoint expectedGeo1 = new GeoPoint(80.77043127275441, -6.857718749999995);
|
||||
assertEquals(expectedGeo1.getLat(), actualGeo1.getLat(), 0.0001);
|
||||
assertEquals(expectedGeo1.getLng(), actualGeo1.getLng(), 0.0001);
|
||||
|
||||
javafx.geometry.Point2D point2 = new javafx.geometry.Point2D(1.235, 255.4565);
|
||||
GeoPoint actualGeo2 = MercatorProjection.toMapGeo(point2);
|
||||
GeoPoint expectedGeo2 = new GeoPoint(-84.98475532898011, -178.26328125);
|
||||
assertEquals(expectedGeo2.getLat(), actualGeo2.getLat(), 0.0001);
|
||||
assertEquals(expectedGeo2.getLng(), actualGeo2.getLng(), 0.0001);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,9 @@ package steps;
|
||||
import cucumber.api.java.en.Given;
|
||||
import cucumber.api.java.en.Then;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import org.junit.Assert;
|
||||
import seng302.visualiser.MapMaker;
|
||||
|
||||
@@ -16,26 +19,26 @@ public class CustomMapsSteps {
|
||||
|
||||
@Given("^that the game has multiple race xml files$")
|
||||
public void that_the_game_has_multiple_race_xml_files() throws Throwable {
|
||||
// mapMaker = MapMaker.getInstance();
|
||||
// String firstMap = mapMaker.getCurrentRacePath();
|
||||
// int numMaps = 0;
|
||||
// do {
|
||||
// mapMaker.next();
|
||||
// numMaps++;
|
||||
// } while (!mapMaker.getCurrentRacePath().equals(firstMap));
|
||||
// Assert.assertTrue(numMaps >= 2);
|
||||
mapMaker = MapMaker.getInstance();
|
||||
String firstMap = mapMaker.getCurrentRacePath();
|
||||
int numMaps = 0;
|
||||
do {
|
||||
mapMaker.next();
|
||||
numMaps++;
|
||||
} while (!mapMaker.getCurrentRacePath().equals(firstMap));
|
||||
Assert.assertTrue(numMaps >= 2);
|
||||
}
|
||||
|
||||
@Then("^all of them can be seen$")
|
||||
public void all_of_them_can_be_seen() throws Throwable {
|
||||
// File[] files = new File(this.getClass().getResource("/maps/").getPath()).listFiles();
|
||||
// for (File file : files) {
|
||||
// if (file.isFile()) {
|
||||
// Assert.assertTrue(file.getAbsolutePath().equals(mapMaker.getCurrentRacePath()));
|
||||
// mapMaker.next();
|
||||
// System.out.println(file.getAbsolutePath());
|
||||
// }
|
||||
// }
|
||||
File[] files = new File(this.getClass().getResource("/maps/").getPath()).listFiles();
|
||||
Arrays.sort(files);
|
||||
for (File file : files) {
|
||||
if (file.isFile()) {
|
||||
Assert.assertTrue(file.getAbsolutePath().endsWith(mapMaker.getCurrentRacePath()));
|
||||
mapMaker.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Given("^that I choose a race$")
|
||||
|
||||
@@ -45,7 +45,7 @@ public class SendChatSteps {
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
host = new ClientToServerThread("localhost", 4942);
|
||||
host = new ClientToServerThread("localhost", mst.getPortNumber());
|
||||
host.addStreamObserver(() -> {
|
||||
while (host.getPacketQueue().peek() != null) {
|
||||
StreamPacket packet = host.getPacketQueue().poll();
|
||||
@@ -68,7 +68,7 @@ public class SendChatSteps {
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
client = new ClientToServerThread("localhost", 4942);
|
||||
client = new ClientToServerThread("localhost", mst.getPortNumber());
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ie) {
|
||||
|
||||
@@ -44,7 +44,7 @@ public class ToggleSailSteps {
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
client = new ClientToServerThread("localhost", 4942);
|
||||
client = new ClientToServerThread("localhost", mst.getPortNumber());
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ie) {
|
||||
|
||||
Reference in New Issue
Block a user