diff --git a/src/main/java/lab/Bullet.java b/src/main/java/lab/Bullet.java index c8deeffecfa583112be32435adb9fa8957c12e01..2172d11a30b2cf2499ded7076f1a283fe755e799 100644 --- a/src/main/java/lab/Bullet.java +++ b/src/main/java/lab/Bullet.java @@ -1,36 +1,47 @@ package lab; import javafx.geometry.Point2D; +import javafx.geometry.Rectangle2D; import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; -public class Bullet { +public class Bullet extends WorldEntity implements Collisionable{ private static final double SIZE = 20; - private final Point2D acceleration; - - private final World world; - private Point2D position; - private Point2D velocity; + protected final Point2D acceleration; + protected Point2D velocity; public Bullet(World world, Point2D position, Point2D velocity, Point2D acceleration) { - this.world = world; - this.position = position; + super(world, position); this.velocity = velocity; this.acceleration = acceleration; } - public void draw(GraphicsContext gc) { + @Override + public void drawInternal(GraphicsContext gc) { gc.setFill(Color.SILVER); gc.fillOval(position.getX(), position.getY(), SIZE, SIZE); } + @Override public void simulate(double deltaT) { position = position.add(velocity.multiply(deltaT)); velocity = velocity.add(acceleration.multiply(deltaT)); } - protected Point2D getPosition() { - return position; + @Override + public Rectangle2D getBoundingBox() { + return new Rectangle2D(position.getX(), position.getY(), SIZE, SIZE); + } + + @Override + public boolean intersect(Rectangle2D another) { + return getBoundingBox().intersects(another); } + + @Override + public void hitBy(Collisionable another) { + + } + } diff --git a/src/main/java/lab/BulletAnimated.java b/src/main/java/lab/BulletAnimated.java index cc7d236ffe7f1320897d2958303506ac5842c994..2134c1292e28308fbcac0caed6348e36c8b33412 100644 --- a/src/main/java/lab/BulletAnimated.java +++ b/src/main/java/lab/BulletAnimated.java @@ -5,40 +5,35 @@ import javafx.geometry.Rectangle2D; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; -public class BulletAnimated { +public class BulletAnimated extends Bullet { private static final double SIZE = 40; - private final World world; + private final Point2D initVelocity; + private Cannon cannon; private Image image = new Image(this.getClass().getResourceAsStream("fireball-transparent.gif")); - public BulletAnimated(World world, Point2D position, Point2D velocity, Point2D acceleration) { - this.world = world; - this.position = position; - this.velocity = velocity; - this.acceleration = acceleration; + public BulletAnimated(World world, Cannon cannon, Point2D position, Point2D velocity, Point2D acceleration) { + super(world, position, velocity, acceleration); + this.initVelocity = velocity; + this.cannon = cannon; } - public void draw(GraphicsContext gc) { + @Override + public void drawInternal(GraphicsContext gc) { gc.drawImage(image, getPosition().getX(), getPosition().getY(), SIZE, SIZE); gc.strokeRect(position.getX(), position.getY(), SIZE, SIZE); } - private final Point2D acceleration; - - private Point2D position; - private Point2D velocity; - - public void simulate(double deltaT) { - position = position.add(velocity.multiply(deltaT)); - velocity = velocity.add(acceleration.multiply(deltaT)); - } - - protected Point2D getPosition() { - return position; + @Override + public void hitBy(Collisionable another) { + if (another instanceof Ufo) { + reload(); + } } - public Rectangle2D getBoundingBox() { - return new Rectangle2D(position.getX(), position.getY(), SIZE,SIZE); + public void reload() { + position = cannon.getPosition(); + velocity = initVelocity; } -} +} \ No newline at end of file diff --git a/src/main/java/lab/Cannon.java b/src/main/java/lab/Cannon.java index 0a1cf1746c5f2b37865d7231ec375ff705478e5a..59f6d2172d4e7debc36115666702dabde6e353cc 100644 --- a/src/main/java/lab/Cannon.java +++ b/src/main/java/lab/Cannon.java @@ -6,31 +6,27 @@ import javafx.scene.paint.Color; import javafx.scene.transform.Affine; import javafx.scene.transform.Transform; -public class Cannon { +public class Cannon extends WorldEntity{ private static final double LENGTH = 60; private static final double WIDTH = 15; - private final World world; - private Point2D position; private double angle; private double angleDelta = -25; public Cannon(World world, Point2D position, double angle) { - this.world = world; - this.position = position; + super(world, position); this.angle = angle; } - public void draw(GraphicsContext gc) { - gc.save(); + @Override + public void drawInternal(GraphicsContext gc) { gc.transform(new Affine(Transform.rotate(angle, position.getX(), position.getY() + WIDTH / 2))); gc.setFill(Color.BROWN); gc.fillRect(position.getX(), position.getY(), LENGTH, WIDTH); - gc.restore(); } + @Override public void simulate(double deltaT) { - // do nothing yet angle += angleDelta * deltaT; if (angle >= 0 || angle <= -90) { angleDelta = -angleDelta; diff --git a/src/main/java/lab/Collisionable.java b/src/main/java/lab/Collisionable.java new file mode 100644 index 0000000000000000000000000000000000000000..40a81570906acfe0a433fcda9f2bd47757b7cdf6 --- /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 0000000000000000000000000000000000000000..d5b5d45871e5124a9aa526115a50d5e2e64fb401 --- /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/Ufo.java b/src/main/java/lab/Ufo.java index 472c4f1920b7d8b5289eb3b998b7f5a35c198255..78ea525119625e1f61f338e2811b29e1c7ee946d 100644 --- a/src/main/java/lab/Ufo.java +++ b/src/main/java/lab/Ufo.java @@ -7,44 +7,54 @@ import javafx.geometry.Rectangle2D; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; -public class Ufo { +public class Ufo extends WorldEntity implements Collisionable { private static final Random RANDOM = new Random(); private Image image = new Image(this.getClass().getResourceAsStream("ufo-small.gif")); - private final World world; - private Point2D position; private Point2D velocity; public Ufo(World world) { - this(world, - new Point2D(RANDOM.nextDouble(world.getWidth()), - RANDOM.nextDouble(0, world.getHeight()*0.3)), + this(world, new Point2D(RANDOM.nextDouble(world.getWidth()), RANDOM.nextDouble(0, world.getHeight() * 0.3)), new Point2D(RANDOM.nextDouble(70, 150), 0)); } public Ufo(World world, Point2D position, Point2D velocity) { - this.world = world; - this.position = position; + super(world, position); this.velocity = velocity; } - public void draw(GraphicsContext gc) { + @Override + public void drawInternal(GraphicsContext gc) { gc.drawImage(image, getPosition().getX(), getPosition().getY()); } - public void changeDirection(){ + public void changeDirection() { velocity = velocity.multiply(-1); } + + @Override public void simulate(double deltaT) { position = position.add(velocity.multiply(deltaT)); - position = new Point2D(position.getX()%world.getWidth(), position.getY()); + position = new Point2D(position.getX() % world.getWidth(), position.getY()); + if(position.getX() < -image.getWidth()) { + position = new Point2D(world.getWidth(), position.getY()); + } } - protected Point2D getPosition() { - return position; - } - + @Override public Rectangle2D getBoundingBox() { - return new Rectangle2D(position.getX(), position.getY(), image.getWidth(), image.getHeight()); + 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 BulletAnimated || another instanceof Bullet) { + changeDirection(); + } } } diff --git a/src/main/java/lab/World.java b/src/main/java/lab/World.java index 6abd918876c6fdc2cd0552120a9b929735388ad9..253af0e99f6b6c1fcba88942cfb83f8052757639 100644 --- a/src/main/java/lab/World.java +++ b/src/main/java/lab/World.java @@ -11,20 +11,19 @@ public class World { private final double height; - private final Bullet bullet; - private final BulletAnimated bullet2; - private final Cannon cannon; - private Ufo[] ufos; + private DrawableSimulable[] entities; public World(double width, double height) { this.width = width; this.height = height; - bullet = new Bullet(this, new Point2D(0, height), new Point2D(30, -30), new Point2D(0, 9.81)); - bullet2 = new BulletAnimated(this, new Point2D(0, height), new Point2D(50, -80), new Point2D(0, 9.81)); - cannon = new Cannon(this, new Point2D(0, height-20), -45); - ufos = new Ufo[5]; - for (int i = 0; i < ufos.length; i++) { - ufos[i] = new Ufo(this); + entities = new DrawableSimulable[8]; + Cannon cannon = new Cannon(this, new Point2D(0, height - 20), -45); + entities[0] = cannon; + entities[1] = new Bullet(this, new Point2D(0, height), new Point2D(30, -30), new Point2D(0, 9.81)); + entities[2] = new BulletAnimated(this, cannon, new Point2D(0, height), new Point2D(50, -80), + new Point2D(0, 9.81)); + for (int i = 3; i < entities.length; i++) { + entities[i] = new Ufo(this); } } @@ -32,25 +31,26 @@ public class World { gc.clearRect(0, 0, width, height); gc.save(); - bullet.draw(gc); - bullet2.draw(gc); - cannon.draw(gc); - for (int i = 0; i < ufos.length; i++) { - ufos[i].draw(gc); + for (DrawableSimulable entity : entities) { + entity.draw(gc); } gc.restore(); } public void simulate(double deltaT) { - bullet.simulate(deltaT); - bullet2.simulate(deltaT); - cannon.simulate(deltaT); - for (int i = 0; i < ufos.length; i++) { - ufos[i].simulate(deltaT); + for (DrawableSimulable entity : entities) { + entity.simulate(deltaT); } - for (Ufo ufo : ufos) { - if(ufo.getBoundingBox().intersects(bullet2.getBoundingBox())) { - ufo.changeDirection(); + 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); + } + } + } } } } @@ -62,5 +62,5 @@ public class World { public double getHeight() { return height; } - + } \ No newline at end of file diff --git a/src/main/java/lab/WorldEntity.java b/src/main/java/lab/WorldEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..83228945ad45686a47585875f8cf626578e55f68 --- /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 World world; + protected Point2D position; + + public WorldEntity(World world, Point2D position) { + this.world = world; + 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; + } + + +}