mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Packets are sent out when collision happens and receiver is able to interpret and display as visual alert. Updated visual alert to looks better.
- Created yacht event code message to be sent out as packet. - Added observers to main server thread on yacht so when collision detected, main server thread will send out yacht event message to all server to client threads. - Updated collision visual alert using circle and animation timer. #story[1117]
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
package seng302.gameServer;
|
package seng302.gameServer;
|
||||||
|
|
||||||
|
import com.sun.corba.se.spi.activation.Server;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import seng302.model.GeoPoint;
|
import seng302.model.GeoPoint;
|
||||||
@@ -18,7 +20,8 @@ import seng302.visualiser.GameClient;
|
|||||||
* A class describing the overall server, which creates and collects server threads for each client
|
* A class describing the overall server, which creates and collects server threads for each client
|
||||||
* Created by wmu16 on 13/07/17.
|
* Created by wmu16 on 13/07/17.
|
||||||
*/
|
*/
|
||||||
public class MainServerThread extends Observable implements Runnable, ClientConnectionDelegate {
|
public class MainServerThread extends Observable implements Runnable, ClientConnectionDelegate,
|
||||||
|
Observer {
|
||||||
|
|
||||||
private static final int PORT = 4942;
|
private static final int PORT = 4942;
|
||||||
private static final Integer CLIENT_UPDATES_PER_SECOND = 10;
|
private static final Integer CLIENT_UPDATES_PER_SECOND = 10;
|
||||||
@@ -112,7 +115,7 @@ public class MainServerThread extends Observable implements Runnable, ClientConn
|
|||||||
serverToClientThreads.add(serverToClientThread);
|
serverToClientThreads.add(serverToClientThread);
|
||||||
this.addObserver(serverToClientThread);
|
this.addObserver(serverToClientThread);
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers();
|
notifyObservers("send setup message");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -136,11 +139,12 @@ public class MainServerThread extends Observable implements Runnable, ClientConn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers();
|
notifyObservers("send setup message");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startGame() {
|
public void startGame() {
|
||||||
initialiseBoatPositions();
|
initialiseBoatPositions();
|
||||||
|
setupYachtObserver();
|
||||||
|
|
||||||
Timer t = new Timer();
|
Timer t = new Timer();
|
||||||
|
|
||||||
@@ -210,4 +214,17 @@ public class MainServerThread extends Observable implements Runnable, ClientConn
|
|||||||
boatIndex++;
|
boatIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Observable o, Object arg) {
|
||||||
|
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
|
||||||
|
serverToClientThread.sendCollisionMessage((Integer) arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupYachtObserver() {
|
||||||
|
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
|
||||||
|
serverToClientThread.getYacht().addObserver(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import java.util.concurrent.ThreadLocalRandom;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
import java.util.zip.Checksum;
|
import java.util.zip.Checksum;
|
||||||
|
import seng302.gameServer.server.messages.YachtEventCodeMessage;
|
||||||
import seng302.model.Player;
|
import seng302.model.Player;
|
||||||
import seng302.model.Yacht;
|
import seng302.model.Yacht;
|
||||||
import seng302.model.stream.packets.PacketType;
|
import seng302.model.stream.packets.PacketType;
|
||||||
@@ -126,8 +127,10 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Observable o, Object arg) {
|
public void update(Observable o, Object arg) {
|
||||||
|
if (arg.equals("send setup message")) {
|
||||||
sendSetupMessages();
|
sendSetupMessages();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
int sync1;
|
int sync1;
|
||||||
@@ -372,4 +375,8 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
public Yacht getYacht() {
|
public Yacht getYacht() {
|
||||||
return yacht;
|
return yacht;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendCollisionMessage(Integer yachtId) {
|
||||||
|
sendMessage(new YachtEventCodeMessage(yachtId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by zyt10 on 10/08/17.
|
||||||
|
*/
|
||||||
|
public class YachtEventCodeMessage extends Message {
|
||||||
|
|
||||||
|
private final MessageType MESSAGE_TYPE = MessageType.YACHT_EVENT_CODE;
|
||||||
|
private final int MESSAGE_VERSION = 1; //Always set to 1
|
||||||
|
private final int MESSAGE_SIZE = 22;
|
||||||
|
|
||||||
|
// Message fields
|
||||||
|
private long timeStamp;
|
||||||
|
private long ack = 0x00; //Unused
|
||||||
|
private int raceId;
|
||||||
|
private int destSourceId;
|
||||||
|
private int incidentId;
|
||||||
|
private int eventId;
|
||||||
|
|
||||||
|
|
||||||
|
public YachtEventCodeMessage(Integer subjectId) {
|
||||||
|
timeStamp = System.currentTimeMillis() / 1000L;
|
||||||
|
ack = 0;
|
||||||
|
raceId = 1;
|
||||||
|
destSourceId = subjectId; // collision boat source id
|
||||||
|
incidentId = 0;
|
||||||
|
eventId = 33;
|
||||||
|
|
||||||
|
setHeader(new Header(MESSAGE_TYPE, 0x01, (short) getSize()));
|
||||||
|
allocateBuffer();
|
||||||
|
writeHeaderToBuffer();
|
||||||
|
|
||||||
|
// Write message fields
|
||||||
|
putUnsignedByte((byte) MESSAGE_VERSION);
|
||||||
|
putInt((int) timeStamp, 6);
|
||||||
|
putInt((int) ack, 2);
|
||||||
|
putInt((int) raceId, 4);
|
||||||
|
putInt((int) destSourceId, 4);
|
||||||
|
putInt((int) incidentId, 4);
|
||||||
|
putInt((int) eventId, 1);
|
||||||
|
|
||||||
|
writeCRC();
|
||||||
|
rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The length of this message
|
||||||
|
*/
|
||||||
|
public int getSize() {
|
||||||
|
return MESSAGE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.Observable;
|
||||||
|
|
||||||
import static seng302.utilities.GeoUtility.getGeoCoordinate;
|
import static seng302.utilities.GeoUtility.getGeoCoordinate;
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ import static seng302.utilities.GeoUtility.getGeoCoordinate;
|
|||||||
* Class created to store more variables (eg. boat statuses) compared to the XMLParser boat class,
|
* Class created to store more variables (eg. boat statuses) compared to the XMLParser boat class,
|
||||||
* also done outside Boat class because some old variables are not used anymore.
|
* also done outside Boat class because some old variables are not used anymore.
|
||||||
*/
|
*/
|
||||||
public class Yacht {
|
public class Yacht extends Observable {
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface YachtLocationListener {
|
public interface YachtLocationListener {
|
||||||
@@ -148,8 +149,15 @@ public class Yacht {
|
|||||||
if (shouldDoCollisionUpdate()){
|
if (shouldDoCollisionUpdate()){
|
||||||
Yacht collidedYacht = checkCollision(calculatedPoint);
|
Yacht collidedYacht = checkCollision(calculatedPoint);
|
||||||
|
|
||||||
if (collidedYacht != null || markCollidedWith() != null) {
|
if (collidedYacht != null) {
|
||||||
|
location = calculateBounceBack(new GeoPoint(collidedYacht.getLocation().getLat(),
|
||||||
|
collidedYacht.getLocation().getLng()));
|
||||||
|
setChanged();
|
||||||
|
notifyObservers(this.sourceId);
|
||||||
|
} else if (markCollidedWith() != null) {
|
||||||
location = calculateBounceBack(new GeoPoint(markCollidedWith().getLat(), markCollidedWith().getLng()));
|
location = calculateBounceBack(new GeoPoint(markCollidedWith().getLat(), markCollidedWith().getLng()));
|
||||||
|
setChanged();
|
||||||
|
notifyObservers(this.sourceId);
|
||||||
} else {
|
} else {
|
||||||
location = calculatedPoint;
|
location = calculatedPoint;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -342,8 +342,8 @@ public class GameClient {
|
|||||||
* Tells race view to show a collision animation.
|
* Tells race view to show a collision animation.
|
||||||
*/
|
*/
|
||||||
private void showCollisionAlert(YachtEventData yachtEventData) {
|
private void showCollisionAlert(YachtEventData yachtEventData) {
|
||||||
// 1 is used by team 28 to show collision
|
// 33 is the agreed code to show collision
|
||||||
if (yachtEventData.getEventId() == 1) {
|
if (yachtEventData.getEventId() == 33) {
|
||||||
raceView.showCollision(yachtEventData.getSubjectId());
|
raceView.showCollision(yachtEventData.getSubjectId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,16 @@ import java.util.Comparator;
|
|||||||
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 java.util.concurrent.atomic.AtomicInteger;
|
||||||
import javafx.animation.Animation;
|
import javafx.animation.Animation;
|
||||||
import javafx.animation.AnimationTimer;
|
import javafx.animation.AnimationTimer;
|
||||||
import javafx.animation.KeyFrame;
|
import javafx.animation.KeyFrame;
|
||||||
|
import javafx.animation.KeyValue;
|
||||||
import javafx.animation.Timeline;
|
import javafx.animation.Timeline;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.event.Event;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.geometry.Point2D;
|
import javafx.geometry.Point2D;
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
@@ -24,6 +27,7 @@ import javafx.scene.paint.Color;
|
|||||||
import javafx.scene.paint.Paint;
|
import javafx.scene.paint.Paint;
|
||||||
import javafx.scene.shape.Circle;
|
import javafx.scene.shape.Circle;
|
||||||
import javafx.scene.shape.Polygon;
|
import javafx.scene.shape.Polygon;
|
||||||
|
import javafx.scene.shape.StrokeType;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import seng302.model.Colors;
|
import seng302.model.Colors;
|
||||||
@@ -616,26 +620,32 @@ public class GameView extends Pane {
|
|||||||
*/
|
*/
|
||||||
public void drawCollision(GeoPoint collisionPoint) {
|
public void drawCollision(GeoPoint collisionPoint) {
|
||||||
System.out.println("ran");
|
System.out.println("ran");
|
||||||
|
Platform.runLater(() -> {
|
||||||
Point2D point = findScaledXY(collisionPoint);
|
Point2D point = findScaledXY(collisionPoint);
|
||||||
Circle circle = new Circle(point.getX(), point.getY(), 10.0, Color.RED);
|
double circleRadius = 0.0;
|
||||||
|
Circle circle = new Circle(point.getX(), point.getY(), circleRadius, Color.RED);
|
||||||
gameObjects.add(circle);
|
gameObjects.add(circle);
|
||||||
|
|
||||||
|
circle.setFill(Color.TRANSPARENT);
|
||||||
|
circle.setStroke(Color.RED);
|
||||||
|
circle.setStrokeWidth(3);
|
||||||
|
|
||||||
Timeline timeline = new Timeline();
|
Timeline timeline = new Timeline();
|
||||||
timeline.setCycleCount(1);
|
timeline.setCycleCount(1);
|
||||||
EventHandler<ActionEvent> blink = (ActionEvent event) -> {
|
|
||||||
if (circle.getFill() == Color.RED) {
|
|
||||||
circle.setFill(Color.TRANSPARENT);
|
|
||||||
} else {
|
|
||||||
circle.setFill(Color.RED);
|
|
||||||
}
|
|
||||||
System.out.println("beep boop");
|
|
||||||
};
|
|
||||||
|
|
||||||
KeyFrame keyframe = new KeyFrame(Duration.millis(200), blink);
|
KeyFrame keyframe1 = new KeyFrame(Duration.ZERO,
|
||||||
|
new KeyValue(circle.radiusProperty(), 0),
|
||||||
|
new KeyValue(circle.strokeProperty(), Color.TRANSPARENT));
|
||||||
|
KeyFrame keyFrame2 = new KeyFrame(new Duration(1000),
|
||||||
|
new KeyValue(circle.radiusProperty(), 50),
|
||||||
|
new KeyValue(circle.strokeProperty(), Color.RED));
|
||||||
|
KeyFrame keyFrame3 = new KeyFrame(new Duration(1500),
|
||||||
|
new KeyValue(circle.strokeProperty(), Color.TRANSPARENT));
|
||||||
|
|
||||||
timeline.getKeyFrames().add(keyframe);
|
timeline.getKeyFrames().addAll(keyframe1, keyFrame2, keyFrame3);
|
||||||
timeline.play();
|
timeline.play();
|
||||||
|
|
||||||
// gameObjects.remove(circle);
|
timeline.setOnFinished(event -> gameObjects.remove(circle));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user