From e06b33a400b2425bee0cfc35598c726644df12c8 Mon Sep 17 00:00:00 2001
From: jez04 <david.jezek@post.cz>
Date: Thu, 17 Apr 2025 02:46:45 +0200
Subject: [PATCH] feat: assignment lab 09

---
 src/main/java/lab/Setup.java              |  2 -
 src/main/java/lab/game/Background.java    | 67 +++++++++--------
 src/main/java/lab/game/Boat.java          | 29 +++++---
 src/main/java/lab/game/LochNess.java      | 36 +++++----
 src/main/java/lab/game/MyDimension.java   | 14 ++++
 src/main/java/lab/game/MyPoint.java       | 58 +++++++++++++++
 src/main/java/lab/game/Rock.java          | 15 ++--
 src/main/java/lab/game/Scene.java         | 91 ++++++++++++++++-------
 src/main/java/lab/game/WorldEntity.java   |  7 +-
 src/main/java/lab/gui/App.java            | 39 +++++-----
 src/main/java/lab/gui/GameController.java |  7 +-
 11 files changed, 242 insertions(+), 123 deletions(-)
 create mode 100644 src/main/java/lab/game/MyDimension.java
 create mode 100644 src/main/java/lab/game/MyPoint.java

diff --git a/src/main/java/lab/Setup.java b/src/main/java/lab/Setup.java
index 84caa5c..d1f4b9e 100644
--- a/src/main/java/lab/Setup.java
+++ b/src/main/java/lab/Setup.java
@@ -1,6 +1,5 @@
 package lab;
 
-import jakarta.persistence.Entity;
 import lab.storage.DbConnector;
 import lab.storage.ScoreStorageInterface;
 import lombok.AllArgsConstructor;
@@ -8,7 +7,6 @@ import lombok.Builder;
 import lombok.Builder.Default;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
-import lombok.NoArgsConstructor;
 import lombok.ToString;
 
 @Getter
diff --git a/src/main/java/lab/game/Background.java b/src/main/java/lab/game/Background.java
index 56db1d7..0f718ac 100644
--- a/src/main/java/lab/game/Background.java
+++ b/src/main/java/lab/game/Background.java
@@ -1,61 +1,68 @@
 package lab.game;
 
-import javafx.geometry.Point2D;
 import javafx.scene.canvas.GraphicsContext;
 import javafx.scene.image.Image;
 import javafx.scene.paint.Color;
 
 public class Background extends WorldEntity {
 
-	private Point2D[] imagePosition;
-	private Image[] image;
-	private Point2D speed;
+	private MyPoint[] imagePosition;
+	private static Image[] image;
+	private MyPoint speed;
+	private MyDimension sceneSize; 
 	private static final double[] speedMultiplier = new double[] { 0.6, 0.8, 1, 1 };
 
 	public Background(Scene scene) {
-		super(scene, new Point2D(0, 0), 0);
-		image = new Image[4];
-		imagePosition = new Point2D[4];
-		image[0] = new Image(Background.class.getResourceAsStream("cityfar400.png"));
-		image[1] = new Image(Background.class.getResourceAsStream("citymid400.png"));
-		image[2] = new Image(Background.class.getResourceAsStream("cityclose400.png"));
-		image[3] = new Image(Background.class.getResourceAsStream("cityreflection400.png"));
-		imagePosition[0] = new Point2D(0, image[0].getHeight() - scene.getSize().getHeight());
-		imagePosition[1] = new Point2D(0, image[1].getHeight() - scene.getSize().getHeight());
-		imagePosition[2] = new Point2D(0, image[2].getHeight() - scene.getSize().getHeight());
-		imagePosition[3] = new Point2D(0, image[3].getHeight() - scene.getSize().getHeight());
-		speed = new Point2D(100, 0);
+		super(scene, new MyPoint(0, 0), 0);
+		sceneSize = scene.getSize();
+		imagePosition = new MyPoint[4];
+		imagePosition[0] = new MyPoint(0, getImage()[0].getHeight() - sceneSize.getHeight());
+		imagePosition[1] = new MyPoint(0, getImage()[1].getHeight() - sceneSize.getHeight());
+		imagePosition[2] = new MyPoint(0, getImage()[2].getHeight() - sceneSize.getHeight());
+		imagePosition[3] = new MyPoint(0, getImage()[3].getHeight() - sceneSize.getHeight());
+		speed = new MyPoint(100, 0);
+	}
+
+	private static Image[] getImage() {
+		if(image == null) {
+			image = new Image[4];
+			image[0] = new Image(Background.class.getResourceAsStream("cityfar400.png"));
+			image[1] = new Image(Background.class.getResourceAsStream("citymid400.png"));
+			image[2] = new Image(Background.class.getResourceAsStream("cityclose400.png"));
+			image[3] = new Image(Background.class.getResourceAsStream("cityreflection400.png"));
+		}
+		return image;
 	}
 
 	@Override
 	public void drawInternal(GraphicsContext gc) {
 		gc.setFill(Color.DARKBLUE);
-		gc.fillRect(0, 0, scene.getSize().getWidth(), scene.getSize().getHeight());
-		for (int i = 0; i < image.length; i++) {
-			double w = scene.getSize().getWidth();
+		gc.fillRect(0, 0, sceneSize.getWidth(), sceneSize.getHeight());
+		for (int i = 0; i < getImage().length; i++) {
+			double w = sceneSize.getWidth();
 			double x = imagePosition[i].getX();
-			double realWidth = x + w <= image[i].getWidth() ? w : image[i].getWidth() - x;
-			gc.drawImage(image[i], x, imagePosition[i].getY(), realWidth, scene.getSize().getHeight(), 0, 0, realWidth,
-					scene.getSize().getHeight());
-			if (x + w > image[i].getWidth()) {
-				gc.drawImage(image[i], 0, imagePosition[i].getY(), w - realWidth, scene.getSize().getHeight(),
-						image[i].getWidth() - imagePosition[i].getX(), 0, w - realWidth, scene.getSize().getHeight());
+			double realWidth = x + w <= getImage()[i].getWidth() ? w : getImage()[i].getWidth() - x;
+			gc.drawImage(getImage()[i], x, imagePosition[i].getY(), realWidth, sceneSize.getHeight(), 0, 0, realWidth,
+					sceneSize.getHeight());
+			if (x + w > getImage()[i].getWidth()) {
+				gc.drawImage(getImage()[i], 0, imagePosition[i].getY(), w - realWidth, sceneSize.getHeight(),
+						getImage()[i].getWidth() - imagePosition[i].getX(), 0, w - realWidth, sceneSize.getHeight());
 			}
 		}
 	}
 
 	@Override
 	public void simulate(double deltaTime) {
-		Point2D baseSpeed = speed.multiply(deltaTime / 1_000_000_000);
-		for (int i = 0; i < image.length; i++) {
+		MyPoint baseSpeed = speed.multiply(deltaTime / 1_000_000_000);
+		for (int i = 0; i < getImage().length; i++) {
 			imagePosition[i] = imagePosition[i].add(baseSpeed.multiply(speedMultiplier[i]));
-			if (imagePosition[i].getX() > image[i].getWidth()) {
-				imagePosition[i] = new Point2D(0, imagePosition[i].getY());
+			if (imagePosition[i].getX() > getImage()[i].getWidth()) {
+				imagePosition[i] = new MyPoint(0, imagePosition[i].getY());
 			}
 		}
 	}
 
 	public void setSpeed(double doubleValue) {
-		speed = new Point2D(doubleValue, 0);
+		speed = new MyPoint(doubleValue, 0);
 	}
 }
diff --git a/src/main/java/lab/game/Boat.java b/src/main/java/lab/game/Boat.java
index 6d63171..bf84c33 100644
--- a/src/main/java/lab/game/Boat.java
+++ b/src/main/java/lab/game/Boat.java
@@ -2,7 +2,6 @@ package lab.game;
 
 import java.util.Random;
 
-import javafx.geometry.Point2D;
 import javafx.geometry.Rectangle2D;
 import javafx.scene.canvas.GraphicsContext;
 import javafx.scene.image.Image;
@@ -11,18 +10,24 @@ import lab.Setup;
 public class Boat extends WorldEntity implements Collisionable {
 
 	private static final Random RANDOM = new Random();
-	private Point2D speed;
-	private Image image;
+	private MyPoint speed;
+	private static Image image;
 
-	public Boat(Scene scene, Point2D position) {
+	public Boat(Scene scene, MyPoint position) {
 		super(scene, position, 100);
-		image = new Image(Boat.class.getResourceAsStream("ship-boat.gif"));
-		speed = new Point2D(0, 0);
+		speed = new MyPoint(0, 0);
+	}
+
+	private static Image getImage() {
+		if(image == null) {
+			image = new Image(Boat.class.getResourceAsStream("ship-boat.gif"));
+		}
+		return image;
 	}
 
 	@Override
 	public void drawInternal(GraphicsContext gc) {
-		gc.drawImage(image, position.getX(), position.getY());
+		gc.drawImage(getImage(), position.getX(), position.getY());
 		Rectangle2D rec = getBoundingBox();
 		gc.strokeRect(rec.getMinX(), rec.getMinY(), rec.getWidth(), rec.getHeight());
 	}
@@ -36,8 +41,8 @@ public class Boat extends WorldEntity implements Collisionable {
 	@Override
 	public Rectangle2D getBoundingBox() {
 		return new Rectangle2D(position.getX(),
-				position.getY() + image.getHeight() * (1 - Setup.getInstance().getBoatCollisionHeight()),
-				image.getWidth(), image.getHeight() * Setup.getInstance().getBoatCollisionHeight());
+				position.getY() + getImage().getHeight() * (1 - Setup.getInstance().getBoatCollisionHeight()),
+				getImage().getWidth(), getImage().getHeight() * Setup.getInstance().getBoatCollisionHeight());
 	}
 
 	@Override
@@ -49,7 +54,7 @@ public class Boat extends WorldEntity implements Collisionable {
 	public void hitBy(Collisionable another) {
 		if (another instanceof LochNess lochNess) {
 			int direction = RANDOM.nextBoolean() ? -1 : 1;
-			speed = new Point2D(-Setup.getInstance().getBoatHitPulseX(),
+			speed = new MyPoint(-Setup.getInstance().getBoatHitPulseX(),
 					direction * RANDOM.nextDouble(Setup.getInstance().getBoatHitPulseYMin(),
 							Setup.getInstance().getBoatHitPulseYMax()));
 		}
@@ -58,8 +63,8 @@ public class Boat extends WorldEntity implements Collisionable {
 	public void setPosInPercentage(double doubleValue) {
 		double colisionHeight = getBoundingBox().getHeight();
 		double posFromBottom = (scene.getSize().getHeight()-colisionHeight)*doubleValue/100;
-		position = new Point2D(position.getX(),
-				(scene.getSize().getHeight()-image.getHeight() -posFromBottom));
+		position = new MyPoint(position.getX(),
+				(scene.getSize().getHeight()-getImage().getHeight() -posFromBottom));
 	}
 
 }
diff --git a/src/main/java/lab/game/LochNess.java b/src/main/java/lab/game/LochNess.java
index 0766013..b1a50e7 100644
--- a/src/main/java/lab/game/LochNess.java
+++ b/src/main/java/lab/game/LochNess.java
@@ -7,8 +7,6 @@ import java.util.Random;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
-import javafx.geometry.Dimension2D;
-import javafx.geometry.Point2D;
 import javafx.geometry.Rectangle2D;
 import javafx.scene.canvas.GraphicsContext;
 import javafx.scene.image.Image;
@@ -20,44 +18,50 @@ public class LochNess extends WorldEntity implements Collisionable {
 
 	private static final Random RANDOM = new Random();
 
-	private Point2D speed;
-	private Image image;
+	private MyPoint speed;
+	private static Image image;
 	private List<DeadListener> deadListeners = new ArrayList<>();
 
 	public LochNess(Scene scene) {
-		super(scene, new Point2D(0, 0), 90);
+		super(scene, new MyPoint(0, 0), 90);
 		this.scene = scene;
-		image = new Image(LochNess.class.getResourceAsStream("LochNess.gif"));
-		position = new Point2D(
+		position = new MyPoint(
 				RANDOM.nextDouble(scene.getSize().getWidth() * Setup.getInstance().getLochnessMinXPopsition(),
 						scene.getSize().getWidth()),
 				RANDOM.nextDouble(scene.getSize().getHeight() * Setup.getInstance().getLochnessMinYPopsition(),
-						scene.getSize().getHeight() - image.getHeight()));
-		speed = new Point2D(-RANDOM.nextDouble(Setup.getInstance().getLochnessMinSpeed(),
+						scene.getSize().getHeight() - getImage().getHeight()));
+		speed = new MyPoint(-RANDOM.nextDouble(Setup.getInstance().getLochnessMinSpeed(),
 				Setup.getInstance().getLochnessMaxSpeed()), 0);
 	}
 
+	private static Image getImage() {
+		if(image == null) {
+			image = new Image(LochNess.class.getResourceAsStream("LochNess.gif"));
+		}
+		return image;
+	}
+
 	@Override
 	public void drawInternal(GraphicsContext gc) {
-		gc.drawImage(image, position.getX(), position.getY());
-		gc.strokeRect(position.getX(), position.getY(), image.getWidth(), image.getHeight());
+		gc.drawImage(getImage(), position.getX(), position.getY());
+		gc.strokeRect(position.getX(), position.getY(), getImage().getWidth(), getImage().getHeight());
 	}
 
 	@Override
 	public void simulate(double deltaTime) {
 		position = position.add(speed.multiply(deltaTime / 1_000_000_000));
-		if (position.getX() + image.getWidth() < 0) {
-			position = new Point2D(scene.getSize().getWidth(), position.getY());
+		if (position.getX() + getImage().getWidth() < 0) {
+			position = new MyPoint(scene.getSize().getWidth(), position.getY());
 		}
 		if (position.getX() > scene.getSize().getWidth() + 5) {
-			position = new Point2D(scene.getSize().getWidth(), position.getY());
+			position = new MyPoint(scene.getSize().getWidth(), position.getY());
 			speed = speed.multiply(-1);
 		}
 	}
 
 	@Override
 	public Rectangle2D getBoundingBox() {
-		return new Rectangle2D(position.getX(), position.getY(), image.getWidth(), image.getHeight());
+		return new Rectangle2D(position.getX(), position.getY(), getImage().getWidth(), getImage().getHeight());
 	}
 
 	public void changeDirection() {
@@ -75,7 +79,7 @@ public class LochNess extends WorldEntity implements Collisionable {
 		log.trace("LochNess hitted by {}.", another);
 		if (another instanceof Boat) {
 			scene.remove(this);
-			scene.add(new Rock(scene, getPosition(), new Dimension2D(10, 10)));
+			scene.add(new Rock(scene, getPosition(), new MyDimension(10, 10)));
 			fireLochNessDead();
 		}
 
diff --git a/src/main/java/lab/game/MyDimension.java b/src/main/java/lab/game/MyDimension.java
new file mode 100644
index 0000000..d5838b2
--- /dev/null
+++ b/src/main/java/lab/game/MyDimension.java
@@ -0,0 +1,14 @@
+package lab.game;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
+public class MyDimension {
+
+	private double width;
+
+	private double height;
+
+}
diff --git a/src/main/java/lab/game/MyPoint.java b/src/main/java/lab/game/MyPoint.java
new file mode 100644
index 0000000..721a676
--- /dev/null
+++ b/src/main/java/lab/game/MyPoint.java
@@ -0,0 +1,58 @@
+package lab.game;
+
+public class MyPoint {
+
+	public double x;
+	public double y;
+
+	public MyPoint(double x, double y) {
+		super();
+		this.x = x;
+		this.y = y;
+	}
+
+	public double getX() {
+		return x;
+	}
+
+	public void setX(double x) {
+		this.x = x;
+	}
+
+	public double getY() {
+		return y;
+	}
+
+	public void setY(double y) {
+		this.y = y;
+	}
+
+	public MyPoint multiply(double multiplier) {
+		return new MyPoint(x * multiplier, y * multiplier);
+	}
+
+	public MyPoint add(MyPoint other) {
+		return new MyPoint(x + other.x, y + other.y);
+	}
+	public MyPoint add(double dx, double dy) {
+		return new MyPoint(x + dx, y + dy);
+	}
+
+    public double angle(double x, double y) {
+        final double ax = getX();
+        final double ay = getY();
+
+        final double delta = (ax * x + ay * y) / Math.sqrt(
+                (ax * ax + ay * ay) * (x * x + y * y));
+
+        if (delta > 1.0) {
+            return 0.0;
+        }
+        if (delta < -1.0) {
+            return 180.0;
+        }
+
+        return Math.toDegrees(Math.acos(delta));
+    }
+
+}
diff --git a/src/main/java/lab/game/Rock.java b/src/main/java/lab/game/Rock.java
index a1e755a..0337ce6 100644
--- a/src/main/java/lab/game/Rock.java
+++ b/src/main/java/lab/game/Rock.java
@@ -2,24 +2,23 @@ package lab.game;
 
 import java.util.Random;
 
-import javafx.geometry.Dimension2D;
-import javafx.geometry.Point2D;
 import javafx.scene.canvas.GraphicsContext;
 import javafx.scene.paint.Color;
 import javafx.scene.transform.Affine;
 import javafx.scene.transform.Rotate;
+import javafx.scene.transform.Transform;
 
 public class Rock  extends WorldEntity {
 
 	private static final Random RANDOM = new Random();
-	private Dimension2D size;
+	private MyDimension size;
 	private double angle = 0;
 
 	public Rock(Scene scene) {
-		this(scene, new Point2D(350, 200), new Dimension2D(60, 10));
+		this(scene, new MyPoint(350, 200), new MyDimension(60, 10));
 	}
 
-	public Rock(Scene scene, Point2D position, Dimension2D size) {
+	public Rock(Scene scene, MyPoint position, MyDimension size) {
 		super(scene, position, 50);
 		this.size = size;
 	}
@@ -28,8 +27,8 @@ public class Rock  extends WorldEntity {
 	public void drawInternal(GraphicsContext gc) {
 		gc.setFill(Color.GRAY);
 		gc.setStroke(Color.GREEN);
-		Point2D center = position.add(size.getWidth() / 2, size.getHeight() / 2);
-		Rotate rotateMatrix = Affine.rotate(angle, center.getX(), center.getY());
+		MyPoint center = position.add(size.getWidth() / 2, size.getHeight() / 2);
+		Rotate rotateMatrix = Transform.rotate(angle, center.getX(), center.getY());
 		gc.setTransform(new Affine(rotateMatrix));
 		gc.fillRect(position.getX(), position.getY(), size.getWidth(), size.getHeight());
 		gc.strokeRect(position.getX(), position.getY(), size.getWidth(), size.getHeight());
@@ -40,7 +39,7 @@ public class Rock  extends WorldEntity {
 	}
 
 	public void changePosition() {
-		position = new Point2D(
+		position = new MyPoint(
 				RANDOM.nextDouble(scene.getSize().getWidth()*0.3, scene.getSize().getWidth()*0.9),
 				RANDOM.nextDouble(scene.getSize().getHeight()*0.5, scene.getSize().getHeight()*0.95));
 	}
diff --git a/src/main/java/lab/game/Scene.java b/src/main/java/lab/game/Scene.java
index a5481b1..e45ae1d 100644
--- a/src/main/java/lab/game/Scene.java
+++ b/src/main/java/lab/game/Scene.java
@@ -6,8 +6,6 @@ import java.util.Comparator;
 import java.util.LinkedList;
 import java.util.List;
 
-import javafx.geometry.Dimension2D;
-import javafx.geometry.Point2D;
 import javafx.scene.canvas.GraphicsContext;
 import lab.Setup;
 import lombok.extern.log4j.Log4j2;
@@ -15,7 +13,11 @@ import lombok.extern.log4j.Log4j2;
 @Log4j2
 public class Scene {
 
-	private Dimension2D size;
+	private Object entitiesLock = new Object();
+
+	private boolean viewMode;
+
+	private MyDimension size;
 	private List<DrawableSimulable> sceneEntitites;
 	private List<DrawableSimulable> entititesToAdd = new ArrayList<>();
 	private List<DrawableSimulable> entititesToRemove = new ArrayList<>();
@@ -25,63 +27,90 @@ public class Scene {
 	private Rock rock;
 	private Background background;
 
-	public Scene(double width, double height, int numberOfMonsters) {
-		size = new Dimension2D(width, height);
+	public Scene(double width, double height, int numberOfMonsters, boolean viewMode) {
+		size = new MyDimension(width, height);
+		this.viewMode = viewMode;
 		sceneEntitites = new ArrayList<>();
 		background = new Background(this);
-		rock = new Rock(this, new Point2D(300, 300), new Dimension2D(30, 50));
-		boat = new Boat(this, new Point2D(20, 200));
+		rock = new Rock(this, new MyPoint(300, 300), new MyDimension(30, 50));
+		boat = new Boat(this, new MyPoint(20, 200));
 		sceneEntitites.add(background);
 		sceneEntitites.add(rock);
 		sceneEntitites.add(boat);
 		for (int i = 0; i < numberOfMonsters * Setup.getInstance().getLochnessMultiplier(); i++) {
 			LochNess lochNess = new LochNess(this);
-			lochNess.addDeadListener(ln -> lochNessDeadLogs.add(new LochNessDeadLog(LocalDateTime.now(), ln.getPosition())));
+			lochNess.addDeadListener(
+					ln -> lochNessDeadLogs.add(new LochNessDeadLog(LocalDateTime.now(), ln.getPosition())));
 			sceneEntitites.add(lochNess);
 		}
+		initServerOrViewMode();
+	}
+
+	public void initServerOrViewMode() {
+		if (!viewMode) {
+			startServer();
+		} else {
+			connectToServer();
+		}
+	}
+
+	public void startServer() {
+		//TODO:
+	}
+
+	public void connectToServer() {
+		//TODO:
+	}
+
+	record LochNessDeadLog(LocalDateTime time, MyPoint position) {
 	}
-	
-	record LochNessDeadLog(LocalDateTime time, Point2D position) {}
 
-	
 	public void printDeadLog() {
 		for (LochNessDeadLog lochNessDeadLog : lochNessDeadLogs) {
 			log.info(lochNessDeadLog);
 		}
 	}
-	
-	
-	public Dimension2D getSize() {
+
+	public MyDimension getSize() {
 		return size;
 	}
 
 	public void draw(GraphicsContext gc) {
-		for (DrawableSimulable entity : sceneEntitites) {
-			entity.draw(gc);
+		synchronized (entitiesLock) {
+			for (DrawableSimulable entity : sceneEntitites) {
+				entity.draw(gc);
+			}
 		}
 	}
 
 	public void simulate(double deltaTime) {
-		for (DrawableSimulable drawableSimulable : sceneEntitites) {
-			drawableSimulable.simulate(deltaTime);
+		if (viewMode) {
+			return;
+		}
+		synchronized (entitiesLock) {
+			for (DrawableSimulable drawableSimulable : sceneEntitites) {
+				drawableSimulable.simulate(deltaTime);
+			}
+			detectColision();
+			sceneEntitites.removeAll(entititesToRemove);
+			sceneEntitites.addAll(entititesToAdd);
+			entititesToAdd.clear();
+			entititesToRemove.clear();
+			sceneEntitites.sort(Comparator.comparing(DrawableSimulable::getZIndex));
 		}
+	}
+
+	private void detectColision() {
 		for (int i = 0; i < sceneEntitites.size(); i++) {
 			if (sceneEntitites.get(i) instanceof Collisionable c1) {
 				for (int j = i + 1; j < sceneEntitites.size(); j++) {
-					if (sceneEntitites.get(j) instanceof Collisionable c2) {
-						if (c1.intersect(c2.getBoundingBox())) {
-							c1.hitBy(c2);
-							c2.hitBy(c1);
-						}
+					if (sceneEntitites.get(j) instanceof Collisionable c2 && c1.intersect(c2.getBoundingBox())) {
+						c1.hitBy(c2);
+						c2.hitBy(c1);
 					}
 				}
 			}
 		}
-		sceneEntitites.removeAll(entititesToRemove);
-		sceneEntitites.addAll(entititesToAdd);
-		entititesToAdd.clear();
-		entititesToRemove.clear();
-		sceneEntitites.sort(Comparator.comparing(DrawableSimulable::getZIndex));
 	}
 
 	public Boat getBoat() {
@@ -97,10 +126,16 @@ public class Scene {
 	}
 
 	public void add(DrawableSimulable entity) {
+		if (viewMode) {
+			return;
+		}
 		entititesToAdd.add(entity);
 	}
 
 	public void remove(DrawableSimulable entity) {
+		if (viewMode) {
+			return;
+		}
 		entititesToRemove.add(entity);
 	}
 
diff --git a/src/main/java/lab/game/WorldEntity.java b/src/main/java/lab/game/WorldEntity.java
index d1fdcfe..016fb5f 100644
--- a/src/main/java/lab/game/WorldEntity.java
+++ b/src/main/java/lab/game/WorldEntity.java
@@ -1,21 +1,20 @@
 package lab.game;
 
-import javafx.geometry.Point2D;
 import javafx.scene.canvas.GraphicsContext;
 
 public abstract class WorldEntity implements DrawableSimulable {
 
 	protected Scene scene;
-	protected Point2D position;
+	protected MyPoint position;
 	private int zIndex;
 
-	public WorldEntity(Scene scene, Point2D position, int zIndex) {
+	public WorldEntity(Scene scene, MyPoint position, int zIndex) {
 		this.scene = scene;
 		this.position = position;
 		this.zIndex = zIndex;
 	}
 
-	public Point2D getPosition() {
+	public MyPoint getPosition() {
 		return position;
 	}
 
diff --git a/src/main/java/lab/gui/App.java b/src/main/java/lab/gui/App.java
index cb62b5f..b2e5857 100644
--- a/src/main/java/lab/gui/App.java
+++ b/src/main/java/lab/gui/App.java
@@ -2,20 +2,21 @@ package lab.gui;
 
 import java.io.IOException;
 import java.net.URL;
-import java.sql.SQLException;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.h2.tools.Server;
 
 import javafx.application.Application;
 import javafx.fxml.FXMLLoader;
 import javafx.scene.Parent;
 import javafx.scene.Scene;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.ButtonType;
 import javafx.stage.Stage;
 import javafx.stage.WindowEvent;
 import lab.Setup;
-import lab.storage.JpaConnector;
+import lab.storage.FileStorage;
 
 /**
  * Class <b>App</b> - extends class Application and it is an entry point of the
@@ -27,32 +28,24 @@ public class App extends Application {
 
 	private static Logger log = LogManager.getLogger(App.class);
 	private GameController gameController;
-	
+
+	private boolean viewMode;
+
 	private Stage primaryStage;
-	
+
 	public static void main(String[] args) {
 		log.info("Application lauched");
-		Setup.configure(Setup.builder().scoreStorageInterface(new JpaConnector()).build());
-		
-		startH2WebServerToInspectDb();
-		
-		launch(args);
-	}
+		Setup.configure(Setup.builder().scoreStorageInterface(new FileStorage()).build());
 
-	private static void startH2WebServerToInspectDb() {
-		//Start HTTP server for access H2 DB for look inside 
-		try {
-		    Server server = Server.createWebServer();
-		    log.info(server.getURL());
-		    server.start();
-		} catch (SQLException e) {
-		    e.printStackTrace();
-		}
+		launch(args);
 	}
 
 	@Override
 	public void start(Stage primaryStage) {
 		try {
+			Alert alert = new Alert(AlertType.CONFIRMATION, "View Mode?", ButtonType.YES, ButtonType.NO);
+			alert.showAndWait().ifPresent(button -> viewMode = ButtonType.YES.equals(button));
+
 			this.primaryStage = primaryStage;
 			switchToMenu();
 			primaryStage.setTitle("Java 2 - 2th laboratory");
@@ -69,12 +62,14 @@ public class App extends Application {
 		FXMLLoader gameLoader = new FXMLLoader(getClass().getResource("/lab/gui/gameWindow.fxml"));
 		Parent root = gameLoader.load();
 		gameController = gameLoader.getController();
+		gameController.setViewMode(viewMode);
 		Scene scene = new Scene(root);
 		URL cssUrl = getClass().getResource("application.css");
 		scene.getStylesheets().add(cssUrl.toString());
 		primaryStage.setScene(scene);
 		gameController.startGame(name, numberOfMonsters);
 	}
+
 	private void switchToMenu() throws IOException {
 		// Construct a main window with a canvas.
 		FXMLLoader menuLoader = new FXMLLoader(getClass().getResource("/lab/gui/mainScreen.fxml"));
@@ -89,7 +84,7 @@ public class App extends Application {
 
 	@Override
 	public void stop() throws Exception {
-		if(gameController != null) {
+		if (gameController != null) {
 			gameController.stop();
 		}
 		super.stop();
@@ -97,7 +92,7 @@ public class App extends Application {
 	}
 
 	private void exitProgram(WindowEvent evt) {
-		if(gameController != null) {
+		if (gameController != null) {
 			gameController.stop();
 		}
 		Setup.getInstance().getScoreStorageInterface().stop();
diff --git a/src/main/java/lab/gui/GameController.java b/src/main/java/lab/gui/GameController.java
index 0b059c1..8652704 100644
--- a/src/main/java/lab/gui/GameController.java
+++ b/src/main/java/lab/gui/GameController.java
@@ -19,6 +19,7 @@ public class GameController {
 	private static Logger log = LogManager.getLogger(GameController.class);
 	
 	private Scene scene;
+	private boolean viewMode; 
 
     @FXML
 	private Slider boatPosition;
@@ -74,9 +75,13 @@ public class GameController {
 		log.info("Screeen initialized.");
 	}
 
+	public void setViewMode(boolean viewMode) {
+		this.viewMode = viewMode;
+	}
+
 	public void startGame(String name, int numberOfMonsters) {
 		playerName.setText(name);
-		scene = new Scene(canvas.getWidth(), canvas.getHeight(), numberOfMonsters);
+		scene = new Scene(canvas.getWidth(), canvas.getHeight(), numberOfMonsters, viewMode);
 		timer = new DrawingThread(canvas, scene);
 		timer.start();
 
-- 
GitLab