diff --git a/src/main/java/lab/game/Level.java b/src/main/java/lab/game/Level.java index 234c52e50a544eff66ddf9ccd054f7b2d31f7014..d2c640cad83296540409464040940703c5cff6fd 100644 --- a/src/main/java/lab/game/Level.java +++ b/src/main/java/lab/game/Level.java @@ -1,5 +1,12 @@ package lab.game; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Comparator; @@ -14,6 +21,8 @@ import lombok.extern.log4j.Log4j2; @Log4j2 public class Level { + private Object entitiesLock = new Object(); + private boolean viewMode; private double width; @@ -51,11 +60,67 @@ public class Level { } public void startServer() { - // TODO: + new Thread(() -> { + try (ServerSocket listenSocket = new ServerSocket(4600)) { + while (!Thread.currentThread().isInterrupted()) { + try { + Socket client = listenSocket.accept(); + new Thread(() -> handleViewer(client), "Viewer handler").start(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + + }).start(); + } + + public void handleViewer(Socket client) { + try (OutputStream outputStream = client.getOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)) { + while (!Thread.currentThread().isInterrupted()) { + synchronized (entitiesLock) { + objectOutputStream.reset(); + synchronized (entitiesLock) { + objectOutputStream.writeObject(entities); + } + objectOutputStream.flush(); + } + sleepForWhile(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void sleepForWhile() { + try { + Thread.sleep(20); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } } public void connectToServer() { - // TODO: + new Thread(() -> { + try (Socket socketToServer = new Socket("localhost", 4600); + InputStream inputStream = socketToServer.getInputStream(); + ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) { + while (!Thread.currentThread().isInterrupted()) { + Object o = objectInputStream.readObject(); + if (o instanceof List l) { + synchronized (entitiesLock) { + entities = l; + } + } + } + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + + }).start(); } record MonsterDeadLog(LocalDateTime time, MyPoint position) { @@ -70,8 +135,10 @@ public class Level { public void draw(GraphicsContext gc) { gc.setFill(Color.WHITE); gc.clearRect(0, 0, width, height); - for (DrawableSimulable entity : entities) { - entity.draw(gc); + synchronized (entitiesLock) { + for (DrawableSimulable entity : entities) { + entity.draw(gc); + } } } @@ -79,15 +146,17 @@ public class Level { if (viewMode) { return; } - for (DrawableSimulable entity : entities) { - entity.simulate(delay); + synchronized (entitiesLock) { + for (DrawableSimulable entity : entities) { + entity.simulate(delay); + } + detectCollisions(); + entities.removeAll(entitiesToRemove); + entities.addAll(entitiesToAdd); + entitiesToAdd.clear(); + entitiesToRemove.clear(); + entities.sort(Comparator.comparing(DrawableSimulable::getZIndex)); } - detectCollisions(); - entities.removeAll(entitiesToRemove); - entities.addAll(entitiesToAdd); - entitiesToAdd.clear(); - entitiesToRemove.clear(); - entities.sort(Comparator.comparing(DrawableSimulable::getZIndex)); } private void detectCollisions() { diff --git a/src/main/java/lab/game/Monster.java b/src/main/java/lab/game/Monster.java index d9c27882a0fb51fd9dc31781b9cac72a7b65e7b2..2877a56c0375394c37862b7b82e71a55ea5d1d11 100644 --- a/src/main/java/lab/game/Monster.java +++ b/src/main/java/lab/game/Monster.java @@ -1,5 +1,6 @@ package lab.game; +import java.io.Serial; import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -14,13 +15,16 @@ import lab.Config; public class Monster extends WorldEntity implements Collisionable { + @Serial + private static final long serialVersionUID = 4227585479714088964L; + private static Logger log = LogManager.getLogger(Monster.class); private static final Random RANDOM = new Random(); private static Image image; private MyPoint speed; - private List<DeadListener> deadListeners = new ArrayList<>(); + private transient List<DeadListener> deadListeners = new ArrayList<>(); public Monster(Level level) { super(level, new MyPoint(0, 0), 100); diff --git a/src/main/java/lab/game/MyDimension.java b/src/main/java/lab/game/MyDimension.java index d76dfb2d145377badc1ebc26748cd66add897ba4..20cb459c8816555b7a83e5edc0765f62c651948a 100644 --- a/src/main/java/lab/game/MyDimension.java +++ b/src/main/java/lab/game/MyDimension.java @@ -1,5 +1,6 @@ package lab.game; +import java.io.Serial; import java.io.Serializable; import lombok.AllArgsConstructor; @@ -7,7 +8,10 @@ import lombok.Getter; @AllArgsConstructor @Getter -public class MyDimension { +public class MyDimension implements Serializable { + + @Serial + private static final long serialVersionUID = -4053578370437363200L; private double width; diff --git a/src/main/java/lab/game/MyPoint.java b/src/main/java/lab/game/MyPoint.java index 721a676cc1f3c5d7a2fbd4612c011591480b9965..265ed63439f69a47bc520d87dfcc70b9784bff2e 100644 --- a/src/main/java/lab/game/MyPoint.java +++ b/src/main/java/lab/game/MyPoint.java @@ -1,6 +1,12 @@ package lab.game; -public class MyPoint { +import java.io.Serial; +import java.io.Serializable; + +public class MyPoint implements Serializable { + + @Serial + private static final long serialVersionUID = 5131948780897974323L; public double x; public double y; diff --git a/src/main/java/lab/game/NicerObstacle.java b/src/main/java/lab/game/NicerObstacle.java index 140412ca3c9f0cd9a7bd54c4fd0d403988f7ad21..dc8138a5fd9a1fb9e855966663ad85c1edf58b95 100644 --- a/src/main/java/lab/game/NicerObstacle.java +++ b/src/main/java/lab/game/NicerObstacle.java @@ -1,10 +1,15 @@ package lab.game; +import java.io.Serial; + import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; public class NicerObstacle extends WorldEntity { + @Serial + private static final long serialVersionUID = -6623353377339746275L; + private static Image image; public NicerObstacle(Level level, MyPoint position) { @@ -12,18 +17,18 @@ public class NicerObstacle extends WorldEntity { } private static Image getImage() { - if (image == null) { + if(image == null){ image = new Image(NicerObstacle.class.getResourceAsStream("spike.gif")); } return image; } - + public void drawInternal(GraphicsContext gc) { gc.drawImage(getImage(), position.getX(), position.getY()); } public void simulate(double delay) { - /* nothing to do */ + /*nothing to do*/ } } diff --git a/src/main/java/lab/game/Obstacle.java b/src/main/java/lab/game/Obstacle.java index 4bc5a981ff3b3349cc41a32640267c5d650eb696..285fdb7e7d190fb4530381e99b74df1f30c0989a 100644 --- a/src/main/java/lab/game/Obstacle.java +++ b/src/main/java/lab/game/Obstacle.java @@ -1,11 +1,15 @@ package lab.game; +import java.io.Serial; + import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; import lab.Config; public class Obstacle extends WorldEntity { + @Serial + private static final long serialVersionUID = 3430702588557969248L; private MyDimension size; public Obstacle(Level level) { @@ -27,7 +31,7 @@ public class Obstacle extends WorldEntity { } public void simulate(double delay) { - /* nothing to do */ + /*nothing to do*/ } } diff --git a/src/main/java/lab/game/Player.java b/src/main/java/lab/game/Player.java index 1c84de4b3beaee839d217eb1d0d242e3e3e0947c..8ad0eda3ff0b64951e4bca29261c36d12ab0ca08 100644 --- a/src/main/java/lab/game/Player.java +++ b/src/main/java/lab/game/Player.java @@ -1,5 +1,6 @@ package lab.game; +import java.io.Serial; import java.util.Random; import javafx.geometry.Rectangle2D; @@ -12,6 +13,9 @@ import lab.Config; public class Player extends WorldEntity implements Collisionable { + @Serial + private static final long serialVersionUID = -4487836387706082936L; + private static final Random RANDOM = new Random(); private MyPoint speed; diff --git a/src/main/java/lab/game/WorldEntity.java b/src/main/java/lab/game/WorldEntity.java index 965ef45510c362cb3b4f82929e8fde32dcc6c699..067e052856e5a09a92410ab4f36ef6c78d5c8b38 100644 --- a/src/main/java/lab/game/WorldEntity.java +++ b/src/main/java/lab/game/WorldEntity.java @@ -1,10 +1,16 @@ package lab.game; +import java.io.Serial; +import java.io.Serializable; + import javafx.scene.canvas.GraphicsContext; -public abstract class WorldEntity implements DrawableSimulable { +public abstract class WorldEntity implements DrawableSimulable, Serializable { - protected final Level level; + @Serial + private static final long serialVersionUID = 2626363250832813659L; + + protected transient final Level level; protected MyPoint position; private int zIndex; @@ -36,5 +42,5 @@ public abstract class WorldEntity implements DrawableSimulable { public int getZIndex() { return zIndex; } - + }