diff --git a/src/main/java/lab/game/Bullet.java b/src/main/java/lab/game/Bullet.java index dae49cb0530168e912dfa57b0a92219f4e825e00..59537e0967c1dbf06c87996b0a4f783730eb7fae 100644 --- a/src/main/java/lab/game/Bullet.java +++ b/src/main/java/lab/game/Bullet.java @@ -1,11 +1,16 @@ package lab.game; +import java.io.Serial; + import javafx.geometry.Rectangle2D; import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; public class Bullet extends WorldEntity implements Collisionable{ + @Serial + private static final long serialVersionUID = -3773585484081897646L; + private static final double SIZE = 20; protected final MyPoint acceleration; diff --git a/src/main/java/lab/game/BulletAnimated.java b/src/main/java/lab/game/BulletAnimated.java index e4a9a118f8cbdf8bd1e9c254d93e76acbe4c356a..99532f0e1820b0b29706333815fb283d8ba992ba 100644 --- a/src/main/java/lab/game/BulletAnimated.java +++ b/src/main/java/lab/game/BulletAnimated.java @@ -1,5 +1,6 @@ package lab.game; +import java.io.Serial; import java.util.ArrayList; import java.util.List; @@ -8,11 +9,14 @@ import javafx.scene.image.Image; public class BulletAnimated extends Bullet { + @Serial + private static final long serialVersionUID = 4366455699671618979L; + private static final double SIZE = 40; private Cannon cannon; private static Image image = new Image(BulletAnimated.class.getResourceAsStream("fireball-transparent.gif")); - private List<HitListener> hitListeners = new ArrayList<>(); + private transient List<HitListener> hitListeners = new ArrayList<>(); public BulletAnimated(World world, Cannon cannon, MyPoint position, MyPoint velocity, MyPoint acceleration) { super(world, position, velocity, acceleration); diff --git a/src/main/java/lab/game/Cannon.java b/src/main/java/lab/game/Cannon.java index d9a98063aa198b12c2d58f1f673d875286bb2e95..064f81e1e23996a2056e68bb95a9e578b3986843 100644 --- a/src/main/java/lab/game/Cannon.java +++ b/src/main/java/lab/game/Cannon.java @@ -1,5 +1,7 @@ package lab.game; +import java.io.Serial; + import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; import javafx.scene.transform.Affine; @@ -7,6 +9,9 @@ import javafx.scene.transform.Transform; public class Cannon extends WorldEntity { + @Serial + private static final long serialVersionUID = 2092588800016758726L; + private static final double LENGTH = 60; private static final double WIDTH = 15; private double angle; @@ -25,7 +30,7 @@ public class Cannon extends WorldEntity { @Override public void simulate(double deltaT) { - /* nothing to do */ + /*nothing to do*/ } public double getAngle() { diff --git a/src/main/java/lab/game/Ufo.java b/src/main/java/lab/game/Ufo.java index 6aff6f0cbe536dd9db0dce2602567407b49c5aae..bc5116851fd4556a55c6521f76d5f10a313f809f 100644 --- a/src/main/java/lab/game/Ufo.java +++ b/src/main/java/lab/game/Ufo.java @@ -1,5 +1,6 @@ package lab.game; +import java.io.Serial; import java.time.LocalDateTime; import java.util.Random; @@ -13,6 +14,9 @@ import lab.Setting; public class Ufo extends WorldEntity implements Collisionable { + @Serial + private static final long serialVersionUID = -2830189192945805617L; + private static Logger log = LogManager.getLogger(Ufo.class); private static final Random RANDOM = new Random(); diff --git a/src/main/java/lab/game/World.java b/src/main/java/lab/game/World.java index d2cb07af8d6430bb11b8e987346fb263757e5c13..b649853d27bc1397f5ec7e230049e2fa4877baa1 100644 --- a/src/main/java/lab/game/World.java +++ b/src/main/java/lab/game/World.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.util.ArrayList; import java.util.Collection; import java.util.LinkedList; @@ -18,6 +25,8 @@ public class World { private final double height; + private Object entitiesLock = new Object(); + private List<DrawableSimulable> entities; private Collection<DrawableSimulable> entitiesToRemove = new LinkedList<>(); private Collection<DrawableSimulable> entitiesToAdd = new LinkedList<>(); @@ -50,11 +59,65 @@ public class World { } 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(); + 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(); } public void add(UfoDestroyLog ufoDestroyLog) { @@ -71,8 +134,10 @@ public class World { gc.clearRect(0, 0, width, height); gc.save(); - for (DrawableSimulable entity : entities) { - entity.draw(gc); + synchronized (entitiesLock) { + for (DrawableSimulable entity : entities) { + entity.draw(gc); + } } gc.restore(); } @@ -81,14 +146,16 @@ public class World { if (viewMode) { return; } - for (DrawableSimulable entity : entities) { - entity.simulate(deltaT); + synchronized (entitiesLock) { + for (DrawableSimulable entity : entities) { + entity.simulate(deltaT); + } + detectCollision(); + entities.removeAll(entitiesToRemove); + entities.addAll(entitiesToAdd); + entitiesToAdd.clear(); + entitiesToRemove.clear(); } - detectCollision(); - entities.removeAll(entitiesToRemove); - entities.addAll(entitiesToAdd); - entitiesToAdd.clear(); - entitiesToRemove.clear(); } private void detectCollision() { diff --git a/src/main/java/lab/game/WorldEntity.java b/src/main/java/lab/game/WorldEntity.java index 7ab784afe5c1fe453f70d4204ec39e47dc6840bb..8bcfb3870bacf76f706232d7494ff416e5e3a765 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 World world; + @Serial + private static final long serialVersionUID = -8041266267302181620L; + + protected final transient World world; protected MyPoint position; protected WorldEntity(World world, MyPoint position) {