diff --git a/src/main/java/core/general/Master.java b/src/main/java/core/general/Master.java index c964354..5d198c1 100644 --- a/src/main/java/core/general/Master.java +++ b/src/main/java/core/general/Master.java @@ -122,6 +122,16 @@ public class Master extends JPanel { create(new DebugPos(pos, new Vector2D(2, 2)), 3); } + /** + * Debug a position, creates a green dot at the position + * + * @param pos The position + * @param lifeTime The lifetime of the {@code DebugPos} in ms + */ + public void debugPos(Vector2D pos, long lifeTime) { + create(new DebugPos(pos, new Vector2D(2, 2), lifeTime), 3); + } + /** * This method is the entry method for each frame. It handles everything about the frame diff --git a/src/main/java/core/math/Vector2D.java b/src/main/java/core/math/Vector2D.java index caa05ab..2aa5844 100644 --- a/src/main/java/core/math/Vector2D.java +++ b/src/main/java/core/math/Vector2D.java @@ -31,8 +31,7 @@ public class Vector2D { * Create a new empty Vector2D object */ public Vector2D() { - x = 0; - y = 0; + this(0, 0); } /** @@ -44,7 +43,6 @@ public class Vector2D { return new Vector2D(point.x, point.y); } - /** * Add another Vector to this vector, modifies this object * @@ -58,9 +56,9 @@ public class Vector2D { } /** - * Multiply this vector with a simple scalar, modifies this object + * Multiply this vector with a simple factor, modifies this object * - * @param a The scalar + * @param a The multiplying factor * @return this after the multiplication */ public Vector2D multiply(double a) { @@ -101,6 +99,14 @@ public class Vector2D { return new Vector2D(-x, -y); } + /** + * Get the rotation of the {@code Vector2D} in radians + * @return the rotation in radians + */ + public double getRotation() { + return Math.atan2(y, x); + } + /** * Add two Vectors @@ -183,11 +189,21 @@ public class Vector2D { return rotateAround(new Vector2D(), new Vector2D(0, 1), direction); } + /** + * Get the distance between two {@code Vector2D} + * @param a The first {@code Vector2D} + * @param b The second {@code Vector2D} + * @return The distance between the 2 {@code Vector2D} + */ public static double distance(Vector2D a, Vector2D b) { Vector2D dif = subtract(a, b); return Math.sqrt(dif.x * dif.x + dif.y + dif.y); } + public static Vector2D zero() { + return new Vector2D(0, 0); + } + /** * Copy this object @@ -222,8 +238,4 @@ public class Vector2D { if (Double.compare(vector2D.x, x) != 0) return false; return Double.compare(vector2D.y, y) == 0; } - - public double getRotation() { - return Math.atan2(y, x); - } } \ No newline at end of file diff --git a/src/main/java/core/objects/base/DebugPos.java b/src/main/java/core/objects/base/DebugPos.java index 5dd25e1..f6b39c3 100644 --- a/src/main/java/core/objects/base/DebugPos.java +++ b/src/main/java/core/objects/base/DebugPos.java @@ -1,7 +1,9 @@ package core.objects.base; +import core.math.Coordinates; import core.math.Vector2D; import core.objects.core.GameObject; +import core.renderer.CustomRenderer; import java.awt.*; @@ -22,11 +24,20 @@ public class DebugPos extends GameObject { this.velocity = new Vector2D(); this.mainColor = Color.GREEN; this.lifeTime = lifeTime; - } + this.spawnTime = System.currentTimeMillis(); + this.layer = 3; - @Override - public void draw(Graphics2D g2d) { - drawOval(g2d, "center"); + this.setRenderer(new CustomRenderer(Color.GREEN, this) { + @Override + public void draw(Graphics2D g2d) { + Vector2D positionAbs = Coordinates.getWorldCoordinates(getMapPosition()); + g2d.setColor(color); + g2d.setStroke(new BasicStroke((int) Coordinates.getWorldCoordinates(new Vector2D(0.5, 0)).x, BasicStroke.CAP_BUTT, + BasicStroke.JOIN_BEVEL)); + g2d.drawLine((int)positionAbs.x - 20, (int)positionAbs.y, (int)positionAbs.x + 20, (int)positionAbs.y); + g2d.drawLine((int)positionAbs.x, (int)positionAbs.y-20, (int)positionAbs.x, (int)positionAbs.y+20); + } + }); } @Override diff --git a/src/main/java/core/objects/core/CollGameObject.java b/src/main/java/core/objects/core/CollGameObject.java index b345994..7ec6ae5 100644 --- a/src/main/java/core/objects/core/CollGameObject.java +++ b/src/main/java/core/objects/core/CollGameObject.java @@ -5,6 +5,7 @@ import core.objects.core.GameObject; import core.physics.Collidable; import core.physics.Collision; import core.physics.hitboxes.Hitbox; +import core.renderer.Renderer; import java.util.ArrayList; diff --git a/src/main/java/core/objects/core/GameObject.java b/src/main/java/core/objects/core/GameObject.java index 3b26b43..3ebf025 100644 --- a/src/main/java/core/objects/core/GameObject.java +++ b/src/main/java/core/objects/core/GameObject.java @@ -4,6 +4,7 @@ import core.math.Coordinates; import core.renderer.Drawable; import core.general.Master; import core.math.Vector2D; +import core.renderer.Renderer; import java.awt.*; @@ -28,6 +29,9 @@ public abstract class GameObject implements Drawable { protected GameObject parent; + private Renderer renderer; + + @Deprecated public GameObject(double x, double y, double xSize, double ySize) { this(new Vector2D(x, y), new Vector2D(xSize, ySize)); } @@ -60,6 +64,11 @@ public abstract class GameObject implements Drawable { */ public abstract void update(); + @Override + public void draw(Graphics2D g2d) { + renderer.draw(g2d); + } + /** * A simple method to move the object to a Vector2D. This method should be called instead of doing it manually. * @@ -95,15 +104,6 @@ public abstract class GameObject implements Drawable { g2d.fillOval((int) abs.x, (int) abs.y, (int) sizeAbs.x, (int) sizeAbs.y); } - /** - * This method draws an oval at the current position and size - * - * @param g2d The Graphics2D object provided by the master - */ - public void drawOval(Graphics2D g2d) { - drawOval(g2d, ""); - } - /** * This method draws an oval at the current position and size with arguments * @@ -126,29 +126,6 @@ public abstract class GameObject implements Drawable { g2d.drawOval((int) abs.x, (int) abs.y, (int) sizeAbs.x, (int) sizeAbs.y); } - /** - * This method draws a rounded rectangle at the current position and size - * - * @param g2d The Graphics2D object provided by the master - * @param arcW The arc width of the rectangle - * @param arcH The arc height of the rectangle - */ - public void drawRoundRect(Graphics2D g2d, int arcW, int arcH) { - - Vector2D abs = Coordinates.getWorldCoordinates(position); - Vector2D sizeAbs = Coordinates.getWorldCoordinates(size); - - int xCenterAbs = (int) (abs.x + sizeAbs.x / 2); - int yCenterAbs = (int) (abs.y + sizeAbs.y / 2); - - g2d.setPaint(mainColor); - - g2d.rotate(rotation, xCenterAbs, yCenterAbs); - g2d.fillRoundRect((int) abs.x, (int) abs.y, (int) sizeAbs.x, (int) sizeAbs.y, arcW, arcH); - - g2d.rotate(-rotation, xCenterAbs, yCenterAbs); - } - /** * Destroy this {@code GameObject} */ @@ -156,15 +133,15 @@ public abstract class GameObject implements Drawable { master.destroy(this); } - /** * Returns the value as map coords * @param value The value relative to the parent * @return The value in global map coordinates */ public Vector2D getMapCoords(Vector2D value) { - double x = parent.position.x + value.x; - double y = parent.position.y + value.y; + Vector2D rotated = Vector2D.rotateAround(parent.getCenterPositionLocal(), value, parent.rotation); + double x = parent.position.x + rotated.x; + double y = parent.position.y + rotated.y; return parent.getMapCoords(new Vector2D(x, y)); } @@ -186,6 +163,14 @@ public abstract class GameObject implements Drawable { return new Vector2D(position.x + size.x / 2, position.y + size.y / 2); } + /** + * Get the local center position of the object + * @return The center position + */ + public Vector2D getCenterPositionLocal(){ + return new Vector2D(size.x / 2, size.y / 2); + } + /** * Get the render layer of the object * @return The render layer @@ -201,4 +186,26 @@ public abstract class GameObject implements Drawable { protected Vector2D getV2DRotation(){ return Vector2D.getUnitVector(rotation); } + + //----------- Getters and setters ----------------- + + public Vector2D getMapPosition(){ + return getMapCoords(position); + } + + public Vector2D getPosition() { + return position; + } + + public double getRotation() { + return rotation; + } + + public Vector2D getSize() { + return size; + } + + protected void setRenderer(Renderer renderer){ + this.renderer = renderer; + } } diff --git a/src/main/java/core/objects/core/MapAnchor.java b/src/main/java/core/objects/core/MapAnchor.java index 168da7b..7b78961 100644 --- a/src/main/java/core/objects/core/MapAnchor.java +++ b/src/main/java/core/objects/core/MapAnchor.java @@ -15,12 +15,10 @@ public class MapAnchor extends GameObject { @Override public void draw(Graphics2D g2d) { - } @Override public void update() { - } @Override diff --git a/src/main/java/core/renderer/CircleRenderer.java b/src/main/java/core/renderer/CircleRenderer.java index a7af285..76aa7c7 100644 --- a/src/main/java/core/renderer/CircleRenderer.java +++ b/src/main/java/core/renderer/CircleRenderer.java @@ -1,14 +1,46 @@ package core.renderer; +import core.math.Coordinates; +import core.math.Vector2D; +import core.objects.core.GameObject; + import java.awt.*; -public class CircleRenderer extends Renderer{ +/** + * A simple {@code Renderer} that renders a filled circle + */ +public class CircleRenderer extends Renderer { + /** + * The radius of the circle + */ private double radius; - private Color color; + + /** + * The constructor for the circle + * @param object The {@code GameObject} the {@code Renderer} is assigned to + * @param color The {@code Color} of the circle + * @param radius The radius of the circle + */ + public CircleRenderer(GameObject object, Color color, double radius) { + super(color, object); + this.radius = radius; + } @Override public void draw(Graphics2D g2d) { + Vector2D abs = Coordinates.getWorldCoordinates(object.getMapPosition()); + Vector2D sizeAbs = Coordinates.getWorldCoordinates(new Vector2D(radius * 2, radius * 2)); + g2d.setPaint(color); + g2d.fillOval((int) abs.x, (int) abs.y, (int) sizeAbs.x, (int) sizeAbs.y); + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; } } diff --git a/src/main/java/core/renderer/ComplexRenderer.java b/src/main/java/core/renderer/ComplexRenderer.java index 9f42080..d4c5ce8 100644 --- a/src/main/java/core/renderer/ComplexRenderer.java +++ b/src/main/java/core/renderer/ComplexRenderer.java @@ -1,14 +1,26 @@ package core.renderer; +import core.objects.core.GameObject; + import java.awt.*; import java.util.ArrayList; +import java.util.Arrays; +/** + * The {@code ComplexRenderer} consists of multiple {@code Renderers} + *

The {@code Renderer} at index 0 gets rendered first

+ */ public class ComplexRenderer extends Renderer{ private ArrayList renderers; + public ComplexRenderer (GameObject object, Renderer ... renderers){ + super(null, object); + this.renderers = new ArrayList<>(Arrays.asList(renderers)); + } + @Override public void draw(Graphics2D g2d) { - + renderers.forEach(e -> e.draw(g2d)); } } diff --git a/src/main/java/core/renderer/CustomRenderer.java b/src/main/java/core/renderer/CustomRenderer.java new file mode 100644 index 0000000..8178f12 --- /dev/null +++ b/src/main/java/core/renderer/CustomRenderer.java @@ -0,0 +1,11 @@ +package core.renderer; + +import core.objects.core.GameObject; + +import java.awt.*; + +public abstract class CustomRenderer extends Renderer{ + public CustomRenderer(Color color, GameObject object) { + super(color, object); + } +} diff --git a/src/main/java/core/renderer/RectRenderer.java b/src/main/java/core/renderer/RectRenderer.java new file mode 100644 index 0000000..59c0e41 --- /dev/null +++ b/src/main/java/core/renderer/RectRenderer.java @@ -0,0 +1,21 @@ +package core.renderer; + +import core.math.Vector2D; +import core.objects.core.GameObject; + +import java.awt.*; + +public class RectRenderer extends Renderer{ + + private int width; + private int height; + + public RectRenderer(Color color, GameObject object) { + super(color, object); + } + + @Override + public void draw(Graphics2D g2d) { + + } +} diff --git a/src/main/java/core/renderer/Renderer.java b/src/main/java/core/renderer/Renderer.java index 74a0543..b3c6795 100644 --- a/src/main/java/core/renderer/Renderer.java +++ b/src/main/java/core/renderer/Renderer.java @@ -1,8 +1,30 @@ package core.renderer; +import core.objects.core.GameObject; + import java.awt.*; +/** + * The base renderer class for all renderers + */ public abstract class Renderer { + protected Color color; + protected GameObject object; + + /** + * The superconstructor for every {@code Renderer} that sets the color and the {@code GameObject} the renderer is assigned to + * @param color The color of the object the {@code Renderer} renders + * @param object The {@code GameObject} the {@code Renderer} os assigned to + */ + public Renderer(Color color, GameObject object) { + this.color = color; + this.object = object; + } + + /** + * This method is called on every renderer for every {@code GameObject} + * @param g2d the {@code Graphics2D} object + */ public abstract void draw(Graphics2D g2d); } diff --git a/src/main/java/core/renderer/RoundRectRenderer.java b/src/main/java/core/renderer/RoundRectRenderer.java new file mode 100644 index 0000000..8586119 --- /dev/null +++ b/src/main/java/core/renderer/RoundRectRenderer.java @@ -0,0 +1,41 @@ +package core.renderer; + +import core.general.Master; +import core.math.Coordinates; +import core.math.Vector2D; +import core.objects.core.GameObject; + +import java.awt.*; + +public class RoundRectRenderer extends Renderer { + + private Vector2D size; + private double cornerFactorX, cornerFactorY; + private Master master; + + public RoundRectRenderer(Color color, GameObject object, Vector2D size, double cornerFactorX, double cornerFactorY) { + super(color, object); + this.size = size; + this.master = Master.getMaster(); + this.cornerFactorX = cornerFactorX; + this.cornerFactorY = cornerFactorY; + } + + @Override + public void draw(Graphics2D g2d) { + Vector2D abs = Coordinates.getWorldCoordinates(object.getMapPosition()); + Vector2D sizeAbs = Coordinates.getWorldCoordinates(size); + + master.debugPos(object.getMapPosition()); + + int xCenterAbs = (int) (abs.x + sizeAbs.x / 2); + int yCenterAbs = (int) (abs.y + sizeAbs.y / 2); + + g2d.setPaint(color); + + g2d.rotate(object.getRotation(), xCenterAbs, yCenterAbs); + g2d.fillRoundRect((int) abs.x, (int) abs.y, (int) sizeAbs.x, (int) sizeAbs.y, (int) (master.getW() / cornerFactorX), (int) (master.getH() / cornerFactorY)); + + g2d.rotate(-object.getRotation(), xCenterAbs, yCenterAbs); + } +} diff --git a/src/main/java/objects/ships/BattleShip.java b/src/main/java/objects/ships/BattleShip.java index 79326c0..ed8bbe1 100644 --- a/src/main/java/objects/ships/BattleShip.java +++ b/src/main/java/objects/ships/BattleShip.java @@ -5,6 +5,7 @@ import core.math.Vector2D; import core.objects.core.CollGameObject; import core.objects.core.GameObject; import core.physics.hitboxes.RectHitBox; +import core.renderer.RoundRectRenderer; import java.awt.*; import java.awt.event.KeyEvent; @@ -35,12 +36,12 @@ public class BattleShip extends GameObject { turrets = new ArrayList<>(); this.mainColor = mainColor; this.doesDespawn = false; + setRenderer(new RoundRectRenderer(mainColor, this, size, 10, 10)); } @Override public void draw(Graphics2D g2d) { - - drawRoundRect(g2d, master.getW() / 10, master.getW() / 10); + super.draw(g2d); turrets.forEach((turret -> turret.draw(g2d))); } diff --git a/src/main/java/objects/ships/Shell.java b/src/main/java/objects/ships/Shell.java index 4ca44f7..d88f350 100644 --- a/src/main/java/objects/ships/Shell.java +++ b/src/main/java/objects/ships/Shell.java @@ -18,7 +18,6 @@ public class Shell extends CollGameObject { this.mainColor = Color.ORANGE; this.ignores.add(Shell.class); this.isTrigger = true; - this.doesDespawn = false; } @Override diff --git a/src/main/java/objects/ships/Submarine.java b/src/main/java/objects/ships/Submarine.java index a39d1cd..1ca6215 100644 --- a/src/main/java/objects/ships/Submarine.java +++ b/src/main/java/objects/ships/Submarine.java @@ -4,6 +4,9 @@ import core.math.Coordinates; import core.math.Vector2D; import core.physics.hitboxes.RectHitBox; import core.objects.core.CollGameObject; +import core.renderer.CircleRenderer; +import core.renderer.CustomRenderer; +import core.renderer.RectRenderer; import java.awt.*; @@ -11,16 +14,11 @@ public class Submarine extends CollGameObject { public Submarine(Vector2D position, Vector2D size) { super(position, size, new RectHitBox(position, size)); + setRenderer(new CircleRenderer(this, Color.BLUE, size.x/2)); this.mainColor = Color.BLUE; doesDespawn = false; } - @Override - public void draw(Graphics2D g2d) { - g2d.setPaint(Color.BLUE); - fillOval(g2d); - } - @Override public void update() { Point mouse = master.getMouseLocation(); diff --git a/src/main/java/objects/ships/Turret.java b/src/main/java/objects/ships/Turret.java index 4e49ca6..f2873b9 100644 --- a/src/main/java/objects/ships/Turret.java +++ b/src/main/java/objects/ships/Turret.java @@ -47,10 +47,11 @@ public class Turret extends GameObject { g2d.fillOval((int) abs.x, (int) abs.y, sizeAbs, sizeAbs); - g2d.setStroke(new BasicStroke((int) Coordinates.getWorldCoordinates(new Vector2D(size.x / barrelAmount / BARREL_THICKNESS, 0)).x, BasicStroke.CAP_BUTT, - BasicStroke.JOIN_BEVEL)); + //BARRELS--------------------------------------- + g2d.setStroke(new BasicStroke((int) Coordinates.getWorldCoordinates(new Vector2D(size.x / barrelAmount / BARREL_THICKNESS, 0)).x, BasicStroke.CAP_BUTT, + BasicStroke.JOIN_BEVEL)); g2d.setPaint(Color.BLACK); int barrelSpacing = sizeAbs / (barrelAmount + 1); diff --git a/target/classes/objects/ships/Turret.class b/target/classes/objects/ships/Turret.class index ea08041..2a9f760 100644 Binary files a/target/classes/objects/ships/Turret.class and b/target/classes/objects/ships/Turret.class differ