From 268d0795de16eacb33337d6c61ecbe510c5e46ea Mon Sep 17 00:00:00 2001 From: jez04 <david.jezek@post.cz> Date: Tue, 22 Oct 2024 00:23:30 +0200 Subject: [PATCH] feat: :tada: solution lab 04 --- src/main/java/lab/Collisionable.java | 13 +++++++ src/main/java/lab/DrawableSimulable.java | 9 +++++ src/main/java/lab/DrawingThread.java | 2 +- src/main/java/lab/Level.java | 46 ++++++++++++------------ src/main/java/lab/Monster.java | 26 ++++++++++---- src/main/java/lab/NicerObstacle.java | 11 +++--- src/main/java/lab/Obstacle.java | 11 ++---- src/main/java/lab/Player.java | 31 +++++++++++----- src/main/java/lab/WorldEntity.java | 30 ++++++++++++++++ 9 files changed, 124 insertions(+), 55 deletions(-) create mode 100644 src/main/java/lab/Collisionable.java create mode 100644 src/main/java/lab/DrawableSimulable.java create mode 100644 src/main/java/lab/WorldEntity.java diff --git a/src/main/java/lab/Collisionable.java b/src/main/java/lab/Collisionable.java new file mode 100644 index 0000000..40a8157 --- /dev/null +++ b/src/main/java/lab/Collisionable.java @@ -0,0 +1,13 @@ +package lab; + +import javafx.geometry.Rectangle2D; + +public interface Collisionable { + + Rectangle2D getBoundingBox(); + + boolean intersect(Rectangle2D another); + + void hitBy(Collisionable another); + +} diff --git a/src/main/java/lab/DrawableSimulable.java b/src/main/java/lab/DrawableSimulable.java new file mode 100644 index 0000000..d5b5d45 --- /dev/null +++ b/src/main/java/lab/DrawableSimulable.java @@ -0,0 +1,9 @@ +package lab; + +import javafx.scene.canvas.GraphicsContext; + +public interface DrawableSimulable { + void draw(GraphicsContext gc); + + void simulate(double deltaT); +} diff --git a/src/main/java/lab/DrawingThread.java b/src/main/java/lab/DrawingThread.java index a53ad11..f5e0529 100644 --- a/src/main/java/lab/DrawingThread.java +++ b/src/main/java/lab/DrawingThread.java @@ -19,7 +19,7 @@ public class DrawingThread extends AnimationTimer { } /** - * Draws objects into the canvas. Put you code here. + * Draws objects into the canvas. Put you code here. */ @Override public void handle(long now) { diff --git a/src/main/java/lab/Level.java b/src/main/java/lab/Level.java index f4a0be2..d6f9031 100644 --- a/src/main/java/lab/Level.java +++ b/src/main/java/lab/Level.java @@ -7,45 +7,45 @@ import javafx.scene.paint.Color; public class Level { - private NicerObstacle nicerObstacle; - private Obstacle obstacle1; - private Obstacle obstacle2; - private Player player; private double width; private double height; - private Monster[] monsters; + private DrawableSimulable[] entities; public Level(double width, double height) { this.width = width; this.height = height; - nicerObstacle = new NicerObstacle(this, new Point2D(20, 150)); - obstacle1 = new Obstacle(this, new Point2D(300, 200), new Dimension2D(80, 40)); - obstacle2 = new Obstacle(this); - player = new Player(this, new Point2D(20, 250), new Point2D(100, -20)); - monsters = new Monster[5]; - for (int i = 0; i < monsters.length; i++) { - monsters[i] = new Monster(this); + entities = new DrawableSimulable[9]; + entities[0] = new NicerObstacle(this, new Point2D(20, 150)); + entities[1] = new Obstacle(this, new Point2D(300, 200), new Dimension2D(80, 40)); + entities[2] = new Obstacle(this); + entities[3] = new Player(this, new Point2D(20, 250), new Point2D(100, -20)); + for (int i = 4; i < entities.length; i++) { + entities[i] = new Monster(this); } } public void draw(GraphicsContext gc) { gc.setFill(Color.WHITE); gc.clearRect(0, 0, width, height); - nicerObstacle.draw(gc); - obstacle1.draw(gc); - obstacle2.draw(gc); - player.draw(gc); - for (Monster monster : monsters) { - monster.draw(gc); + for (DrawableSimulable entity : entities) { + entity.draw(gc); } } public void simulate(double delay) { - player.simulate(delay); - for (Monster monster : monsters) { - monster.simulate(delay); - if (monster.getBoundingBox().intersects(player.getBoundingBox())) { - monster.changeDirection(); + for (DrawableSimulable entity : entities) { + entity.simulate(delay); + } + for (int i = 0; i < entities.length; i++) { + if (entities[i] instanceof Collisionable c1) { + for (int j = i + 1; j < entities.length; j++) { + if (entities[j] instanceof Collisionable c2) { + if (c1.intersect(c2.getBoundingBox())) { + c1.hitBy(c2); + c2.hitBy(c1); + } + } + } } } } diff --git a/src/main/java/lab/Monster.java b/src/main/java/lab/Monster.java index 88144d1..9c4cf34 100644 --- a/src/main/java/lab/Monster.java +++ b/src/main/java/lab/Monster.java @@ -7,17 +7,15 @@ import javafx.geometry.Rectangle2D; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; -public class Monster { +public class Monster extends WorldEntity implements Collisionable { private static final Random RANDOM = new Random(); - private Level level; private Image image; - private Point2D position; private Point2D speed; public Monster(Level level) { - this.level = level; + super(level, new Point2D(0, 0)); image = new Image(getClass().getResourceAsStream("red-monster.gif")); position = new Point2D(level.getWidth() * 0.5 + RANDOM.nextDouble(level.getWidth() * 0.5 - image.getWidth()), RANDOM.nextDouble(level.getHeight())); @@ -25,25 +23,39 @@ public class Monster { } public Monster(Level level, Point2D position) { - this.level = level; - this.position = position; + super(level, position); image = new Image(getClass().getResourceAsStream("spike.gif")); } - public void draw(GraphicsContext gc) { + public void drawInternal(GraphicsContext gc) { gc.drawImage(image, position.getX(), position.getY()); } public void changeDirection() { speed = speed.multiply(-1); } + public void simulate(double delay) { position = position.add(speed.multiply(delay / 1_000_000_000)); position = new Point2D(position.getX(), position.getY() % level.getHeight()); } + @Override public Rectangle2D getBoundingBox() { return new Rectangle2D(position.getX(), position.getY(), image.getWidth(), image.getHeight()); } + @Override + public boolean intersect(Rectangle2D another) { + return getBoundingBox().intersects(another); + } + + @Override + public void hitBy(Collisionable another) { + if (another instanceof Player) { + changeDirection(); + } + + } + } diff --git a/src/main/java/lab/NicerObstacle.java b/src/main/java/lab/NicerObstacle.java index fd39886..a0a6c27 100644 --- a/src/main/java/lab/NicerObstacle.java +++ b/src/main/java/lab/NicerObstacle.java @@ -4,24 +4,21 @@ import javafx.geometry.Point2D; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; -public class NicerObstacle { +public class NicerObstacle extends WorldEntity { - private Level level; private Image image; - private Point2D position; public NicerObstacle(Level level, Point2D position) { - this.level = level; - this.position = position; + super(level, position); image = new Image(getClass().getResourceAsStream("spike.gif")); } - public void draw(GraphicsContext gc) { + public void drawInternal(GraphicsContext gc) { gc.drawImage(image, position.getX(), position.getY()); } public void simulate(double delay) { - + } } diff --git a/src/main/java/lab/Obstacle.java b/src/main/java/lab/Obstacle.java index 0c0fe1d..09a46c3 100644 --- a/src/main/java/lab/Obstacle.java +++ b/src/main/java/lab/Obstacle.java @@ -5,10 +5,8 @@ import javafx.geometry.Point2D; import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; -public class Obstacle { +public class Obstacle extends WorldEntity { - private Level level; - private Point2D position; private Dimension2D size; public Obstacle(Level level) { @@ -16,19 +14,16 @@ public class Obstacle { } public Obstacle(Level level, Point2D position, Dimension2D size) { - this.level = level; - this.position = position; + super(level, position); this.size = size; } - public void draw(GraphicsContext gc) { - gc.save(); + public void drawInternal(GraphicsContext gc) { gc.setFill(Color.BLUEVIOLET); gc.setStroke(Color.RED); gc.setLineWidth(3); gc.fillRect(position.getX(), position.getY(), size.getWidth(), size.getHeight()); gc.strokeRect(position.getX(), position.getY(), size.getWidth(), size.getHeight()); - gc.restore(); } public void simulate(double delay) { diff --git a/src/main/java/lab/Player.java b/src/main/java/lab/Player.java index db14f4a..7450176 100644 --- a/src/main/java/lab/Player.java +++ b/src/main/java/lab/Player.java @@ -1,5 +1,7 @@ package lab; +import java.util.Random; + import javafx.geometry.Point2D; import javafx.geometry.Rectangle2D; import javafx.scene.canvas.GraphicsContext; @@ -7,19 +9,16 @@ import javafx.scene.paint.Color; import javafx.scene.transform.Affine; import javafx.scene.transform.Rotate; -public class Player { - private Level level; - private Point2D position; +public class Player extends WorldEntity implements Collisionable { + private static final Random RANDOM = new Random(); private Point2D speed; public Player(Level level, Point2D position, Point2D speed) { - this.level = level; - this.position = position; + super(level, position); this.speed = speed; } - public void draw(GraphicsContext gc) { - gc.save(); + public void drawInternal(GraphicsContext gc) { Point2D center = position.add(10, 25); double angle = speed.angle(1, 0); if (speed.getY() < 0) { @@ -33,16 +32,30 @@ public class Player { gc.fillRect(center.getX(), center.getY(), 50, 1); gc.fillRoundRect(position.getX(), position.getY(), 20, 50, 20, 20); gc.strokeRoundRect(position.getX(), position.getY(), 20, 50, 20, 20); - gc.restore(); } public void simulate(double delay) { - position = position.add(speed.multiply(delay/1_000_000_000)); + position = position.add(speed.multiply(delay / 1_000_000_000)); // speed = speed.multiply(0.9994); } + @Override public Rectangle2D getBoundingBox() { return new Rectangle2D(position.getX(), position.getY(), 20, 50); } + @Override + public boolean intersect(Rectangle2D another) { + return getBoundingBox().intersects(another); + } + + @Override + public void hitBy(Collisionable another) { + if (another instanceof Monster) { + position = new Point2D(RANDOM.nextDouble(0, level.getWidth() * 0.4), + RANDOM.nextDouble(level.getHeight() * 0.5, level.getHeight())); + } + + } + } diff --git a/src/main/java/lab/WorldEntity.java b/src/main/java/lab/WorldEntity.java new file mode 100644 index 0000000..cdeebff --- /dev/null +++ b/src/main/java/lab/WorldEntity.java @@ -0,0 +1,30 @@ +package lab; + +import javafx.geometry.Point2D; +import javafx.scene.canvas.GraphicsContext; + +public abstract class WorldEntity implements DrawableSimulable{ + + protected final Level level; + protected Point2D position; + + public WorldEntity(Level level, Point2D position) { + this.level = level; + this.position = position; + } + + @Override + public final void draw(GraphicsContext gc) { + gc.save(); + drawInternal(gc); + gc.restore(); + } + + public abstract void drawInternal(GraphicsContext gc); + + public Point2D getPosition() { + return position; + } + + +} -- GitLab