Skip to content
Snippets Groups Projects
Commit e06b33a4 authored by jez04's avatar jez04
Browse files

feat: assignment lab 09

parent e3df2923
No related merge requests found
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
......
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);
}
}
......@@ -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));
}
}
......@@ -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();
}
......
package lab.game;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public class MyDimension {
private double width;
private double height;
}
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));
}
}
......@@ -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));
}
......
......@@ -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);
}
......
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;
}
......
......@@ -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();
......
......@@ -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();
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment