Merge branch '1273_Changing_Cameras' into 1273_Skybox

This commit is contained in:
Michael Rausch
2017-09-25 18:40:15 +13:00
38 changed files with 505 additions and 249 deletions
@@ -18,6 +18,7 @@ import seng302.utilities.XMLParser;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import java.util.*; import java.util.*;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
/** /**
* A Static class to hold information about the current state of the game (model) * A Static class to hold information about the current state of the game (model)
@@ -453,7 +454,7 @@ public class GameState implements Runnable {
private void updateVelocity(ServerYacht yacht) { private void updateVelocity(ServerYacht yacht) {
Double trueWindAngle = Math.abs(windDirection - yacht.getHeading()); Double trueWindAngle = Math.abs(windDirection - yacht.getHeading());
Double boatSpeedInKnots = PolarTable.getBoatSpeed(getWindSpeedKnots(), trueWindAngle); Double boatSpeedInKnots = PolarTable.getBoatSpeed(getWindSpeedKnots(), trueWindAngle);
Double maxBoatSpeed = GeoUtility.knotsToMMS(boatSpeedInKnots) * speedMultiplier; Double maxBoatSpeed = GeoUtility.knotsToMMS(boatSpeedInKnots) * speedMultiplier * yacht.getMaxSpeedMultiplier();
if (yacht.getPowerUp() != null) { if (yacht.getPowerUp() != null) {
if (yacht.getPowerUp().equals(TokenType.BOOST)) { if (yacht.getPowerUp().equals(TokenType.BOOST)) {
maxBoatSpeed *= VELOCITY_BOOST_MULTIPLIER; maxBoatSpeed *= VELOCITY_BOOST_MULTIPLIER;
@@ -464,17 +465,17 @@ public class GameState implements Runnable {
// TODO: 15/08/17 remove magic numbers from these equations. // TODO: 15/08/17 remove magic numbers from these equations.
if (yacht.getSailIn()) { if (yacht.getSailIn()) {
if (currentVelocity < maxBoatSpeed - 500) { if (currentVelocity < maxBoatSpeed - 500) {
yacht.changeVelocity(maxBoatSpeed / 100); yacht.changeVelocity((maxBoatSpeed / 100) * yacht.getAccelerationMultiplier());
} else if (currentVelocity > maxBoatSpeed + 500) { } else if (currentVelocity > maxBoatSpeed + 500) {
yacht.changeVelocity(-currentVelocity / 200); yacht.changeVelocity((-currentVelocity / 200) * yacht.getAccelerationMultiplier());
} else { } else {
yacht.setCurrentVelocity(maxBoatSpeed); yacht.setCurrentVelocity((maxBoatSpeed) * yacht.getAccelerationMultiplier());
} }
} else { } else {
if (currentVelocity > 3000) { if (currentVelocity > 3000) {
yacht.changeVelocity(-currentVelocity / 200); yacht.changeVelocity((-currentVelocity / 200) * yacht.getAccelerationMultiplier());
} else if (currentVelocity > 100) { } else if (currentVelocity > 100) {
yacht.changeVelocity(-currentVelocity / 50); yacht.changeVelocity((-currentVelocity / 50) * yacht.getAccelerationMultiplier());
} else if (currentVelocity <= 100) { } else if (currentVelocity <= 100) {
yacht.setCurrentVelocity(0d); yacht.setCurrentVelocity(0d);
} }
@@ -705,6 +706,9 @@ public class GameState implements Runnable {
int blue = customizeData[2] & 0xFF; int blue = customizeData[2] & 0xFF;
Color yachtColor = Color.rgb(red, green, blue); Color yachtColor = Color.rgb(red, green, blue);
playerYacht.setBoatColor(yachtColor); playerYacht.setBoatColor(yachtColor);
} else if (requestType.equals(CustomizeRequestType.SHAPE)) {
String type = new String(customizeData);
playerYacht.setBoatType(BoatMeshType.valueOf(type));
} }
} }
@@ -33,6 +33,7 @@ import seng302.model.stream.packets.PacketType;
import seng302.model.stream.packets.StreamPacket; import seng302.model.stream.packets.StreamPacket;
import seng302.model.stream.xml.generator.RaceXMLTemplate; import seng302.model.stream.xml.generator.RaceXMLTemplate;
import seng302.utilities.XMLGenerator; import seng302.utilities.XMLGenerator;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
/** /**
* A class describing a single connection to a Client for the purposes of sending and receiving on * A class describing a single connection to a Client for the purposes of sending and receiving on
@@ -125,7 +126,7 @@ public class ServerToClientThread implements Runnable {
lName = all.get(ThreadLocalRandom.current().nextInt(0, all.size())); lName = all.get(ThreadLocalRandom.current().nextInt(0, all.size()));
ServerYacht yacht = new ServerYacht( ServerYacht yacht = new ServerYacht(
"Yacht", sourceId, sourceId.toString(), fName, fName + " " + lName, "NZ" BoatMeshType.DINGHY, sourceId, sourceId.toString(), fName, fName + " " + lName, "NZ"
); );
player = new Player(socket, yacht); player = new Player(socket, yacht);
+21 -5
View File
@@ -6,6 +6,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import java.util.Timer;
import javafx.beans.property.ReadOnlyDoubleProperty; import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.beans.property.ReadOnlyDoubleWrapper; import javafx.beans.property.ReadOnlyDoubleWrapper;
import javafx.beans.property.ReadOnlyIntegerProperty; import javafx.beans.property.ReadOnlyIntegerProperty;
@@ -18,6 +19,7 @@ import javafx.scene.paint.Color;
import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.Function;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
import seng302.model.token.TokenType; import seng302.model.token.TokenType;
import seng302.visualiser.fxObjects.assets_3D.BoatObject; import seng302.visualiser.fxObjects.assets_3D.BoatObject;
@@ -47,7 +49,7 @@ public class ClientYacht extends Observable {
private Logger logger = LoggerFactory.getLogger(ClientYacht.class); private Logger logger = LoggerFactory.getLogger(ClientYacht.class);
private String boatType; private BoatMeshType boatType;
private Integer sourceId; private Integer sourceId;
private String hullID; //matches HullNum in the XML spec. private String hullID; //matches HullNum in the XML spec.
private String shortName; private String shortName;
@@ -57,7 +59,7 @@ public class ClientYacht extends Observable {
private TokenType powerUp; private TokenType powerUp;
private Long estimateTimeAtFinish; private Long estimateTimeAtFinish;
private Boolean sailIn = false; private Boolean sailIn = true;
private Integer currentMarkSeqID = 0; private Integer currentMarkSeqID = 0;
private Long markRoundTime; private Long markRoundTime;
private Long timeTillNext; private Long timeTillNext;
@@ -67,6 +69,8 @@ public class ClientYacht extends Observable {
private Integer boatStatus; private Integer boatStatus;
private Double currentVelocity; private Double currentVelocity;
Timer t;
private BoatObject boatObject; private BoatObject boatObject;
private List<YachtLocationListener> locationListeners = new ArrayList<>(); private List<YachtLocationListener> locationListeners = new ArrayList<>();
@@ -76,9 +80,10 @@ public class ClientYacht extends Observable {
private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper(); private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper();
private ReadOnlyLongWrapper timeSinceLastMarkProperty = new ReadOnlyLongWrapper(); private ReadOnlyLongWrapper timeSinceLastMarkProperty = new ReadOnlyLongWrapper();
private ReadOnlyIntegerWrapper placingProperty = new ReadOnlyIntegerWrapper(); private ReadOnlyIntegerWrapper placingProperty = new ReadOnlyIntegerWrapper();
private ReadOnlyDoubleWrapper headingProperty = new ReadOnlyDoubleWrapper();
private Color colour; private Color colour;
public ClientYacht(String boatType, Integer sourceId, String hullID, String shortName, public ClientYacht(BoatMeshType boatType, Integer sourceId, String hullID, String shortName,
String boatName, String country) { String boatName, String country) {
this.boatType = boatType; this.boatType = boatType;
this.sourceId = sourceId; this.sourceId = sourceId;
@@ -88,6 +93,7 @@ public class ClientYacht extends Observable {
this.country = country; this.country = country;
this.location = new GeoPoint(57.670341, 11.826856); this.location = new GeoPoint(57.670341, 11.826856);
this.heading = 120.0; //In degrees this.heading = 120.0; //In degrees
this.headingProperty.set(this.heading);
this.currentVelocity = 0d; this.currentVelocity = 0d;
this.boatStatus = 1; this.boatStatus = 1;
this.colour = Color.rgb(0, 0, 0, 1.0); this.colour = Color.rgb(0, 0, 0, 1.0);
@@ -102,7 +108,7 @@ public class ClientYacht extends Observable {
super.addObserver(o); super.addObserver(o);
} }
public String getBoatType() { public BoatMeshType getBoatType() {
return boatType; return boatType;
} }
@@ -246,6 +252,7 @@ public class ClientYacht extends Observable {
public void setHeading(Double heading) { public void setHeading(Double heading) {
this.heading = heading; this.heading = heading;
setHeadingProperty();
} }
@Override @Override
@@ -274,10 +281,10 @@ public class ClientYacht extends Observable {
this.colour = colour; this.colour = colour;
} }
public void updateLocation(double lat, double lng, double heading, double velocity) { public void updateLocation(double lat, double lng, double heading, double velocity) {
setLocation(lat, lng); setLocation(lat, lng);
this.heading = heading; this.heading = heading;
setHeadingProperty();
this.currentVelocity = velocity; this.currentVelocity = velocity;
updateVelocityProperty(velocity); updateVelocityProperty(velocity);
for (YachtLocationListener yll : locationListeners) { for (YachtLocationListener yll : locationListeners) {
@@ -285,6 +292,10 @@ public class ClientYacht extends Observable {
} }
} }
private void setHeadingProperty() {
headingProperty.set(heading);
}
public void addLocationListener(YachtLocationListener listener) { public void addLocationListener(YachtLocationListener listener) {
locationListeners.add(listener); locationListeners.add(listener);
} }
@@ -325,4 +336,9 @@ public class ClientYacht extends Observable {
public BoatObject getBoatObject() { public BoatObject getBoatObject() {
return this.boatObject; return this.boatObject;
} }
public ReadOnlyDoubleWrapper getHeadingProperty() {
return headingProperty;
}
} }
+46 -22
View File
@@ -8,10 +8,13 @@ import seng302.gameServer.messages.BoatStatus;
import seng302.model.mark.Mark; import seng302.model.mark.Mark;
import seng302.model.token.TokenType; import seng302.model.token.TokenType;
import seng302.utilities.GeoUtility; import seng302.utilities.GeoUtility;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
/** /**
* Yacht class for the racing boat. <p> Class created to store more variables (eg. boat statuses) * Yacht class for the racing boat. <p> Class created to store more variables (eg. boat statuses)
@@ -20,12 +23,14 @@ import java.util.Observer;
*/ */
public class ServerYacht { public class ServerYacht {
private Logger logger = LoggerFactory.getLogger(ClientYacht.class); private Logger logger = LoggerFactory.getLogger(ServerYacht.class);
public static final Double TURN_STEP = 5.0;
//Boat info //Boat info
private String boatType; private BoatMeshType boatType;
private Double turnStep = 5.0;
private Double maxSpeedMultiplier = 1.0;
private Double turnStepMultiplier = 1.0;
private Double accelerationMultiplier = 1.0;
private Integer sourceId; private Integer sourceId;
private String hullID; //matches HullNum in the XML spec. private String hullID; //matches HullNum in the XML spec.
private String shortName; private String shortName;
@@ -57,9 +62,9 @@ public class ServerYacht {
private Long powerUpStartTime; private Long powerUpStartTime;
public ServerYacht(String boatType, Integer sourceId, String hullID, String shortName, public ServerYacht(BoatMeshType boatType, Integer sourceId, String hullID, String shortName,
String boatName, String country) { String boatName, String country) {
this.boatType = boatType; setBoatType(boatType);
this.boatStatus = BoatStatus.PRESTART; this.boatStatus = BoatStatus.PRESTART;
this.sourceId = sourceId; this.sourceId = sourceId;
this.hullID = hullID; this.hullID = hullID;
@@ -129,7 +134,7 @@ public class ServerYacht {
* @param amount the amount by which to adjust the boat heading. * @param amount the amount by which to adjust the boat heading.
*/ */
public void adjustHeading(Double amount) { public void adjustHeading(Double amount) {
Double newVal = heading + amount; Double newVal = heading + (amount * turnStepMultiplier);
lastHeading = heading; lastHeading = heading;
heading = (double) Math.floorMod(newVal.longValue(), 360L); heading = (double) Math.floorMod(newVal.longValue(), 360L);
} }
@@ -174,7 +179,7 @@ public class ServerYacht {
if (isAuto) { if (isAuto) {
turnTowardsHeading(autoHeading); turnTowardsHeading(autoHeading);
if (Math.abs(heading - autoHeading) if (Math.abs(heading - autoHeading)
<= TURN_STEP) { //Cancel when within 1 turn step of target. <= turnStep) { //Cancel when within 1 turn step of target.
isAuto = false; isAuto = false;
} }
} }
@@ -189,20 +194,20 @@ public class ServerYacht {
Double normalizedHeading = normalizeHeading(); Double normalizedHeading = normalizeHeading();
if (normalizedHeading == 0) { if (normalizedHeading == 0) {
if (lastHeading < 180) { if (lastHeading < 180) {
adjustHeading(-TURN_STEP); adjustHeading(-turnStep);
} else { } else {
adjustHeading(TURN_STEP); adjustHeading(turnStep);
} }
} else if (normalizedHeading == 180) { } else if (normalizedHeading == 180) {
if (lastHeading < 180) { if (lastHeading < 180) {
adjustHeading(TURN_STEP); adjustHeading(turnStep);
} else { } else {
adjustHeading(-TURN_STEP); adjustHeading(-turnStep);
} }
} else if (normalizedHeading < 180) { } else if (normalizedHeading < 180) {
adjustHeading(-TURN_STEP); adjustHeading(-turnStep);
} else { } else {
adjustHeading(TURN_STEP); adjustHeading(turnStep);
} }
} }
@@ -211,20 +216,20 @@ public class ServerYacht {
Double normalizedHeading = normalizeHeading(); Double normalizedHeading = normalizeHeading();
if (normalizedHeading == 0) { if (normalizedHeading == 0) {
if (lastHeading < 180) { if (lastHeading < 180) {
adjustHeading(TURN_STEP); adjustHeading(turnStep);
} else { } else {
adjustHeading(-TURN_STEP); adjustHeading(-turnStep);
} }
} else if (normalizedHeading == 180) { } else if (normalizedHeading == 180) {
if (lastHeading < 180) { if (lastHeading < 180) {
adjustHeading(-TURN_STEP); adjustHeading(-turnStep);
} else { } else {
adjustHeading(TURN_STEP); adjustHeading(turnStep);
} }
} else if (normalizedHeading < 180) { } else if (normalizedHeading < 180) {
adjustHeading(TURN_STEP); adjustHeading(turnStep);
} else { } else {
adjustHeading(-TURN_STEP); adjustHeading(-turnStep);
} }
} }
@@ -268,9 +273,9 @@ public class ServerYacht {
private void turnTowardsHeading(Double newHeading) { private void turnTowardsHeading(Double newHeading) {
Double newVal = heading - newHeading; Double newVal = heading - newHeading;
if (Math.floorMod(newVal.longValue(), 360L) > 180) { if (Math.floorMod(newVal.longValue(), 360L) > 180) {
adjustHeading(TURN_STEP / 5); adjustHeading(turnStep / 5);
} else { } else {
adjustHeading(-TURN_STEP / 5); adjustHeading(-turnStep / 5);
} }
} }
@@ -421,4 +426,23 @@ public class ServerYacht {
return boatColor; return boatColor;
} }
public void setBoatType(BoatMeshType boatType) {
this.accelerationMultiplier = boatType.accelerationMultiplier;
this.maxSpeedMultiplier = boatType.maxSpeedMultiplier;
this.turnStepMultiplier = boatType.turnStep;
this.boatType = boatType;
}
public Double getMaxSpeedMultiplier() {
return maxSpeedMultiplier;
}
public Double getAccelerationMultiplier(){
return accelerationMultiplier;
}
public BoatMeshType getBoatType() {
return boatType;
}
} }
+13 -5
View File
@@ -14,8 +14,10 @@ public class Sounds {
private static MediaPlayer soundEffect; private static MediaPlayer soundEffect;
private static MediaPlayer soundPlayer; private static MediaPlayer soundPlayer;
private static MediaPlayer hoverSoundPlayer; private static MediaPlayer hoverSoundPlayer;
private static MediaPlayer crashSoundPlayer;
private static boolean hoverInitialized = false; private static boolean hoverInitialized = false;
private static boolean crashInitialized = false;
private static boolean musicMuted = false; private static boolean musicMuted = false;
private static boolean soundEffectsMuted = false; private static boolean soundEffectsMuted = false;
@@ -155,11 +157,17 @@ public class Sounds {
public static void playCrashSound() { public static void playCrashSound() {
if (!soundEffectsMuted) { if (!soundEffectsMuted) {
Media crashSound = new Media( if (!crashInitialized) {
Media pickupSound = new Media(
Sounds.class.getClassLoader().getResource("sounds/Large-metal-door-slam.mp3") Sounds.class.getClassLoader().getResource("sounds/Large-metal-door-slam.mp3")
.toString()); .toString());
soundPlayer = new MediaPlayer(crashSound); crashSoundPlayer = new MediaPlayer(pickupSound);
soundPlayer.play(); crashInitialized = true;
}
if (crashSoundPlayer != null) {
crashSoundPlayer.stop();
}
crashSoundPlayer.play();
} }
} }
@@ -176,10 +184,10 @@ public class Sounds {
public static void playHoverSound() { public static void playHoverSound() {
if (!soundEffectsMuted) { if (!soundEffectsMuted) {
if (!hoverInitialized) { if (!hoverInitialized) {
Media crashSound = new Media( Media hoverSound = new Media(
Sounds.class.getClassLoader().getResource("sounds/Error-sound-effect.mp3") Sounds.class.getClassLoader().getResource("sounds/Error-sound-effect.mp3")
.toString()); .toString());
hoverSoundPlayer = new MediaPlayer(crashSound); hoverSoundPlayer = new MediaPlayer(hoverSound);
hoverInitialized = true; hoverInitialized = true;
} }
hoverSoundPlayer.setVolume(0.5); hoverSoundPlayer.setVolume(0.5);
@@ -18,6 +18,7 @@ import seng302.model.stream.xml.parser.RaceXMLData;
import seng302.model.stream.xml.parser.RegattaXMLData; import seng302.model.stream.xml.parser.RegattaXMLData;
import seng302.model.token.Token; import seng302.model.token.Token;
import seng302.model.token.TokenType; import seng302.model.token.TokenType;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
/** /**
* Utilities for parsing XML documents * Utilities for parsing XML documents
@@ -139,18 +140,16 @@ public class XMLParser {
if (currentBoat.getNodeName().equals("Boat")) { if (currentBoat.getNodeName().equals("Boat")) {
// Boat boat = new Boat(currentBoat); // Boat boat = new Boat(currentBoat);
ClientYacht yacht = new ClientYacht( ClientYacht yacht = new ClientYacht(
XMLParser.getNodeAttributeString(currentBoat, "Type"), BoatMeshType.valueOf(XMLParser.getNodeAttributeString(currentBoat, "Type")),
XMLParser.getNodeAttributeInt(currentBoat, "SourceID"), XMLParser.getNodeAttributeInt(currentBoat, "SourceID"),
XMLParser.getNodeAttributeString(currentBoat, "HullNum"), XMLParser.getNodeAttributeString(currentBoat, "HullNum"),
XMLParser.getNodeAttributeString(currentBoat, "ShortName"), XMLParser.getNodeAttributeString(currentBoat, "ShortName"),
XMLParser.getNodeAttributeString(currentBoat, "BoatName"), XMLParser.getNodeAttributeString(currentBoat, "BoatName"),
XMLParser.getNodeAttributeString(currentBoat, "Country")); XMLParser.getNodeAttributeString(currentBoat, "Country"));
yacht.setColour(Color.web(getNodeAttributeString(currentBoat, "Color"))); yacht.setColour(Color.web(getNodeAttributeString(currentBoat, "Color")));
if (yacht.getBoatType().equals("Yacht")) {
competingBoats.put(yacht.getSourceId(), yacht); competingBoats.put(yacht.getSourceId(), yacht);
} }
} }
}
return competingBoats; return competingBoats;
} }
@@ -46,7 +46,6 @@ import seng302.visualiser.fxObjects.assets_3D.*;
public class GameView3D { public class GameView3D {
private final double FOV = 60; private final double FOV = 60;
private final double DEFAULT_CAMERA_DEPTH = -125; private final double DEFAULT_CAMERA_DEPTH = -125;
private final double DEFAULT_CAMERA_X = 0; private final double DEFAULT_CAMERA_X = 0;
@@ -101,12 +100,12 @@ public class GameView3D {
camera.setFieldOfView(FOV); camera.setFieldOfView(FOV);
camera2 = new TopDownCamera(); camera2 = new TopDownCamera();
camera2.setFarClip(600); camera2.setFarClip(100000);
camera2.setNearClip(0.1); camera2.setNearClip(0.1);
camera2.setFieldOfView(FOV); camera2.setFieldOfView(FOV);
camera3 = new ChaseCamera(); camera3 = new ChaseCamera();
camera3.setFarClip(600); camera3.setFarClip(100000);
camera3.setNearClip(0.1); camera3.setNearClip(0.1);
camera3.setFieldOfView(FOV); camera3.setFieldOfView(FOV);
@@ -118,6 +117,7 @@ public class GameView3D {
view.setCamera(camera); view.setCamera(camera);
camera.getTransforms().add(new Rotate(30, new Point3D(1,0,0))); camera.getTransforms().add(new Rotate(30, new Point3D(1,0,0)));
//TDBC: Fix
skybox = new Skybox(new Image("https://i.pinimg.com/originals/3a/24/14/3a24142dce7b271799b6501fabc4ee19.jpg"), 100000, camera); skybox = new Skybox(new Image("https://i.pinimg.com/originals/3a/24/14/3a24142dce7b271799b6501fabc4ee19.jpg"), 100000, camera);
skybox.getTransforms().addAll(new Rotate(90, Rotate.X_AXIS)); skybox.getTransforms().addAll(new Rotate(90, Rotate.X_AXIS));
@@ -446,16 +446,16 @@ public class GameView3D {
((RaceCamera) view.getCamera()).zoomOut(); ((RaceCamera) view.getCamera()).zoomOut();
break; break;
case W: case W:
view.getCamera().getTransforms().addAll(new Translate(0, -1, 0)); ((RaceCamera) view.getCamera()).panUp();
break; break;
case S: case S:
view.getCamera().getTransforms().addAll(new Translate(0, 1, 0)); ((RaceCamera) view.getCamera()).panDown();
break; break;
case A: case A:
view.getCamera().getTransforms().addAll(new Translate(-1, 0, 0)); ((RaceCamera) view.getCamera()).panLeft();
break; break;
case D: case D:
view.getCamera().getTransforms().addAll(new Translate(1, 0, 0)); ((RaceCamera) view.getCamera()).panRight();
break; break;
case F1: case F1:
if (view.getCamera().equals(camera)) { if (view.getCamera().equals(camera)) {
@@ -493,7 +493,7 @@ public class GameView3D {
final List<Group> wakes = new ArrayList<>(); final List<Group> wakes = new ArrayList<>();
for (ClientYacht clientYacht : yachts) { for (ClientYacht clientYacht : yachts) {
Color colour = clientYacht.getColour(); Color colour = clientYacht.getColour();
newBoat = new BoatObject(); newBoat = new BoatObject(clientYacht.getBoatType());
newBoat.setFill(colour); newBoat.setFill(colour);
boatObjects.put(clientYacht, newBoat); boatObjects.put(clientYacht, newBoat);
wakesGroup.getChildren().add(newBoat.getWake()); wakesGroup.getChildren().add(newBoat.getWake());
@@ -507,7 +507,8 @@ public class GameView3D {
if (clientYacht.getSourceId().equals( if (clientYacht.getSourceId().equals(
ViewManager.getInstance().getGameClient().getServerThread().getClientId())) { ViewManager.getInstance().getGameClient().getServerThread().getClientId())) {
((ChaseCamera) camera3).setPlayerBoat(newBoat); ((ChaseCamera) camera3).setPlayerBoat(newBoat, clientYacht);
((TopDownCamera) camera2).setPlayerBoat(newBoat);
} }
} }
Platform.runLater(() -> { Platform.runLater(() -> {
@@ -627,6 +628,7 @@ public class GameView3D {
} }
public void setBoatAsPlayer (ClientYacht playerYacht) { public void setBoatAsPlayer (ClientYacht playerYacht) {
playerYacht.toggleSail();
playerBoatAnimationTimer = new AnimationTimer() { playerBoatAnimationTimer = new AnimationTimer() {
double count = 60; double count = 60;
@@ -8,6 +8,7 @@ import javafx.scene.PerspectiveCamera;
import javafx.scene.transform.Rotate; import javafx.scene.transform.Rotate;
import javafx.scene.transform.Transform; import javafx.scene.transform.Transform;
import javafx.scene.transform.Translate; import javafx.scene.transform.Translate;
import seng302.model.ClientYacht;
import seng302.visualiser.fxObjects.assets_3D.BoatObject; import seng302.visualiser.fxObjects.assets_3D.BoatObject;
@@ -15,55 +16,80 @@ public class ChaseCamera extends PerspectiveCamera implements RaceCamera {
private ObservableList<Transform> transforms; private ObservableList<Transform> transforms;
private BoatObject playerBoat; private BoatObject playerBoat;
private ClientYacht playerYacht;
private Double zoomFactor;
private Double horizontalPan;
private Double verticalPan;
public ChaseCamera() { public ChaseCamera() {
super(true); super(true);
transforms = this.getTransforms(); transforms = this.getTransforms();
this.zoomFactor = -75.0;
this.horizontalPan = 0.0;
this.verticalPan = 0.0;
} }
public void setPlayerBoat(BoatObject playerBoat) { public void setPlayerBoat(BoatObject playerBoat, ClientYacht playerYacht) {
this.playerBoat = playerBoat; this.playerBoat = playerBoat;
this.playerYacht = playerYacht;
this.playerYacht.getHeadingProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue,
Number newValue) {
repositionCamera();
}
});
this.playerBoat.layoutXProperty().addListener(new ChangeListener<Number>() { this.playerBoat.layoutXProperty().addListener(new ChangeListener<Number>() {
@Override @Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, public void changed(ObservableValue<? extends Number> observable, Number oldValue,
Number newValue) { Number newValue) {
updateCameraX((Double) oldValue, (Double) newValue); repositionCamera();
} }
}); });
this.playerBoat.layoutYProperty().addListener(new ChangeListener<Number>() { this.playerBoat.layoutYProperty().addListener(new ChangeListener<Number>() {
@Override @Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, public void changed(ObservableValue<? extends Number> observable, Number oldValue,
Number newValue) { Number newValue) {
updateCameraY((Double) oldValue, (Double) newValue); repositionCamera();
} }
}); });
} }
private void repositionCamera() {
private void updateCameraX(Double oldXValue, Double newXValue) { transforms.clear();
if (transforms.size() == 0) { // boat is placed and then moved at start,
transforms.addAll( transforms.addAll(
new Translate(playerBoat.getLayoutX() - 30, playerBoat.getLayoutY() - 30, -125), new Translate(playerBoat.getLayoutX(), playerBoat.getLayoutY(), 0),
new Rotate(80, new Point3D(0, 0, 1)) new Rotate(playerYacht.getHeadingProperty().getValue() + horizontalPan,
new Point3D(0, 0, 1)),
new Rotate(60 + verticalPan, new Point3D(1, 0, 0)),
new Translate(0, 0, zoomFactor)
); );
} else { }
transforms.addAll(new Translate(newXValue - oldXValue, 0, 0));
private void adjustZoomFactor(Double adjustment) {
if (zoomFactor + adjustment < -15.0 && zoomFactor + adjustment > -125.0) {
zoomFactor = zoomFactor + adjustment;
repositionCamera();
} }
} }
private void updateCameraY(Double oldYValue, Double newYValue) { private void adjustVerticalPan(Double adjustment) {
transforms.addAll(new Translate(0, (newYValue - oldYValue), 0)); if (verticalPan + adjustment >= -20 && verticalPan + adjustment <= 20) {
verticalPan += adjustment;
repositionCamera();
}
} }
@Override @Override
public void zoomIn() { public void zoomIn() {
transforms.addAll(new Translate(0, 0, 1.5)); adjustZoomFactor(5.0);
} }
@Override @Override
public void zoomOut() { public void zoomOut() {
transforms.addAll(new Translate(0, 0, -1.5)); adjustZoomFactor(-5.0);
} }
@@ -73,17 +99,23 @@ public class ChaseCamera extends PerspectiveCamera implements RaceCamera {
@Override @Override
public void panLeft() { public void panLeft() {
this.horizontalPan -= 5;
repositionCamera();
} }
@Override @Override
public void panRight() { public void panRight() {
this.horizontalPan += 5;
repositionCamera();
} }
@Override @Override
public void panUp() { public void panUp() {
adjustVerticalPan(-5.0);
} }
@Override @Override
public void panDown() { public void panDown() {
adjustVerticalPan(5.0);
} }
} }
@@ -1,14 +1,18 @@
package seng302.visualiser.cameras; package seng302.visualiser.cameras;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.scene.PerspectiveCamera; import javafx.scene.PerspectiveCamera;
import javafx.scene.transform.Transform; import javafx.scene.transform.Transform;
import javafx.scene.transform.Translate; import javafx.scene.transform.Translate;
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
public class TopDownCamera extends PerspectiveCamera implements RaceCamera { public class TopDownCamera extends PerspectiveCamera implements RaceCamera {
ObservableList<Transform> transforms; private ObservableList<Transform> transforms;
private BoatObject playerBoat;
public TopDownCamera() { public TopDownCamera() {
super(true); super(true);
@@ -16,6 +20,39 @@ public class TopDownCamera extends PerspectiveCamera implements RaceCamera {
transforms.add(new Translate(0, 0, -125)); transforms.add(new Translate(0, 0, -125));
} }
public void setPlayerBoat(BoatObject playerBoat) {
this.playerBoat = playerBoat;
this.playerBoat.layoutXProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue,
Number newValue) {
updateCameraX((Double) oldValue, (Double) newValue);
}
});
this.playerBoat.layoutYProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue,
Number newValue) {
updateCameraY((Double) oldValue, (Double) newValue);
}
});
}
private void updateCameraX(Double oldXValue, Double newXValue) {
if (transforms.size() == 0) { // boat is placed and then moved at start,
transforms.addAll(
new Translate(playerBoat.getLayoutX(), playerBoat.getLayoutY(), -125)
);
} else {
transforms.addAll(new Translate(newXValue - oldXValue, 0, 0));
}
}
private void updateCameraY(Double oldYValue, Double newYValue) {
transforms.addAll(new Translate(0, (newYValue - oldYValue), 0));
}
@Override @Override
public void zoomIn() { public void zoomIn() {
transforms.addAll(new Translate(0, 0, 1.5)); transforms.addAll(new Translate(0, 0, 1.5));
@@ -31,7 +31,11 @@ import seng302.visualiser.controllers.dialogs.DirectConnectController;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.*; import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
public class LobbyController implements Initializable { public class LobbyController implements Initializable {
@@ -134,6 +138,8 @@ public class LobbyController implements Initializable {
controller.setPlayerName(this.playerBoats controller.setPlayerName(this.playerBoats
.get(ViewManager.getInstance().getGameClient().getServerThread().getClientId()) .get(ViewManager.getInstance().getGameClient().getServerThread().getClientId())
.getBoatName()); .getBoatName());
controller.setCurrentBoat(this.playerBoats.get(ViewManager.getInstance().getGameClient().getServerThread().getClientId())
.getBoatType().toString());
return customizationDialog; return customizationDialog;
} }
@@ -208,7 +214,7 @@ public class LobbyController implements Initializable {
FXMLLoader loader = new FXMLLoader( FXMLLoader loader = new FXMLLoader(
getClass().getResource("/views/cells/PlayerCell.fxml")); getClass().getResource("/views/cells/PlayerCell.fxml"));
loader.setController(new PlayerCell(playerId, yacht.getBoatName(), yacht.getColour())); loader.setController(new PlayerCell(playerId, yacht));
try { try {
pane = loader.load(); pane = loader.load();
@@ -269,6 +269,8 @@ public class ViewManager {
stage.setMinHeight(500); stage.setMinHeight(500);
stage.setMinWidth(800); stage.setMinWidth(800);
stage.setTitle("Party Parrots At Sea");
stage.getIcons().add(new Image(getClass().getResourceAsStream("/PP.png")));
stage.setOnCloseRequest(e -> closeAll()); stage.setOnCloseRequest(e -> closeAll());
stage.setScene(scene); stage.setScene(scene);
stage.show(); stage.show();
@@ -6,6 +6,7 @@ import javafx.scene.control.Label;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import seng302.model.ClientYacht;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType; import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
import seng302.visualiser.fxObjects.assets_3D.BoatModel; import seng302.visualiser.fxObjects.assets_3D.BoatModel;
import seng302.visualiser.fxObjects.assets_3D.ModelFactory; import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
@@ -24,11 +25,13 @@ public class PlayerCell {
private String name; private String name;
private Color boatColor; private Color boatColor;
private Integer playerId; private Integer playerId;
private BoatMeshType boatType;
public PlayerCell(Integer playerId, String playerName, Color color) { public PlayerCell(Integer playerId, ClientYacht yacht) {
this.playerId = playerId; this.playerId = playerId;
this.name = playerName; this.name = yacht.getBoatName();
this.boatColor = color; this.boatColor = yacht.getColour();
this.boatType = yacht.getBoatType();
} }
public void initialize() { public void initialize() {
@@ -37,7 +40,7 @@ public class PlayerCell {
// Add Rotating Boat to Player Cell with players color on it. // Add Rotating Boat to Player Cell with players color on it.
Group group = new Group(); Group group = new Group();
boatPane.getChildren().add(group); boatPane.getChildren().add(group);
BoatModel bo = ModelFactory.boatIconView(BoatMeshType.DINGHY, this.boatColor); BoatModel bo = ModelFactory.boatIconView(boatType, boatColor);
group.getChildren().add(bo.getAssets()); group.getChildren().add(bo.getAssets());
} }
@@ -6,15 +6,25 @@ import com.jfoenix.controls.JFXTextField;
import com.jfoenix.validation.RequiredFieldValidator; import com.jfoenix.validation.RequiredFieldValidator;
import java.net.URL; import java.net.URL;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.PointLight;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import seng302.gameServer.messages.CustomizeRequestType; import seng302.gameServer.messages.CustomizeRequestType;
import seng302.utilities.Sounds; import seng302.utilities.Sounds;
import seng302.visualiser.ClientToServerThread; import seng302.visualiser.ClientToServerThread;
import seng302.visualiser.controllers.LobbyController; import seng302.visualiser.controllers.LobbyController;
import seng302.visualiser.controllers.ViewManager; import seng302.visualiser.controllers.ViewManager;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
import seng302.visualiser.fxObjects.assets_3D.BoatModel;
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
import seng302.visualiser.validators.FieldLengthValidator; import seng302.visualiser.validators.FieldLengthValidator;
import seng302.visualiser.validators.ValidationTools; import seng302.visualiser.validators.ValidationTools;
@@ -24,23 +34,35 @@ public class BoatCustomizeController implements Initializable{
@FXML @FXML
private JFXColorPicker colorPicker; private JFXColorPicker colorPicker;
@FXML @FXML
private ProgressBar speedBar;
@FXML
private ProgressBar accelBar;
@FXML
private ProgressBar handleBar;
@FXML
private JFXButton submitBtn; private JFXButton submitBtn;
@FXML @FXML
private JFXTextField boatName; private JFXTextField boatName;
@FXML @FXML
void colorChanged(ActionEvent event) { private Pane boatPane;
Color color = colorPicker.getValue(); @FXML
void colorChanged() {
refreshBoat();
} }
//---------FXML END---------// //---------FXML END---------//
private ClientToServerThread socketThread; private ClientToServerThread socketThread;
private LobbyController lobbyController; private LobbyController lobbyController;
private BoatMeshType currentBoat;
private Double maxSpeedMultiplier = 1.0;
private Double maxTurnRateMultiplier = 1.0;
private Double maxAccelerationMultiplier = 1.0;
@Override @Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
socketThread = ViewManager.getInstance().getGameClient().getServerThread(); socketThread = ViewManager.getInstance().getGameClient().getServerThread();
findMaxStats();
RequiredFieldValidator playerNameReqValidator = new RequiredFieldValidator(); RequiredFieldValidator playerNameReqValidator = new RequiredFieldValidator();
playerNameReqValidator.setMessage("Player name required."); playerNameReqValidator.setMessage("Player name required.");
@@ -48,6 +70,8 @@ public class BoatCustomizeController implements Initializable{
playerNameLengthValidator.setMessage("Player name too long."); playerNameLengthValidator.setMessage("Player name too long.");
boatName.setValidators(playerNameLengthValidator, playerNameReqValidator); boatName.setValidators(playerNameLengthValidator, playerNameReqValidator);
boatPane.setBackground(
new Background(new BackgroundFill(Color.SKYBLUE, CornerRadii.EMPTY, Insets.EMPTY)));
submitBtn.setOnMouseReleased(event -> { submitBtn.setOnMouseReleased(event -> {
Sounds.playButtonClick(); Sounds.playButtonClick();
@@ -78,7 +102,10 @@ public class BoatCustomizeController implements Initializable{
colorArray[2] = (byte) blue; colorArray[2] = (byte) blue;
socketThread.sendCustomizationRequest(CustomizeRequestType.COLOR, colorArray); socketThread.sendCustomizationRequest(CustomizeRequestType.COLOR, colorArray);
socketThread.sendCustomizationRequest(CustomizeRequestType.SHAPE, currentBoat.toString().getBytes());
lobbyController.closeCustomizationDialog(); lobbyController.closeCustomizationDialog();
} }
} }
@@ -93,4 +120,61 @@ public class BoatCustomizeController implements Initializable{
public void setParentController(LobbyController lobbyController){ public void setParentController(LobbyController lobbyController){
this.lobbyController = lobbyController; this.lobbyController = lobbyController;
} }
public void setCurrentBoat(String boatType) {
currentBoat = BoatMeshType.valueOf(boatType);
displayCurrentBoat();
refreshStatBars(currentBoat);
}
public void nextBoat() {
currentBoat = BoatMeshType.getNextBoatType(currentBoat);
displayCurrentBoat();
refreshStatBars(currentBoat);
}
public void prevBoat() {
currentBoat = BoatMeshType.getPrevBoatType(currentBoat);
displayCurrentBoat();
refreshStatBars(currentBoat);
}
private void displayCurrentBoat() {
boatPane.getChildren().clear();
Group group = new Group();
boatPane.getChildren().add(group);
BoatModel bo = ModelFactory.boatCustomiseView(currentBoat, colorPicker.getValue());
group.getChildren().add(bo.getAssets());
group.getChildren().add(new PointLight());
}
private void refreshBoat() {
boatPane.getChildren().clear();
Group group = new Group();
boatPane.getChildren().add(group);
BoatModel bo = ModelFactory.boatCustomiseView(currentBoat, colorPicker.getValue());
group.getChildren().add(bo.getAssets());
refreshStatBars(currentBoat);
}
private void findMaxStats() {
for (BoatMeshType bmt: BoatMeshType.values()) {
if (bmt.turnStep > maxTurnRateMultiplier) {
maxTurnRateMultiplier = bmt.turnStep;
}
if (bmt.maxSpeedMultiplier > maxSpeedMultiplier) {
maxSpeedMultiplier = bmt.maxSpeedMultiplier;
}
if (bmt.accelerationMultiplier > maxAccelerationMultiplier) {
maxAccelerationMultiplier = bmt.accelerationMultiplier;
}
}
}
private void refreshStatBars(BoatMeshType bo) {
speedBar.setProgress((bo.maxSpeedMultiplier) / maxSpeedMultiplier);
accelBar.setProgress(bo.accelerationMultiplier / maxAccelerationMultiplier);
handleBar.setProgress(bo.turnStep / maxTurnRateMultiplier);
}
} }
@@ -2,21 +2,59 @@ package seng302.visualiser.fxObjects.assets_3D;
/** /**
* Enum for boat meshes. Enum values should be of the form : * Enum for boat meshes. Enum values should be of the form :
* ENUM_VALUE (hull file, mast file, Y offset of mast CoR from origin, sail file, Y offset of sail CoR from origin) * ENUM_VALUE (hull file, mast file, Y offset of mast CoR from origin, sail file, Y offset of sail CoR from origin, jib file, fixed sail)
* Files must be valid .stl files. * Files must be valid .stl files.
*/ */
public enum BoatMeshType { public enum BoatMeshType {
DINGHY ("dinghy_hull.stl", "dinghy_mast.stl", -1.36653, "dinghy_sail.stl", -1.36653); DINGHY("dinghy_hull.stl", "dinghy_mast.stl", 1.36653, "dinghy_sail.stl", 1.36653, null, false, 1.8, 1.0, 1.0),
CATAMARAN("catamaran_hull.stl", "catamaran_mast.stl", 0.997, "catamaran_sail.stl",
0.997, null, false, 1.0, 1.4, 2.0),
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);
final String hullFile, mastFile, sailFile; final String hullFile, mastFile, sailFile, jibFile;
final double mastOffset, sailOffset; final double mastOffset, sailOffset;
public final double maxSpeedMultiplier;
public final double accelerationMultiplier;
public final double turnStep;
final boolean fixedSail;
final static BoatMeshType[] boatTypes = new BoatMeshType[]{DINGHY, CATAMARAN, PIRATE_SHIP};
BoatMeshType(String hullFile, String mastFile, double mastOffset, String sailFile, double sailOffset) { BoatMeshType(String hullFile, String mastFile, double mastOffset, String sailFile,
double sailOffset, String jibFile, boolean fixedSail, double maxSpeedMultiplier, double accelerationMultiplier, double turnStep) {
this.hullFile = hullFile; this.hullFile = hullFile;
this.mastFile = mastFile; this.mastFile = mastFile;
this.mastOffset = mastOffset; this.mastOffset = mastOffset;
this.sailFile = sailFile; this.sailFile = sailFile;
this.sailOffset = sailOffset; this.sailOffset = sailOffset;
this.jibFile = jibFile;
this.fixedSail = fixedSail;
this.maxSpeedMultiplier = maxSpeedMultiplier;
this.accelerationMultiplier = accelerationMultiplier;
this.turnStep = turnStep;
}
public static BoatMeshType getNextBoatType(BoatMeshType boatType) {
for (int i = 0; i < boatTypes.length; i++) {
if (i == boatTypes.length -1) {
return boatTypes[0];
} else if (boatType == boatTypes[i]) {
return boatTypes[i+1];
}
}
return boatType;
}
public static BoatMeshType getPrevBoatType(BoatMeshType boatType) {
for (int i = 0; i < boatTypes.length; i++) {
if (i == 0 && boatType == boatTypes[i]) {
return boatTypes[boatTypes.length -1];
} else if (boatType == boatTypes[i]) {
return boatTypes[i-1];
}
}
return boatType;
} }
} }
@@ -34,15 +34,17 @@ public class BoatModel extends Model {
* @param degrees The rotation of the sail in degrees * @param degrees The rotation of the sail in degrees
*/ */
public void rotateSail(double degrees) { public void rotateSail(double degrees) {
if (!meshType.fixedSail) {
MeshView mast = getMeshViewChild(MAST_INDEX); MeshView mast = getMeshViewChild(MAST_INDEX);
MeshView sail = getMeshViewChild(SAIL_INDEX); MeshView sail = getMeshViewChild(SAIL_INDEX);
mast.getTransforms().setAll( mast.getTransforms().setAll(
new Rotate(degrees, -meshType.mastOffset, 0,0, new Point3D(0, 0, 1)) new Rotate(degrees, 0, -meshType.mastOffset, 0, new Point3D(0, 0, 1))
); );
sail.getTransforms().setAll( sail.getTransforms().setAll(
new Rotate(degrees, -meshType.sailOffset, 0,0, new Point3D(0, 0, 1)) new Rotate(degrees, 0, -meshType.sailOffset,0, new Point3D(0, 0, 1))
); );
} }
}
public void hideSail() { public void hideSail() {
getMeshViewChild(SAIL_INDEX).setVisible(false); getMeshViewChild(SAIL_INDEX).setVisible(false);
@@ -69,4 +71,8 @@ public class BoatModel extends Model {
private MeshView getMeshViewChild(int index) { private MeshView getMeshViewChild(int index) {
return (MeshView) assets.getChildren().get(index); return (MeshView) assets.getChildren().get(index);
} }
public BoatMeshType getMeshType() {
return meshType;
}
} }
@@ -11,7 +11,7 @@ import javafx.scene.transform.Rotate;
/** /**
* BoatGroup is a javafx group that by default contains a graphical objects for representing a 2 * BoatGroup is a javafx group that by default contains a graphical objects for representing a 2
* dimensional boat. It contains a single polygon for the boat, a group of lines to show it's path, * dimensional boat. It contains a single polygon for the boat, a group of lines to show it's path,
* a wake object and two text labels to annotate the boat teams name and the boats velocity. The * a wake object and two text labels to annotate the boat teams name and the boatTypes velocity. The
* boat will update it's position onscreen everytime UpdatePosition is called unless the window is * boat will update it's position onscreen everytime UpdatePosition is called unless the window is
* minimized in which case it attempts to store animations and apply them when the window is * minimized in which case it attempts to store animations and apply them when the window is
* maximised. * maximised.
@@ -28,15 +28,15 @@ public class BoatObject extends Group {
private Group wake; private Group wake;
private Color colour = Color.BLACK; private Color colour = Color.BLACK;
private Boolean isSelected = false; private Boolean isSelected = false;
private Rotate rotation = new Rotate(0,0,1); private Rotate rotation = new Rotate(0, new Point3D(0,0,1));
private List<SelectedBoatListener> selectedBoatListenerListeners = new ArrayList<>(); private List<SelectedBoatListener> selectedBoatListenerListeners = new ArrayList<>();
/** /**
* Creates a BoatGroup with the default triangular boat polygon. * Creates a BoatGroup with the default triangular boat polygon.
*/ */
public BoatObject() { public BoatObject(BoatMeshType boatMeshType) {
boatAssets = ModelFactory.boatGameView(BoatMeshType.DINGHY, colour); boatAssets = ModelFactory.boatGameView(boatMeshType, colour);
boatAssets.hideSail(); boatAssets.hideSail();
boatAssets.getAssets().getTransforms().addAll( boatAssets.getAssets().getTransforms().addAll(
rotation rotation
@@ -66,8 +66,6 @@ public class BoatObject extends Group {
* @param windDir . * @param windDir .
*/ */
public void moveTo(double x, double y, double rotation, double velocity, Boolean sailIn, double windDir) { public void moveTo(double x, double y, double rotation, double velocity, Boolean sailIn, double windDir) {
Double dx = Math.abs(boatAssets.getAssets().getLayoutX() - x);
Double dy = Math.abs(boatAssets.getAssets().getLayoutY() - y);
Platform.runLater(() -> { Platform.runLater(() -> {
rotateTo(rotation, sailIn, windDir); rotateTo(rotation, sailIn, windDir);
this.layoutXProperty().setValue(x); this.layoutXProperty().setValue(x);
@@ -7,6 +7,7 @@ import javafx.geometry.Point3D;
import javafx.scene.AmbientLight; import javafx.scene.AmbientLight;
import javafx.scene.CacheHint; import javafx.scene.CacheHint;
import javafx.scene.Group; import javafx.scene.Group;
import javafx.scene.PointLight;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial; import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Circle; import javafx.scene.shape.Circle;
@@ -18,7 +19,7 @@ import javafx.scene.transform.Translate;
/** /**
* Factory class for creating 3D models of boats. * Factory class for creating 3D models of boatTypes.
*/ */
public class ModelFactory { public class ModelFactory {
@@ -51,6 +52,35 @@ public class ModelFactory {
return bo; return bo;
} }
public static BoatModel boatCustomiseView(BoatMeshType boatType, Color primaryColour) {
Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour);
final Rotate animationRotate = new Rotate(0, new Point3D(0,0,1));
boatAssets.getTransforms().addAll(
new Scale(8.0, 8.0, 8.0),
new Rotate(-70, new Point3D(1,0,0)),
new Translate(16,50, 1),
animationRotate
);
boatAssets.getTransforms().add(animationRotate);
BoatModel bo = new BoatModel(boatAssets, null, boatType);
bo.rotateSail(45);
bo.setAnimation(new AnimationTimer() {
double boatAngle = 0;
Rotate rotate = animationRotate;
@Override
public void handle(long now) {
boatAngle += 0.5;
rotate.setAngle(boatAngle);
}
});
boatAssets.getChildren().addAll(
new AmbientLight()
);
return bo;
}
public static BoatModel boatRotatingView(BoatMeshType boatType, Color primaryColour) { public static BoatModel boatRotatingView(BoatMeshType boatType, Color primaryColour) {
Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour); Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour);
boatAssets.getTransforms().addAll( boatAssets.getTransforms().addAll(
@@ -84,20 +114,29 @@ public class ModelFactory {
} }
private static Group getUnmodifiedBoatModel(BoatMeshType boatType, Color primaryColour) { private static Group getUnmodifiedBoatModel(BoatMeshType boatType, Color primaryColour) {
Group boatAssets = new Group(); Group boatAssets = new Group();
MeshView hull = importFile(boatType.hullFile); MeshView hull = importSTL(boatType.hullFile);
hull.setMaterial(new PhongMaterial(primaryColour)); hull.setMaterial(new PhongMaterial(primaryColour));
MeshView mast = importFile(boatType.mastFile); MeshView mast = importSTL(boatType.mastFile);
mast.setMaterial(new PhongMaterial(primaryColour)); mast.setMaterial(new PhongMaterial(primaryColour));
MeshView sail = importFile(boatType.sailFile); MeshView sail = importSTL(boatType.sailFile);
sail.setMaterial(new PhongMaterial(Color.WHITE)); sail.setMaterial(new PhongMaterial(Color.WHITE));
if (boatType.jibFile != null) {
MeshView jib = importSTL(boatType.jibFile);
sail.setMaterial(new PhongMaterial(Color.WHITE));
boatAssets.getChildren().addAll(hull, mast, sail, jib);
} else {
boatAssets.getChildren().addAll(hull, mast, sail); boatAssets.getChildren().addAll(hull, mast, sail);
}
return boatAssets; return boatAssets;
} }
private static MeshView importFile(String fileName) { private static MeshView importSTL(String fileName) {
StlMeshImporter importer = new StlMeshImporter(); StlMeshImporter importer = new StlMeshImporter();
importer.read(ModelFactory.class.getResource("/meshes/" + fileName)); importer.read(ModelFactory.class.getResource("/meshes/boatSTLs/" + fileName));
MeshView importedFile = new MeshView(importer.getImport()); MeshView importedFile = new MeshView(importer.getImport());
importedFile.setCache(true); importedFile.setCache(true);
importedFile.setCacheHint(CacheHint.SCALE_AND_ROTATE); importedFile.setCacheHint(CacheHint.SCALE_AND_ROTATE);
@@ -1,108 +0,0 @@
package seng302.visualiser;
import com.interactivemesh.jfx.importer.stl.StlMeshImporter;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.MeshView;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
/**
* Created by cir27 on 7/09/17.
*/
public class test3d extends Application {
Group root = new Group();
Scene scene;
@Override
public void start(Stage primaryStage) throws Exception {
// camera = new PerspectiveCamera();
// gameObjects = new Group();
// root3D = new Group(camera, gameObjects);
scene = new Scene(
root, 1000, 1000, true, SceneAntialiasing.BALANCED
);
gameView3DTest();
primaryStage.setScene(scene);
primaryStage.show();
// scene.setCamera(camera);
// primaryStage.setScene(scene);
// primaryStage.show();
//
// StlMeshImporter importer = new StlMeshImporter();
// importer.read(test3d.class.getResource("/meshes/dinghy_hull.stl").toString());
// MeshView boat = new MeshView(importer.getImport());
// boat.setMaterial(new PhongMaterial(Color.GREENYELLOW));
//
// importer = new StlMeshImporter();
// importer.read(getClass().getResource("/meshes/dinghy_mast.stl").toString());
// MeshView mast = new MeshView(importer.getImport());
// mast.setMaterial(new PhongMaterial(Color.GREENYELLOW));
//
// importer = new StlMeshImporter();
// importer.read(getClass().getResource("/meshes/dinghy_sail.stl").toString());
// MeshView sail = new MeshView(importer.getImport());
// sail.setMaterial(new PhongMaterial(Color.LIGHTGREY));
//
// gameObjects.getChildren().addAll(boat, mast, sail);
//
// gameObjects.getTransforms().add(new Scale(25, 25,25));
// gameObjects.getTransforms().add(new Translate(15, 20,0));
// gameObjects.getTransforms().addAll(
// new Rotate(90, new Point3D(0,0,1)),
// new Rotate(90, new Point3D(0, 1, 0))
// );
//
//// PointLight light = new PointLight();
//// light.setLightOn(true);
//// light.getTransforms().add(new Translate(15, 20, 0));
////
//// PointLight light2 = new PointLight();
//// light2.setLightOn(true);
//// light2.getTransforms().add(new Translate(30, 40, 0));
//
//// root3D.getChildren().addAll(light);
//
// scene.setOnKeyPressed(event -> {
// switch (event.getCode()) {
// case UP:
// gameObjects.getTransforms().add(new Rotate(5, new Point3D(0,0,1)));
// break;
// case DOWN:
// gameObjects.getTransforms().add(new Rotate(-5, new Point3D(0,0,1)));
// break;
// case LEFT:
// gameObjects.getTransforms().add(new Rotate(-5, new Point3D(0,1,0)));
// break;
// case RIGHT:
// gameObjects.getTransforms().add(new Rotate(5, new Point3D(0,1,0)));
// break;
// }
// });
//
// AnimationTimer animationTimer = new AnimationTimer() {
// @Override
// public void handle(long now) {
// sail.getTransforms().add(new Rotate(0.5, 0, -1.36653, 0, new Point3D(0, 0, 1)));
// }
// };
//
//// animationTimer.start();
}
private void gameView3DTest() {
GameView3D gameView3D = new GameView3D();
root.getChildren().add(gameView3D.getAssets());
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -12,7 +12,7 @@
</BoatShapes> </BoatShapes>
<Boats> <Boats>
<#list boats as boat> <#list boats as boat>
<Boat Type="Yacht" SourceID="${boat.sourceId}" ShapeID="4" HullNum="${boat.hullID}" StoweName="${boat.shortName}" ShortName="${boat.shortName}" <Boat Type="${boat.boatType}" SourceID="${boat.sourceId}" ShapeID="4" HullNum="${boat.hullID}" StoweName="${boat.shortName}" ShortName="${boat.shortName}"
BoatName="${boat.boatName}" Country="${boat.country}" Color="${boat.boatColor}"> BoatName="${boat.boatName}" Country="${boat.country}" Color="${boat.boatColor}">
<GPSposition Z="0" Y="3.7" X="0" /> <GPSposition Z="0" Y="3.7" X="0" />
<MastTop Z="0" Y="6.2" X="0" /> <MastTop Z="0" Y="6.2" X="0" />
@@ -1,5 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import com.jfoenix.controls.*?>
<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import com.jfoenix.controls.JFXButton?> <?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXColorPicker?> <?import com.jfoenix.controls.JFXColorPicker?>
<?import com.jfoenix.controls.JFXDialogLayout?> <?import com.jfoenix.controls.JFXDialogLayout?>
@@ -10,52 +16,43 @@
<?import javafx.scene.layout.ColumnConstraints?> <?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?> <?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?> <?import javafx.scene.layout.RowConstraints?>
<JFXDialogLayout maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefWidth="400.0" xmlns="http://javafx.com/javafx/8" <JFXDialogLayout maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="400.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.dialogs.BoatCustomizeController">
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="seng302.visualiser.controllers.dialogs.BoatCustomizeController">
<children> <children>
<GridPane> <GridPane>
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints maxHeight="90.0" minHeight="90.0" prefHeight="90.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="90.0" minHeight="48.0" prefHeight="48.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="100.0" minHeight="100.0" prefHeight="100.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="207.0" minHeight="93.0" prefHeight="181.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="125.0" minHeight="61.0" prefHeight="99.0" <RowConstraints maxHeight="207.0" minHeight="93.0" prefHeight="181.0" vgrow="SOMETIMES" />
vgrow="SOMETIMES"/> <RowConstraints maxHeight="145.0" minHeight="66.0" prefHeight="109.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="164.0" minHeight="100.0" prefHeight="126.0" <RowConstraints maxHeight="125.0" minHeight="24.0" prefHeight="72.0" vgrow="SOMETIMES" />
vgrow="SOMETIMES"/> <RowConstraints maxHeight="164.0" minHeight="100.0" prefHeight="105.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<Label fx:id="hostDialogHeader" text="Customize Boat" GridPane.halignment="CENTER" <Label fx:id="hostDialogHeader" text="Customize Boat" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
GridPane.valignment="CENTER"/> <JFXButton fx:id="submitBtn" prefHeight="45.0" prefWidth="220.0" text="Customize Boat" GridPane.halignment="CENTER" GridPane.rowIndex="5" GridPane.valignment="CENTER" />
<JFXButton fx:id="submitBtn" prefHeight="45.0" prefWidth="220.0" text="Customize Boat" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="CENTER" /> <JFXTextField fx:id="boatName" focusColor="#6c6c6c" promptText="Boat Name" unFocusColor="#6b6b6b" GridPane.rowIndex="3">
<JFXTextField fx:id="boatName" focusColor="#6c6c6c" promptText="Boat Name"
unFocusColor="#6b6b6b" GridPane.rowIndex="1">
<GridPane.margin> <GridPane.margin>
<Insets left="30.0" right="30.0" /> <Insets left="30.0" right="30.0" />
</GridPane.margin></JFXTextField> </GridPane.margin></JFXTextField>
<GridPane GridPane.halignment="CENTER" GridPane.rowIndex="2" <GridPane GridPane.halignment="CENTER" GridPane.rowIndex="4" GridPane.valignment="CENTER">
GridPane.valignment="CENTER">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="139.0" minWidth="10.0" <ColumnConstraints hgrow="SOMETIMES" maxWidth="139.0" minWidth="10.0" prefWidth="94.0" />
prefWidth="94.0"/> <ColumnConstraints hgrow="SOMETIMES" maxWidth="203.0" minWidth="10.0" prefWidth="198.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="203.0" minWidth="10.0"
prefWidth="198.0"/>
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints percentHeight="100.0" valignment="CENTER" vgrow="SOMETIMES" /> <RowConstraints percentHeight="100.0" valignment="CENTER" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
<Label fx:id="boatColorLabel" prefHeight="25.0" prefWidth="96.0" <Label fx:id="boatColorLabel" prefHeight="25.0" prefWidth="96.0" text="Boat Color" GridPane.valignment="CENTER">
text="Boat Color" GridPane.valignment="CENTER">
<GridPane.margin> <GridPane.margin>
<Insets top="-10.0" /> <Insets top="-10.0" />
</GridPane.margin> </GridPane.margin>
</Label> </Label>
<JFXColorPicker fx:id="colorPicker" onAction="#colorChanged" <JFXColorPicker fx:id="colorPicker" onAction="#colorChanged" GridPane.columnIndex="1" GridPane.valignment="CENTER">
GridPane.columnIndex="1" GridPane.valignment="CENTER">
<GridPane.margin> <GridPane.margin>
<Insets left="30.0" top="-10.0" /> <Insets left="30.0" top="-10.0" />
</GridPane.margin> </GridPane.margin>
@@ -65,6 +62,40 @@
<Insets left="30.0" right="30.0" /> <Insets left="30.0" right="30.0" />
</GridPane.margin> </GridPane.margin>
</GridPane> </GridPane>
<GridPane GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="50.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="256.0" minWidth="10.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="50.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Pane fx:id="boatPane" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" />
<JFXButton buttonType="RAISED" onAction="#prevBoat" prefHeight="200.0" prefWidth="50.0" text="&lt;" />
<JFXButton buttonType="RAISED" onAction="#nextBoat" prefHeight="200.0" prefWidth="50.0" text="&gt;" GridPane.columnIndex="2" />
</children>
</GridPane>
<GridPane GridPane.rowIndex="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 minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Max Speed:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Acceleration:" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER" />
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Handling:" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER" />
<ProgressBar fx:id="speedBar" focusTraversable="false" prefWidth="200.0" progress="0.0" GridPane.columnIndex="1" />
<ProgressBar fx:id="accelBar" prefWidth="200.0" progress="0.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<ProgressBar fx:id="handleBar" prefWidth="200.0" progress="0.0" GridPane.columnIndex="1" GridPane.rowIndex="2" />
</children>
</GridPane>
</children> </children>
</GridPane> </GridPane>
</children> </children>
@@ -5,6 +5,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import seng302.gameServer.GameState; import seng302.gameServer.GameState;
import seng302.utilities.GeoUtility; import seng302.utilities.GeoUtility;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
import static seng302.gameServer.GameState.checkCollision; import static seng302.gameServer.GameState.checkCollision;
@@ -14,8 +15,10 @@ import static seng302.gameServer.GameState.checkCollision;
*/ */
public class UpdateYachtTest { public class UpdateYachtTest {
private ServerYacht yacht1 = new ServerYacht("Yacht", 1, "1", "Yacht" + 1, "Yacht" + 1, "Test1"); private ServerYacht yacht1 = new ServerYacht(BoatMeshType.DINGHY, 1, "1", "Yacht" + 1,
private ServerYacht yacht2 = new ServerYacht("Yacht", 2, "2", "Yacht" + 2, "Yacht" + 2, "Test2"); "Yacht" + 1, "Test1");
private ServerYacht yacht2 = new ServerYacht(BoatMeshType.DINGHY, 2, "2", "Yacht" + 2,
"Yacht" + 2, "Test2");
private GeoPoint geoPoint1 = new GeoPoint(50.0, 50.0); private GeoPoint geoPoint1 = new GeoPoint(50.0, 50.0);
private GeoPoint geoPoint2 = GeoUtility.getGeoCoordinate(geoPoint1, 90.0, 50.0); private GeoPoint geoPoint2 = GeoUtility.getGeoCoordinate(geoPoint1, 90.0, 50.0);
+2 -1
View File
@@ -4,6 +4,7 @@ import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import seng302.gameServer.GameState; import seng302.gameServer.GameState;
import seng302.model.ServerYacht; import seng302.model.ServerYacht;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
public class YachtTest { public class YachtTest {
@@ -17,7 +18,7 @@ public class YachtTest {
@BeforeClass @BeforeClass
public static void setUp() { public static void setUp() {
new GameState("localhost"); new GameState("localhost");
y1 = new ServerYacht("Yacht", 1, "Y1", "Y1", "Yacht 1", "C1"); y1 = new ServerYacht(BoatMeshType.DINGHY, 1, "Y1", "Y1", "Yacht 1", "C1");
gs = new GameState("localhost"); gs = new GameState("localhost");
} }
@@ -0,0 +1,28 @@
package seng302.utilities;
import org.junit.Assert;
import org.junit.Test;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
/**
* Basic tests for the next and previous methods
* Created by kre39 on 20/09/17.
*/
public class BoatMeshTypeTest {
@Test
public void testNextBoatMeshType() {
BoatMeshType currentBoat = BoatMeshType.DINGHY;
BoatMeshType nextBoat = BoatMeshType.getNextBoatType(currentBoat);
Assert.assertEquals(BoatMeshType.CATAMARAN, nextBoat);
}
@Test
public void testPreviousBoatMeshType() {
BoatMeshType currentBoat = BoatMeshType.CATAMARAN;
BoatMeshType prevBoat = BoatMeshType.getPrevBoatType(currentBoat);
Assert.assertEquals(BoatMeshType.DINGHY, prevBoat);
}
}
@@ -6,6 +6,7 @@ import static org.junit.Assert.assertTrue;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import seng302.model.ClientYacht; import seng302.model.ClientYacht;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
/** /**
* Created by kre39 on 6/08/17. * Created by kre39 on 6/08/17.
@@ -16,7 +17,7 @@ public class BoatSailAnimationToggleTest {
@Before @Before
public void setup() throws Exception{ public void setup() throws Exception{
yacht = new ClientYacht("Yacht", 1, "YACHT", "YAC", "Test Yacht", "NZ"); yacht = new ClientYacht(BoatMeshType.DINGHY, 1, "YACHT", "YAC", "Test Yacht", "NZ");
} }
@Test @Test
+1
View File
@@ -13,6 +13,7 @@ import seng302.model.ServerYacht;
import seng302.visualiser.ClientToServerThread; import seng302.visualiser.ClientToServerThread;
/** /**
*
* Created by kre39 on 7/08/17. * Created by kre39 on 7/08/17.
*/ */
public class ToggleSailSteps { public class ToggleSailSteps {