mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Merge branch 'develop' into issue47_disconnect_crash_rebranch
# Conflicts: # src/main/java/seng302/gameServer/ServerToClientThread.java # src/main/java/seng302/visualiser/ClientToServerThread.java # src/main/java/seng302/visualiser/GameClient.java
This commit is contained in:
@@ -6,6 +6,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -14,6 +15,7 @@ import org.w3c.dom.Document;
|
|||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import seng302.gameServer.messages.BoatAction;
|
import seng302.gameServer.messages.BoatAction;
|
||||||
import seng302.gameServer.messages.BoatStatus;
|
import seng302.gameServer.messages.BoatStatus;
|
||||||
|
import seng302.gameServer.messages.CustomizeRequestType;
|
||||||
import seng302.gameServer.messages.MarkRoundingMessage;
|
import seng302.gameServer.messages.MarkRoundingMessage;
|
||||||
import seng302.gameServer.messages.MarkType;
|
import seng302.gameServer.messages.MarkType;
|
||||||
import seng302.gameServer.messages.Message;
|
import seng302.gameServer.messages.Message;
|
||||||
@@ -36,6 +38,7 @@ import seng302.utilities.XMLParser;
|
|||||||
* Created by wmu16 on 10/07/17.
|
* Created by wmu16 on 10/07/17.
|
||||||
*/
|
*/
|
||||||
public class GameState implements Runnable {
|
public class GameState implements Runnable {
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
interface NewMessageListener {
|
interface NewMessageListener {
|
||||||
|
|
||||||
@@ -57,6 +60,8 @@ public class GameState implements Runnable {
|
|||||||
public static Double windDirection;
|
public static Double windDirection;
|
||||||
private static Double windSpeed;
|
private static Double windSpeed;
|
||||||
|
|
||||||
|
private static Boolean customizationFlag; // dirty flag to tell if a player has customized their boat.
|
||||||
|
|
||||||
private static String hostIpAddress;
|
private static String hostIpAddress;
|
||||||
private static List<Player> players;
|
private static List<Player> players;
|
||||||
private static Map<Integer, ServerYacht> yachts;
|
private static Map<Integer, ServerYacht> yachts;
|
||||||
@@ -88,6 +93,7 @@ public class GameState implements Runnable {
|
|||||||
yachts = new HashMap<>();
|
yachts = new HashMap<>();
|
||||||
players = new ArrayList<>();
|
players = new ArrayList<>();
|
||||||
GameState.hostIpAddress = hostIpAddress;
|
GameState.hostIpAddress = hostIpAddress;
|
||||||
|
customizationFlag = false;
|
||||||
|
|
||||||
currentStage = GameStages.LOBBYING;
|
currentStage = GameStages.LOBBYING;
|
||||||
isRaceStarted = false;
|
isRaceStarted = false;
|
||||||
@@ -414,7 +420,7 @@ public class GameState implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/** lobbyController.setPlayerListSource(clientLobbyList);
|
||||||
* 4 Different cases of progression in the race 1 - Passing the start line 2 - Passing any
|
* 4 Different cases of progression in the race 1 - Passing the start line 2 - Passing any
|
||||||
* in-race Gate 3 - Passing any in-race Mark 4 - Passing the finish line
|
* in-race Gate 3 - Passing any in-race Mark 4 - Passing the finish line
|
||||||
*
|
*
|
||||||
@@ -580,6 +586,28 @@ public class GameState implements Runnable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles player customization.
|
||||||
|
*
|
||||||
|
* @param playerID The ID of the player being modified.
|
||||||
|
* @param requestType the type of player customization the player wants
|
||||||
|
* @param customizeData the data related to the customization (color, name, shape)
|
||||||
|
*/
|
||||||
|
public static void customizePlayer(long playerID, CustomizeRequestType requestType,
|
||||||
|
byte[] customizeData) {
|
||||||
|
ServerYacht playerYacht = yachts.get((int) playerID);
|
||||||
|
|
||||||
|
if (requestType.equals(CustomizeRequestType.NAME)) {
|
||||||
|
String name = new String(customizeData);
|
||||||
|
playerYacht.setBoatName(name);
|
||||||
|
} else if (requestType.equals(CustomizeRequestType.COLOR)) {
|
||||||
|
int red = customizeData[0] & 0xFF;
|
||||||
|
int green = customizeData[1] & 0xFF;
|
||||||
|
int blue = customizeData[2] & 0xFF;
|
||||||
|
Color yachtColor = Color.rgb(red, green, blue);
|
||||||
|
playerYacht.setBoatColor(yachtColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Mark checkMarkCollision(ServerYacht yacht) {
|
private static Mark checkMarkCollision(ServerYacht yacht) {
|
||||||
Set<Mark> marksInRace = GameState.getMarks();
|
Set<Mark> marksInRace = GameState.getMarks();
|
||||||
@@ -659,4 +687,16 @@ public class GameState implements Runnable {
|
|||||||
public static void addMarkPassListener(NewMessageListener listener) {
|
public static void addMarkPassListener(NewMessageListener listener) {
|
||||||
markListeners.add(listener);
|
markListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setCustomizationFlag() {
|
||||||
|
customizationFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean getCustomizationFlag() {
|
||||||
|
return customizationFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resetCustomizationFlag() {
|
||||||
|
customizationFlag = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,14 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
|||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
serverLog("Interrupted exception in Main Server Thread thread sleep", 1);
|
serverLog("Interrupted exception in Main Server Thread thread sleep", 1);
|
||||||
}
|
}
|
||||||
|
if (GameState.getCurrentStage() == GameStages.LOBBYING && GameState
|
||||||
|
.getCustomizationFlag()) {
|
||||||
|
// TODO: 16/08/17 ajm412: This can probably be done in a nicer way via those fancy functional interfaces.
|
||||||
|
for (ServerToClientThread thread : serverToClientThreads) {
|
||||||
|
thread.sendSetupMessages();
|
||||||
|
}
|
||||||
|
GameState.resetCustomizationFlag();
|
||||||
|
}
|
||||||
|
|
||||||
if (GameState.getCurrentStage() == GameStages.PRE_RACE) {
|
if (GameState.getCurrentStage() == GameStages.PRE_RACE) {
|
||||||
updateClients();
|
updateClients();
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package seng302.gameServer;
|
package seng302.gameServer;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import seng302.gameServer.messages.BoatAction;
|
||||||
import seng302.gameServer.messages.ClientType;
|
import seng302.gameServer.messages.ClientType;
|
||||||
|
import seng302.gameServer.messages.CustomizeRequestType;
|
||||||
import seng302.gameServer.messages.Message;
|
import seng302.gameServer.messages.Message;
|
||||||
import seng302.model.stream.packets.StreamPacket;
|
import seng302.model.stream.packets.StreamPacket;
|
||||||
import seng302.gameServer.messages.BoatAction;
|
|
||||||
|
|
||||||
|
|
||||||
public class ServerPacketParser {
|
public class ServerPacketParser {
|
||||||
@@ -22,5 +22,11 @@ public class ServerPacketParser {
|
|||||||
long value = Message.bytesToLong(Arrays.copyOfRange(payload, 0, 1));
|
long value = Message.bytesToLong(Arrays.copyOfRange(payload, 0, 1));
|
||||||
return ClientType.getClientType((int) value);
|
return ClientType.getClientType((int) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static CustomizeRequestType extractCustomizationType(StreamPacket packet) {
|
||||||
|
byte[] payload = packet.getPayload();
|
||||||
|
long type = Message.bytesToLong(Arrays.copyOfRange(payload, 4, 5));
|
||||||
|
return CustomizeRequestType.getRequestType((int) type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import java.io.OutputStream;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
@@ -22,6 +23,24 @@ import org.slf4j.LoggerFactory;
|
|||||||
import seng302.gameServer.messages.BoatAction;
|
import seng302.gameServer.messages.BoatAction;
|
||||||
import seng302.gameServer.messages.BoatLocationMessage;
|
import seng302.gameServer.messages.BoatLocationMessage;
|
||||||
import seng302.gameServer.messages.ClientType;
|
import seng302.gameServer.messages.ClientType;
|
||||||
|
import seng302.gameServer.messages.CustomizeRequestType;
|
||||||
|
import seng302.gameServer.messages.Message;
|
||||||
|
import seng302.gameServer.messages.RegistrationResponseMessage;
|
||||||
|
import seng302.gameServer.messages.RegistrationResponseStatus;
|
||||||
|
import seng302.gameServer.messages.XMLMessage;
|
||||||
|
import seng302.gameServer.messages.XMLMessageSubType;
|
||||||
|
import seng302.gameServer.messages.YachtEventCodeMessage;
|
||||||
|
import seng302.gameServer.messages.YachtEventCodeMessage;
|
||||||
|
import seng302.model.Player;
|
||||||
|
import seng302.model.ServerYacht;
|
||||||
|
import seng302.model.stream.packets.PacketType;
|
||||||
|
import seng302.model.stream.packets.StreamPacket;
|
||||||
|
import seng302.model.stream.xml.generator.Race;
|
||||||
|
import seng302.model.stream.xml.generator.Regatta;
|
||||||
|
import seng302.utilities.XMLGenerator;
|
||||||
|
import seng302.gameServer.messages.BoatAction;
|
||||||
|
import seng302.gameServer.messages.BoatLocationMessage;
|
||||||
|
import seng302.gameServer.messages.ClientType;
|
||||||
import seng302.gameServer.messages.Message;
|
import seng302.gameServer.messages.Message;
|
||||||
import seng302.gameServer.messages.RegistrationResponseMessage;
|
import seng302.gameServer.messages.RegistrationResponseMessage;
|
||||||
import seng302.gameServer.messages.RegistrationResponseStatus;
|
import seng302.gameServer.messages.RegistrationResponseStatus;
|
||||||
@@ -206,6 +225,18 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
|
|
||||||
completeRegistration(requestedType);
|
completeRegistration(requestedType);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RACE_CUSTOMIZATION_REQUEST:
|
||||||
|
Long sourceID = Message
|
||||||
|
.bytesToLong(Arrays.copyOfRange(payload, 0, 3));
|
||||||
|
CustomizeRequestType requestType = ServerPacketParser
|
||||||
|
.extractCustomizationType(
|
||||||
|
new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||||
|
GameState.customizePlayer(sourceID, requestType,
|
||||||
|
Arrays.copyOfRange(payload, 6, payload.length));
|
||||||
|
GameState.setCustomizationFlag();
|
||||||
|
// TODO: 17/08/2017 ajm412: Send a response packet here, not really necessary until we do shapes.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.warn("Packet has been dropped", 1);
|
logger.warn("Packet has been dropped", 1);
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package seng302.gameServer.messages;
|
||||||
|
|
||||||
|
// TODO: 14/08/17 ajm412: this may eventually need adjusting due to conforming to the agreed spec.
|
||||||
|
public class CustomizeRequestMessage extends Message {
|
||||||
|
|
||||||
|
|
||||||
|
private static int MESSAGE_LENGTH = 6;
|
||||||
|
|
||||||
|
//Message fields
|
||||||
|
private CustomizeRequestType customizeType;
|
||||||
|
private Integer payloadLength;
|
||||||
|
|
||||||
|
public CustomizeRequestMessage(CustomizeRequestType customizeType, double sourceID,
|
||||||
|
byte[] payload) {
|
||||||
|
payloadLength = payload.length;
|
||||||
|
setHeader(new Header(MessageType.CUSTOMIZATION_REQUEST, 1, (short) getSize()));
|
||||||
|
allocateBuffer();
|
||||||
|
writeHeaderToBuffer();
|
||||||
|
|
||||||
|
|
||||||
|
putInt((int) sourceID, 4);
|
||||||
|
putInt((int) customizeType.getType(), 2);
|
||||||
|
putBytes(payload);
|
||||||
|
|
||||||
|
writeCRC();
|
||||||
|
rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return MESSAGE_LENGTH + payloadLength; // placeholder
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package seng302.gameServer.messages;
|
||||||
|
|
||||||
|
// TODO: 14/08/17 ajm412: this may eventually need adjusting due to conforming to the agreed spec.
|
||||||
|
public enum CustomizeRequestType {
|
||||||
|
NAME(0x00),
|
||||||
|
COLOR(0x01),
|
||||||
|
SHAPE(0x02);
|
||||||
|
|
||||||
|
private int type;
|
||||||
|
|
||||||
|
CustomizeRequestType(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CustomizeRequestType getRequestType(int typeCode) {
|
||||||
|
switch (typeCode) {
|
||||||
|
case 0x00:
|
||||||
|
return NAME;
|
||||||
|
case 0x01:
|
||||||
|
return COLOR;
|
||||||
|
case 0x02:
|
||||||
|
return SHAPE;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package seng302.gameServer.messages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ajm412 on 14/08/17.
|
||||||
|
*/
|
||||||
|
public class CustomizeResponseMessage extends Message {
|
||||||
|
|
||||||
|
private static int MESSAGE_LENGTH = 2;
|
||||||
|
|
||||||
|
public CustomizeResponseMessage(CustomizeResponseType responseType) {
|
||||||
|
setHeader(new Header(MessageType.CUSTOMIZATION_RESPONSE, 1, (short) getSize()));
|
||||||
|
|
||||||
|
allocateBuffer();
|
||||||
|
writeHeaderToBuffer();
|
||||||
|
|
||||||
|
putInt(responseType.getType(), 2);
|
||||||
|
|
||||||
|
writeCRC();
|
||||||
|
rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return MESSAGE_LENGTH; // placeholder
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package seng302.gameServer.messages;
|
||||||
|
|
||||||
|
// TODO: 14/08/17 ajm412: this may eventually need adjusting due to conforming to the agreed spec.
|
||||||
|
public enum CustomizeResponseType {
|
||||||
|
SUCCESS(0x00),
|
||||||
|
FAILURE(0x01),
|
||||||
|
FAILURE_MALFORMED_DATA(0x02),
|
||||||
|
FAILURE_INCOMPATIBLE(0x03);
|
||||||
|
|
||||||
|
private int type;
|
||||||
|
|
||||||
|
CustomizeResponseType(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CustomizeResponseType getResponseType(int typeCode) {
|
||||||
|
switch (typeCode) {
|
||||||
|
case 0x00:
|
||||||
|
return SUCCESS;
|
||||||
|
case 0x01:
|
||||||
|
return FAILURE;
|
||||||
|
case 0x02:
|
||||||
|
return FAILURE_MALFORMED_DATA;
|
||||||
|
case 0x03:
|
||||||
|
return FAILURE_INCOMPATIBLE;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,10 @@ public enum MessageType {
|
|||||||
AVERAGE_WIND(47),
|
AVERAGE_WIND(47),
|
||||||
BOAT_ACTION(100),
|
BOAT_ACTION(100),
|
||||||
REGISTRATION_REQUEST(101),
|
REGISTRATION_REQUEST(101),
|
||||||
REGISTRATION_RESPONSE(102);
|
REGISTRATION_RESPONSE(102),
|
||||||
|
CUSTOMIZATION_REQUEST(103),
|
||||||
|
CUSTOMIZATION_RESPONSE(104);
|
||||||
|
|
||||||
|
|
||||||
private int code;
|
private int code;
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ public class ClientYacht extends Observable {
|
|||||||
this.heading = 120.0; //In degrees
|
this.heading = 120.0; //In degrees
|
||||||
this.currentVelocity = 0d;
|
this.currentVelocity = 0d;
|
||||||
this.boatStatus = 1;
|
this.boatStatus = 1;
|
||||||
|
this.colour = Color.rgb(0, 0, 0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,12 +8,7 @@ import javafx.scene.paint.Color;
|
|||||||
public enum Colors {
|
public enum Colors {
|
||||||
RED, PERU, GOLD, GREEN, BLUE, PURPLE, DEEPPINK, GRAY;
|
RED, PERU, GOLD, GREEN, BLUE, PURPLE, DEEPPINK, GRAY;
|
||||||
|
|
||||||
static Integer index = 0;
|
public static Color getColor(Integer index) {
|
||||||
|
return Color.valueOf(values()[index].toString());
|
||||||
public static Color getColor() {
|
|
||||||
if (index == 8) {
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
return Color.valueOf(values()[index++].toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package seng302.model;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import seng302.gameServer.GameState;
|
import seng302.gameServer.GameState;
|
||||||
@@ -30,6 +31,8 @@ public class ServerYacht extends Observable {
|
|||||||
private String country;
|
private String country;
|
||||||
private BoatStatus boatStatus;
|
private BoatStatus boatStatus;
|
||||||
|
|
||||||
|
private Color boatColor;
|
||||||
|
|
||||||
|
|
||||||
//Location
|
//Location
|
||||||
private Double lastHeading;
|
private Double lastHeading;
|
||||||
@@ -67,6 +70,7 @@ public class ServerYacht extends Observable {
|
|||||||
this.currentVelocity = 0d; //in mms-1
|
this.currentVelocity = 0d; //in mms-1
|
||||||
this.currentMarkSeqID = 0;
|
this.currentMarkSeqID = 0;
|
||||||
this.legNumber = 0;
|
this.legNumber = 0;
|
||||||
|
this.boatColor = Colors.getColor(sourceId - 1);
|
||||||
|
|
||||||
this.hasEnteredRoundingZone = false;
|
this.hasEnteredRoundingZone = false;
|
||||||
this.hasPassedLine = false;
|
this.hasPassedLine = false;
|
||||||
@@ -300,6 +304,10 @@ public class ServerYacht extends Observable {
|
|||||||
return country;
|
return country;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBoatName(String name) {
|
||||||
|
boatName = name;
|
||||||
|
shortName = name.split(" ")[0];
|
||||||
|
}
|
||||||
|
|
||||||
public GeoPoint getLocation() {
|
public GeoPoint getLocation() {
|
||||||
return location;
|
return location;
|
||||||
@@ -391,4 +399,12 @@ public class ServerYacht extends Observable {
|
|||||||
return legNumber;
|
return legNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBoatColor(Color color) {
|
||||||
|
this.boatColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getBoatColor() {
|
||||||
|
return boatColor;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
package seng302.model.stream.packets;
|
package seng302.model.stream.packets;
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Kusal on 4/24/2017.
|
|
||||||
*/
|
|
||||||
public enum PacketType {
|
public enum PacketType {
|
||||||
HEARTBEAT,
|
HEARTBEAT,
|
||||||
RACE_STATUS,
|
RACE_STATUS,
|
||||||
@@ -21,7 +18,9 @@ public enum PacketType {
|
|||||||
BOAT_ACTION,
|
BOAT_ACTION,
|
||||||
OTHER,
|
OTHER,
|
||||||
RACE_REGISTRATION_REQUEST,
|
RACE_REGISTRATION_REQUEST,
|
||||||
RACE_REGISTRATION_RESPONSE;
|
RACE_REGISTRATION_RESPONSE,
|
||||||
|
RACE_CUSTOMIZATION_REQUEST,
|
||||||
|
RACE_CUSTOMIZATION_RESPONSE;
|
||||||
|
|
||||||
public static PacketType assignPacketType(int packetType, byte[] payload){
|
public static PacketType assignPacketType(int packetType, byte[] payload){
|
||||||
switch(packetType){
|
switch(packetType){
|
||||||
@@ -62,6 +61,10 @@ public enum PacketType {
|
|||||||
return RACE_REGISTRATION_REQUEST;
|
return RACE_REGISTRATION_REQUEST;
|
||||||
case 102:
|
case 102:
|
||||||
return RACE_REGISTRATION_RESPONSE;
|
return RACE_REGISTRATION_RESPONSE;
|
||||||
|
case 103:
|
||||||
|
return RACE_CUSTOMIZATION_REQUEST;
|
||||||
|
case 104:
|
||||||
|
return RACE_CUSTOMIZATION_RESPONSE;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
return OTHER;
|
return OTHER;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
@@ -142,6 +143,7 @@ public class XMLParser {
|
|||||||
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")));
|
||||||
if (yacht.getBoatType().equals("Yacht")) {
|
if (yacht.getBoatType().equals("Yacht")) {
|
||||||
competingBoats.put(yacht.getSourceId(), yacht);
|
competingBoats.put(yacht.getSourceId(), yacht);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ import org.slf4j.LoggerFactory;
|
|||||||
import seng302.gameServer.messages.BoatAction;
|
import seng302.gameServer.messages.BoatAction;
|
||||||
import seng302.gameServer.messages.BoatActionMessage;
|
import seng302.gameServer.messages.BoatActionMessage;
|
||||||
import seng302.gameServer.messages.ClientType;
|
import seng302.gameServer.messages.ClientType;
|
||||||
|
import seng302.gameServer.messages.CustomizeRequestMessage;
|
||||||
|
import seng302.gameServer.messages.CustomizeRequestType;
|
||||||
import seng302.gameServer.messages.Message;
|
import seng302.gameServer.messages.Message;
|
||||||
import seng302.gameServer.messages.RegistrationRequestMessage;
|
import seng302.gameServer.messages.RegistrationRequestMessage;
|
||||||
import seng302.gameServer.messages.RegistrationResponseStatus;
|
import seng302.gameServer.messages.RegistrationResponseStatus;
|
||||||
@@ -151,6 +153,17 @@ public class ClientToServerThread implements Runnable {
|
|||||||
closeSocket();
|
closeSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendCustomizationRequest(CustomizeRequestType reqType, byte[] payload) {
|
||||||
|
CustomizeRequestMessage requestMessage = new CustomizeRequestMessage(reqType, this.clientId, payload);
|
||||||
|
try {
|
||||||
|
os.write(requestMessage.getBuffer());
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Could not send customization request");
|
||||||
|
notifyDisconnectListeners("Could not communicate with server");
|
||||||
|
closeSocket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void notifyDisconnectListeners (String message) {
|
private void notifyDisconnectListeners (String message) {
|
||||||
if (socketOpen) {
|
if (socketOpen) {
|
||||||
for (DisconnectedFromHostListener listener : disconnectionListeners) {
|
for (DisconnectedFromHostListener listener : disconnectionListeners) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import seng302.gameServer.GameState;
|
|||||||
import seng302.gameServer.MainServerThread;
|
import seng302.gameServer.MainServerThread;
|
||||||
import seng302.gameServer.messages.BoatAction;
|
import seng302.gameServer.messages.BoatAction;
|
||||||
import seng302.gameServer.messages.BoatStatus;
|
import seng302.gameServer.messages.BoatStatus;
|
||||||
|
import seng302.gameServer.messages.BoatAction;
|
||||||
import seng302.model.ClientYacht;
|
import seng302.model.ClientYacht;
|
||||||
import seng302.model.RaceState;
|
import seng302.model.RaceState;
|
||||||
import seng302.model.stream.packets.StreamPacket;
|
import seng302.model.stream.packets.StreamPacket;
|
||||||
@@ -257,7 +258,7 @@ public class GameClient {
|
|||||||
);
|
);
|
||||||
clientLobbyList.clear();
|
clientLobbyList.clear();
|
||||||
allBoatsMap.forEach((id, boat) ->
|
allBoatsMap.forEach((id, boat) ->
|
||||||
clientLobbyList.add(id + " " + boat.getBoatName())
|
clientLobbyList.add(boat.getBoatName())
|
||||||
);
|
);
|
||||||
raceState.setBoats(allBoatsMap.values());
|
raceState.setBoats(allBoatsMap.values());
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import javafx.scene.shape.Circle;
|
|||||||
import javafx.scene.shape.Polygon;
|
import javafx.scene.shape.Polygon;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
import seng302.model.ClientYacht;
|
||||||
import seng302.gameServer.messages.RoundingSide;
|
import seng302.gameServer.messages.RoundingSide;
|
||||||
import seng302.model.ClientYacht;
|
import seng302.model.ClientYacht;
|
||||||
import seng302.model.Colors;
|
import seng302.model.Colors;
|
||||||
@@ -485,19 +486,19 @@ public class GameView extends Pane {
|
|||||||
public void setBoats(List<ClientYacht> yachts) {
|
public void setBoats(List<ClientYacht> yachts) {
|
||||||
BoatObject newBoat;
|
BoatObject newBoat;
|
||||||
final List<Group> wakes = new ArrayList<>();
|
final List<Group> wakes = new ArrayList<>();
|
||||||
for (ClientYacht yacht : yachts) {
|
for (ClientYacht clientYacht : yachts) {
|
||||||
Paint colour = Colors.getColor();
|
Paint colour = clientYacht.getColour();
|
||||||
newBoat = new BoatObject();
|
newBoat = new BoatObject();
|
||||||
newBoat.addSelectedBoatListener(this::setSelectedBoat);
|
newBoat.addSelectedBoatListener(this::setSelectedBoat);
|
||||||
newBoat.setFill(colour);
|
newBoat.setFill(colour);
|
||||||
boatObjects.put(yacht, newBoat);
|
boatObjects.put(clientYacht, newBoat);
|
||||||
createAndBindAnnotationBox(yacht, colour);
|
createAndBindAnnotationBox(clientYacht, colour);
|
||||||
// wakesGroup.getChildren().add(newBoat.getWake());
|
// wakesGroup.getChildren().add(newBoat.getWake());
|
||||||
wakes.add(newBoat.getWake());
|
wakes.add(newBoat.getWake());
|
||||||
boatObjectGroup.getChildren().add(newBoat);
|
boatObjectGroup.getChildren().add(newBoat);
|
||||||
trails.getChildren().add(newBoat.getTrail());
|
trails.getChildren().add(newBoat.getTrail());
|
||||||
// TODO: 1/08/17 Make this less vile to look at.
|
// TODO: 1/08/17 Make this less vile to look at.
|
||||||
yacht.addLocationListener((boat, lat, lon, heading, sailIn, velocity) -> {
|
clientYacht.addLocationListener((boat, lat, lon, heading, sailIn, velocity) -> {
|
||||||
BoatObject bo = boatObjects.get(boat);
|
BoatObject bo = boatObjects.get(boat);
|
||||||
Point2D p2d = findScaledXY(lat, lon);
|
Point2D p2d = findScaledXY(lat, lon);
|
||||||
bo.moveTo(p2d.getX(), p2d.getY(), heading, velocity, sailIn, windDir);
|
bo.moveTo(p2d.getX(), p2d.getY(), heading, velocity, sailIn, windDir);
|
||||||
@@ -518,11 +519,11 @@ public class GameView extends Pane {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAndBindAnnotationBox(ClientYacht yacht, Paint colour) {
|
private void createAndBindAnnotationBox(ClientYacht clientYacht, Paint colour) {
|
||||||
AnnotationBox newAnnotation = new AnnotationBox();
|
AnnotationBox newAnnotation = new AnnotationBox();
|
||||||
newAnnotation.setFill(colour);
|
newAnnotation.setFill(colour);
|
||||||
newAnnotation.addAnnotation(
|
newAnnotation.addAnnotation(
|
||||||
"name", "Player: " + yacht.getShortName()
|
"name", "Player: " + clientYacht.getShortName()
|
||||||
);
|
);
|
||||||
// newAnnotation.addAnnotation(
|
// newAnnotation.addAnnotation(
|
||||||
// "velocity",
|
// "velocity",
|
||||||
@@ -545,7 +546,7 @@ public class GameView extends Pane {
|
|||||||
// return format.format(time);
|
// return format.format(time);
|
||||||
// }
|
// }
|
||||||
// );
|
// );
|
||||||
annotations.put(yacht, newAnnotation);
|
annotations.put(clientYacht, newAnnotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawFps(Double fps) {
|
private void drawFps(Double fps) {
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package seng302.visualiser.controllers;
|
||||||
|
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.ColorPicker;
|
||||||
|
import javafx.scene.control.TextField;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import seng302.gameServer.messages.CustomizeRequestType;
|
||||||
|
import seng302.visualiser.ClientToServerThread;
|
||||||
|
|
||||||
|
public class CustomizationController {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private TextField nameField;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ColorPicker boatColorPicker;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Button customizeSubmit;
|
||||||
|
|
||||||
|
private LobbyController lc;
|
||||||
|
private ClientToServerThread socketThread;
|
||||||
|
private Stage windowStage;
|
||||||
|
|
||||||
|
public void initialize() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerThread(ClientToServerThread ctsThread) {
|
||||||
|
this.socketThread = ctsThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void submitCustomization() {
|
||||||
|
System.out.println("Attempting to send");
|
||||||
|
socketThread.sendCustomizationRequest(CustomizeRequestType.NAME, nameField.getText().getBytes());
|
||||||
|
// TODO: 16/08/17 ajm412: Turn colors into byte array.
|
||||||
|
Color color = boatColorPicker.getValue();
|
||||||
|
|
||||||
|
short red = (short) (color.getRed() * 255);
|
||||||
|
short green = (short) (color.getGreen() * 255);
|
||||||
|
short blue = (short) (color.getBlue() * 255);
|
||||||
|
|
||||||
|
byte[] colorArray = new byte[3];
|
||||||
|
|
||||||
|
colorArray[0] = (byte) red;
|
||||||
|
colorArray[1] = (byte) green;
|
||||||
|
colorArray[2] = (byte) blue;
|
||||||
|
|
||||||
|
socketThread.sendCustomizationRequest(CustomizeRequestType.COLOR, colorArray);
|
||||||
|
lc.setPlayersColor(color);
|
||||||
|
windowStage.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLobbyController(LobbyController lc) {
|
||||||
|
this.lc = lc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStage(Stage stage) {
|
||||||
|
this.windowStage = stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerName(String name) {
|
||||||
|
this.nameField.setText(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerColor(Color playerColor) {
|
||||||
|
this.boatColorPicker.setValue(playerColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,20 +1,29 @@
|
|||||||
package seng302.visualiser.controllers;
|
package seng302.visualiser.controllers;
|
||||||
|
|
||||||
import java.util.*;
|
import com.sun.media.jfxmedia.logging.Logger;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Parent;
|
||||||
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.TextArea;
|
import javafx.scene.control.TextArea;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
|
import javafx.stage.Stage;
|
||||||
import seng302.gameServer.GameStages;
|
import seng302.gameServer.GameStages;
|
||||||
import seng302.gameServer.GameState;
|
import seng302.gameServer.GameState;
|
||||||
|
import seng302.model.Colors;
|
||||||
import seng302.model.RaceState;
|
import seng302.model.RaceState;
|
||||||
import seng302.visualiser.GameClient;
|
import seng302.visualiser.ClientToServerThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class describing the actions of the lobby screen
|
* A class describing the actions of the lobby screen
|
||||||
@@ -37,6 +46,8 @@ public class LobbyController {
|
|||||||
@FXML
|
@FXML
|
||||||
private Button readyButton;
|
private Button readyButton;
|
||||||
@FXML
|
@FXML
|
||||||
|
private Button customizeButton;
|
||||||
|
@FXML
|
||||||
private TextArea playerOneTxt;
|
private TextArea playerOneTxt;
|
||||||
@FXML
|
@FXML
|
||||||
private TextArea playerTwoTxt;
|
private TextArea playerTwoTxt;
|
||||||
@@ -77,7 +88,14 @@ public class LobbyController {
|
|||||||
private List<TextArea> listViews = new ArrayList<>();
|
private List<TextArea> listViews = new ArrayList<>();
|
||||||
private RaceState raceState;
|
private RaceState raceState;
|
||||||
|
|
||||||
|
private ClientToServerThread socketThread;
|
||||||
|
|
||||||
|
private Stage customizeStage;
|
||||||
|
|
||||||
|
private Color playersColor;
|
||||||
|
|
||||||
private int MAX_NUM_PLAYERS = 8;
|
private int MAX_NUM_PLAYERS = 8;
|
||||||
|
private Integer playerID;
|
||||||
|
|
||||||
private List<LobbyCloseListener> lobbyListeners = new ArrayList<>();
|
private List<LobbyCloseListener> lobbyListeners = new ArrayList<>();
|
||||||
private ObservableList<String> players;
|
private ObservableList<String> players;
|
||||||
@@ -106,6 +124,9 @@ public class LobbyController {
|
|||||||
//Update players if one added.
|
//Update players if one added.
|
||||||
for (int i = 0; i < players.size(); i++) {
|
for (int i = 0; i < players.size(); i++) {
|
||||||
listViews.get(i).setText(players.get(i));
|
listViews.get(i).setText(players.get(i));
|
||||||
|
if (playerID == (i + 1)) {
|
||||||
|
listViews.get(i).setText(listViews.get(i).getText() + " (YOU)");
|
||||||
|
}
|
||||||
imageViews.get(i).setVisible(true);
|
imageViews.get(i).setVisible(true);
|
||||||
}
|
}
|
||||||
//Update empty text fields if player left.
|
//Update empty text fields if player left.
|
||||||
@@ -130,6 +151,37 @@ public class LobbyController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void customize() {
|
||||||
|
Parent root;
|
||||||
|
try {
|
||||||
|
FXMLLoader fxmlLoader = new FXMLLoader(LobbyController.class.getResource("/views/customizeView.fxml"));
|
||||||
|
root = fxmlLoader.load();
|
||||||
|
root.getStylesheets().add("/css/master.css");
|
||||||
|
customizeStage = new Stage();
|
||||||
|
customizeStage.setTitle("Customize Boat");
|
||||||
|
customizeStage.setScene(new Scene(root, 700, 450));
|
||||||
|
CustomizationController cc = fxmlLoader.getController();
|
||||||
|
cc.setServerThread(this.socketThread);
|
||||||
|
cc.setPlayerName(this.players.get(playerID - 1));
|
||||||
|
|
||||||
|
if (this.playersColor == null) {
|
||||||
|
this.playersColor = Colors.getColor(playerID - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
cc.setPlayerColor(this.playersColor);
|
||||||
|
cc.setStage(customizeStage); // pass the stage through so it can be closed later.
|
||||||
|
cc.setLobbyController(this);
|
||||||
|
customizeStage.show();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logger.logMsg(4, "Failed to load Customization View from resources.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSocketThread(ClientToServerThread thread) {
|
||||||
|
this.socketThread = thread;
|
||||||
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void leaveLobbyButtonPressed() {
|
public void leaveLobbyButtonPressed() {
|
||||||
// TODO: 10/07/17 wmu16 - Finish function!
|
// TODO: 10/07/17 wmu16 - Finish function!
|
||||||
@@ -146,6 +198,7 @@ public class LobbyController {
|
|||||||
|
|
||||||
for (LobbyCloseListener readyListener : lobbyListeners)
|
for (LobbyCloseListener readyListener : lobbyListeners)
|
||||||
readyListener.notify(CloseStatus.READY);
|
readyListener.notify(CloseStatus.READY);
|
||||||
|
customizeButton.setDisable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTitle (String title) {
|
public void setTitle (String title) {
|
||||||
@@ -168,8 +221,18 @@ public class LobbyController {
|
|||||||
Platform.runLater(this::updatePlayers);
|
Platform.runLater(this::updatePlayers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPlayerID(Integer id) {
|
||||||
|
playerID = id;
|
||||||
|
}
|
||||||
|
|
||||||
public void updateRaceState(RaceState raceState){
|
public void updateRaceState(RaceState raceState){
|
||||||
this.raceState = raceState;
|
this.raceState = raceState;
|
||||||
|
/*if (this.customizeStage != null) {
|
||||||
|
this.customizeStage.close();
|
||||||
|
}*/ // TODO: 17/08/17 ajm412: close the customization window if the host starts the game while customizing
|
||||||
|
if (!customizeButton.isDisabled()) {
|
||||||
|
customizeButton.setDisable(true);
|
||||||
|
}
|
||||||
timeUntilStart.setText("Starting in: " + raceState.getRaceTimeStr());
|
timeUntilStart.setText("Starting in: " + raceState.getRaceTimeStr());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,4 +240,9 @@ public class LobbyController {
|
|||||||
readyButton.setDisable(true);
|
readyButton.setDisable(true);
|
||||||
readyButton.setVisible(false);
|
readyButton.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPlayersColor(Color playerColor) {
|
||||||
|
this.playersColor = playerColor;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public class BoatObject extends Group {
|
|||||||
* @param y The Y coordinate to move the boat to
|
* @param y The Y coordinate to move the boat to
|
||||||
* @param rotation The rotation by which the boat moves
|
* @param rotation The rotation by which the boat moves
|
||||||
* @param velocity The velocity the boat is moving
|
* @param velocity The velocity the boat is moving
|
||||||
* @param sailIn
|
* @param sailIn Boolean to toggle sail state.
|
||||||
*/
|
*/
|
||||||
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(boatPoly.getLayoutX() - x);
|
Double dx = Math.abs(boatPoly.getLayoutX() - x);
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ Table
|
|||||||
-fx-text-fill: black;
|
-fx-text-fill: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*server thread */
|
||||||
.ui-table .column-header {
|
.ui-table .column-header {
|
||||||
-fx-background-color: transparent;
|
-fx-background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<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="Yacht" SourceID="${boat.sourceId}" ShapeID="4" HullNum="${boat.hullID}" StoweName="${boat.shortName}" ShortName="${boat.shortName}"
|
||||||
BoatName="${boat.boatName}" Country="${boat.country}">
|
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" />
|
||||||
</Boat>
|
</Boat>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
<GridPane prefHeight="166.0" prefWidth="1530.0" GridPane.rowIndex="2">
|
<GridPane prefHeight="166.0" prefWidth="1530.0" GridPane.rowIndex="2">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
|
<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>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<rowConstraints>
|
||||||
@@ -37,7 +38,8 @@
|
|||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<Button fx:id="readyButton" focusTraversable="false" mnemonicParsing="false" onAction="#readyButtonPressed" prefWidth="101.0" text="Ready" GridPane.halignment="CENTER" />
|
<Button fx:id="readyButton" focusTraversable="false" mnemonicParsing="false" onAction="#readyButtonPressed" prefWidth="101.0" text="Ready" GridPane.halignment="CENTER" />
|
||||||
<Button focusTraversable="false" mnemonicParsing="false" onAction="#leaveLobbyButtonPressed" text="Leave Lobby" GridPane.columnIndex="1" GridPane.halignment="CENTER" />
|
<Button focusTraversable="false" mnemonicParsing="false" onAction="#leaveLobbyButtonPressed" text="Leave Lobby" GridPane.columnIndex="2" GridPane.halignment="CENTER" />
|
||||||
|
<Button fx:id="customizeButton" focusTraversable="false" mnemonicParsing="false" onAction="#customize" text="Customization" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
|
||||||
</children>
|
</children>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
<GridPane GridPane.rowIndex="1">
|
<GridPane GridPane.rowIndex="1">
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.ColorPicker?>
|
||||||
|
<?import javafx.scene.control.TextField?>
|
||||||
|
<?import javafx.scene.layout.ColumnConstraints?>
|
||||||
|
<?import javafx.scene.layout.GridPane?>
|
||||||
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
|
<?import javafx.scene.text.Text?>
|
||||||
|
<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
|
||||||
|
prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: #2C2c36;"
|
||||||
|
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
|
||||||
|
fx:controller="seng302.visualiser.controllers.CustomizationController">
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints fillWidth="false" halignment="CENTER" hgrow="SOMETIMES"
|
||||||
|
maxWidth="1.7976931348623157E308" minWidth="1.0" percentWidth="10.0" prefWidth="1.0"/>
|
||||||
|
<ColumnConstraints fillWidth="false" halignment="CENTER" hgrow="SOMETIMES" maxWidth="299.0"
|
||||||
|
minWidth="10.0" percentWidth="30.0" prefWidth="299.0"/>
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="299.0" minWidth="10.0" percentWidth="50.0"
|
||||||
|
prefWidth="154.0"/>
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="123.0" minWidth="0.0" percentWidth="10.0"
|
||||||
|
prefWidth="122.0"/>
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints minHeight="10.0" percentHeight="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 minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
|
<RowConstraints minHeight="10.0" percentHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||||
|
</rowConstraints>
|
||||||
|
<children>
|
||||||
|
<TextField fx:id="nameField" maxWidth="200.0" minWidth="200.0" prefWidth="200.0"
|
||||||
|
GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="1"
|
||||||
|
GridPane.valignment="CENTER"/>
|
||||||
|
<ColorPicker fx:id="boatColorPicker" prefWidth="200.0" style="-fx-background-color: eeeeee;"
|
||||||
|
GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="2"
|
||||||
|
GridPane.valignment="CENTER"/>
|
||||||
|
<Text fill="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="Player Name"
|
||||||
|
GridPane.columnIndex="1" GridPane.rowIndex="1"/>
|
||||||
|
<Text fill="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="Boat Color"
|
||||||
|
GridPane.columnIndex="1" GridPane.rowIndex="2"/>
|
||||||
|
<Button fx:id="customizeSubmit" mnemonicParsing="false" onAction="#submitCustomization"
|
||||||
|
text="Submit" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="3"
|
||||||
|
GridPane.valignment="CENTER"/>
|
||||||
|
</children>
|
||||||
|
</GridPane>
|
||||||
@@ -12,7 +12,7 @@ public class ColorsTest {
|
|||||||
Color expectedColors[] = {Color.RED, Color.PERU, Color.GOLD, Color.GREEN, Color.BLUE,
|
Color expectedColors[] = {Color.RED, Color.PERU, Color.GOLD, Color.GREEN, Color.BLUE,
|
||||||
Color.PURPLE, Color.DEEPPINK, Color.GRAY};
|
Color.PURPLE, Color.DEEPPINK, Color.GRAY};
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
Assert.assertEquals(expectedColors[i], Colors.getColor());
|
Assert.assertEquals(expectedColors[i], Colors.getColor(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class YachtTest {
|
|||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() {
|
public static void setUp() {
|
||||||
y1 = new ServerYacht("Yacht", 101, "Y1", "Y1", "Yacht 1", "C1");
|
y1 = new ServerYacht("Yacht", 1, "Y1", "Y1", "Yacht 1", "C1");
|
||||||
gs = new GameState("localhost");
|
gs = new GameState("localhost");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user