From 72b7c47a3e62a0c58ba044aa450c02a88b38b27c Mon Sep 17 00:00:00 2001 From: Nilstrieb Date: Thu, 31 Dec 2020 18:12:04 +0100 Subject: [PATCH] basic camera --- src/main/java/core/general/Main.java | 2 +- src/main/java/core/general/Master.java | 2 +- src/main/java/core/math/Vector2D.java | 11 ++++++ src/main/java/core/objects/base/Camera.java | 23 +++++++++++ src/main/java/core/objects/base/Empty.java | 2 + .../core/physics/hitboxes/RectHitBox.java | 3 +- .../java/core/rendering/RenderEngine.java | 36 +++++++++++++++--- .../rendering/renderer/EmptyRenderer.java | 24 ++++++++++++ src/main/java/{objects => custom}/Init.java | 16 +++++--- src/main/java/custom/objects/MoveCamera.java | 34 +++++++++++++++++ .../objects/ships/BattleShip.java | 3 +- .../{ => custom}/objects/ships/Shell.java | 2 +- .../{ => custom}/objects/ships/Submarine.java | 2 +- .../{ => custom}/objects/ships/Turret.java | 6 +-- .../java/{ => custom}/objects/world/Grid.java | 2 +- .../java/{ => custom}/objects/world/Wall.java | 2 +- target/classes/objects/ships/BattleShip.class | Bin 2085 -> 0 bytes target/classes/objects/ships/Shell.class | Bin 1447 -> 0 bytes target/classes/objects/ships/Turret.class | Bin 3204 -> 0 bytes target/classes/objects/world/Grid.class | Bin 1280 -> 0 bytes 20 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 src/main/java/core/objects/base/Camera.java create mode 100644 src/main/java/core/rendering/renderer/EmptyRenderer.java rename src/main/java/{objects => custom}/Init.java (77%) create mode 100644 src/main/java/custom/objects/MoveCamera.java rename src/main/java/{ => custom}/objects/ships/BattleShip.java (95%) rename src/main/java/{ => custom}/objects/ships/Shell.java (96%) rename src/main/java/{ => custom}/objects/ships/Submarine.java (96%) rename src/main/java/{ => custom}/objects/ships/Turret.java (97%) rename src/main/java/{ => custom}/objects/world/Grid.java (97%) rename src/main/java/{ => custom}/objects/world/Wall.java (96%) delete mode 100644 target/classes/objects/ships/BattleShip.class delete mode 100644 target/classes/objects/ships/Shell.class delete mode 100644 target/classes/objects/ships/Turret.class delete mode 100644 target/classes/objects/world/Grid.class diff --git a/src/main/java/core/general/Main.java b/src/main/java/core/general/Main.java index 7ee4cf3..bce09bc 100644 --- a/src/main/java/core/general/Main.java +++ b/src/main/java/core/general/Main.java @@ -1,6 +1,6 @@ package core.general; -import objects.Init; +import custom.Init; import javax.swing.*; import java.awt.*; diff --git a/src/main/java/core/general/Master.java b/src/main/java/core/general/Master.java index fe63874..6855e7d 100644 --- a/src/main/java/core/general/Master.java +++ b/src/main/java/core/general/Master.java @@ -8,7 +8,7 @@ import core.physics.Collision; import core.objects.base.DebugPos; import core.objects.core.GameObject; import core.rendering.Drawable; -import objects.Init; +import custom.Init; import javax.swing.*; import java.awt.*; diff --git a/src/main/java/core/math/Vector2D.java b/src/main/java/core/math/Vector2D.java index 2aa5844..a0f05b9 100644 --- a/src/main/java/core/math/Vector2D.java +++ b/src/main/java/core/math/Vector2D.java @@ -43,6 +43,7 @@ public class Vector2D { return new Vector2D(point.x, point.y); } + /** * Add another Vector to this vector, modifies this object * @@ -141,6 +142,16 @@ public class Vector2D { return new Vector2D(a.x / b, a.y / b); } + /** + * Divide a Vector by a Vector + * @param a Vector a + * @param b Vector b + * @return The result + */ + public static Vector2D divide(Vector2D a, Vector2D b) { + return new Vector2D(a.x / b.x, a.y / b.y); + } + /** * Rotate a point around another point *

diff --git a/src/main/java/core/objects/base/Camera.java b/src/main/java/core/objects/base/Camera.java new file mode 100644 index 0000000..a363292 --- /dev/null +++ b/src/main/java/core/objects/base/Camera.java @@ -0,0 +1,23 @@ +package core.objects.base; + +import core.general.Input; +import core.math.Vector2D; +import core.objects.core.GameObject; +import core.rendering.renderer.EmptyRenderer; + +import java.awt.event.KeyEvent; + +/** + * The base Camera that shifts all objects + */ +public class Camera extends GameObject { + public Camera(Vector2D position, Vector2D size) { + super(position, size); + setRenderer(new EmptyRenderer(this)); + this.doesDespawn = false; + } + + @Override + protected void update() { + } +} diff --git a/src/main/java/core/objects/base/Empty.java b/src/main/java/core/objects/base/Empty.java index 5ade288..27f8c10 100644 --- a/src/main/java/core/objects/base/Empty.java +++ b/src/main/java/core/objects/base/Empty.java @@ -2,11 +2,13 @@ package core.objects.base; import core.math.Vector2D; import core.objects.core.GameObject; +import core.rendering.renderer.EmptyRenderer; public class Empty extends GameObject { public Empty(Vector2D position) { super(position, new Vector2D(0, 0)); + setRenderer(new EmptyRenderer(this)); } @Override diff --git a/src/main/java/core/physics/hitboxes/RectHitBox.java b/src/main/java/core/physics/hitboxes/RectHitBox.java index 6edcb9d..cde91b6 100644 --- a/src/main/java/core/physics/hitboxes/RectHitBox.java +++ b/src/main/java/core/physics/hitboxes/RectHitBox.java @@ -1,9 +1,8 @@ package core.physics.hitboxes; import core.math.Coordinates; -import core.general.Master; import core.math.Vector2D; -import objects.Init; +import custom.Init; import java.awt.*; diff --git a/src/main/java/core/rendering/RenderEngine.java b/src/main/java/core/rendering/RenderEngine.java index 4d6115e..1e41ee2 100644 --- a/src/main/java/core/rendering/RenderEngine.java +++ b/src/main/java/core/rendering/RenderEngine.java @@ -3,6 +3,7 @@ package core.rendering; import core.general.Master; import core.math.Coordinates; import core.math.Vector2D; +import core.objects.base.Camera; import javax.swing.*; import java.awt.*; @@ -16,6 +17,8 @@ public class RenderEngine extends JPanel { private final Master master = Master.getMaster(); + private Camera currentCamera; + /** * The current width and height of the game area */ @@ -110,11 +113,32 @@ public class RenderEngine extends JPanel { layerManager.flush(); } + public Camera getCurrentCamera() { + return currentCamera; + } + + public void setCurrentCamera(Camera currentCamera) { + this.currentCamera = currentCamera; + } + + //-------------------------------------- + + public Vector2D shiftPoint(Vector2D point){ + Vector2D newPosShifted = Vector2D.subtract(point, currentCamera.getPosition()); + return Vector2D.divide(newPosShifted, currentCamera.getSize()); + } + + public Vector2D scaleSize(Vector2D size){ + return Vector2D.divide(size, currentCamera.getSize()); + } + + + //Drawing methods--------------------------------------------------------------------------------------------------------------- public void fillRect(Vector2D position, Vector2D size, Color color, double rotation){ - Vector2D abs = Coordinates.getWorldCoordinates(position); - Vector2D sizeAbs = Coordinates.getWorldCoordinates(size); + Vector2D abs = Coordinates.getWorldCoordinates(shiftPoint(position)); + Vector2D sizeAbs = Coordinates.getWorldCoordinates(scaleSize(size)); Vector2D centerAbs = new Vector2D((abs.x + sizeAbs.x / 2), (abs.y + sizeAbs.y / 2)); g2d.setPaint(color); @@ -126,8 +150,8 @@ public class RenderEngine extends JPanel { } public void fillRoundRect(Vector2D position, Vector2D size, Vector2D arcFactors, Color color, double rotation){ - Vector2D abs = Coordinates.getWorldCoordinates(position); - Vector2D sizeAbs = Coordinates.getWorldCoordinates(size); + Vector2D abs = Coordinates.getWorldCoordinates(shiftPoint(position)); + Vector2D sizeAbs = Coordinates.getWorldCoordinates(scaleSize(size)); Vector2D centerAbs = new Vector2D((abs.x + sizeAbs.x / 2), (abs.y + sizeAbs.y / 2)); g2d.setPaint(color); @@ -140,8 +164,8 @@ public class RenderEngine extends JPanel { } public void fillOval(Vector2D position, Vector2D size, Color color, double rotation){ - Vector2D abs = Coordinates.getWorldCoordinates(position); - Vector2D sizeAbs = Coordinates.getWorldCoordinates(size); + Vector2D abs = Coordinates.getWorldCoordinates(shiftPoint(position)); + Vector2D sizeAbs = Coordinates.getWorldCoordinates(scaleSize(size)); Vector2D centerAbs = new Vector2D((abs.x + sizeAbs.x / 2), (abs.y + sizeAbs.y / 2)); g2d.setPaint(color); diff --git a/src/main/java/core/rendering/renderer/EmptyRenderer.java b/src/main/java/core/rendering/renderer/EmptyRenderer.java new file mode 100644 index 0000000..b9fd586 --- /dev/null +++ b/src/main/java/core/rendering/renderer/EmptyRenderer.java @@ -0,0 +1,24 @@ +package core.rendering.renderer; + +import core.objects.core.GameObject; + +import java.awt.*; + +/** + * A filler {@code Renderer} that does nothing + */ +public class EmptyRenderer extends Renderer{ + + /** + * The superconstructor for every {@code Renderer} that sets the color and the {@code GameObject} the renderer is assigned to + * + * @param object The {@code GameObject} the {@code Renderer} os assigned to + */ + public EmptyRenderer(GameObject object) { + super(null, object); + } + + @Override + public void draw(Graphics2D g2d) { + } +} diff --git a/src/main/java/objects/Init.java b/src/main/java/custom/Init.java similarity index 77% rename from src/main/java/objects/Init.java rename to src/main/java/custom/Init.java index 5d47c88..8009668 100644 --- a/src/main/java/objects/Init.java +++ b/src/main/java/custom/Init.java @@ -1,13 +1,15 @@ -package objects; +package custom; import core.general.Master; import core.math.Vector2D; +import core.objects.base.Camera; import core.objects.core.GameObject; -import objects.ships.BattleShip; -import objects.ships.Submarine; -import objects.ships.Turret; -import objects.world.Grid; -import objects.world.Wall; +import custom.objects.MoveCamera; +import custom.objects.ships.BattleShip; +import custom.objects.ships.Submarine; +import custom.objects.ships.Turret; +import custom.objects.world.Grid; +import custom.objects.world.Wall; import java.awt.*; @@ -33,6 +35,8 @@ public class Init { //INIT GOES HERE + Master.getMaster().getRenderEngine().setCurrentCamera(create(new MoveCamera(Vector2D.zero(), new Vector2D(1, 1)))); + create(new Grid()); BattleShip battleShip = create(new BattleShip()); diff --git a/src/main/java/custom/objects/MoveCamera.java b/src/main/java/custom/objects/MoveCamera.java new file mode 100644 index 0000000..3ba1b4a --- /dev/null +++ b/src/main/java/custom/objects/MoveCamera.java @@ -0,0 +1,34 @@ +package custom.objects; + +import core.general.Input; +import core.math.Vector2D; +import core.objects.base.Camera; + +import java.awt.event.KeyEvent; + +public class MoveCamera extends Camera { + public MoveCamera(Vector2D position, Vector2D size) { + super(position, size); + } + + @Override + protected void update() { + if(Input.keyPressed(KeyEvent.VK_RIGHT)){ + position.x += 1; + } else if(Input.keyPressed(KeyEvent.VK_LEFT)){ + position.x -= 1; + } + if(Input.keyPressed(KeyEvent.VK_UP)){ + position.y -= 1; + } else if(Input.keyPressed(KeyEvent.VK_DOWN)){ + position.y += 1; + } + + if(Input.keyPressed(KeyEvent.VK_PAGE_UP)){ + size.multiply(0.9); + } + if(Input.keyPressed(KeyEvent.VK_PAGE_DOWN)){ + size.multiply(1.1); + } + } +} diff --git a/src/main/java/objects/ships/BattleShip.java b/src/main/java/custom/objects/ships/BattleShip.java similarity index 95% rename from src/main/java/objects/ships/BattleShip.java rename to src/main/java/custom/objects/ships/BattleShip.java index 3969b41..36b5277 100644 --- a/src/main/java/objects/ships/BattleShip.java +++ b/src/main/java/custom/objects/ships/BattleShip.java @@ -1,9 +1,8 @@ -package objects.ships; +package custom.objects.ships; import core.general.Input; import core.math.Vector2D; import core.objects.core.GameObject; -import core.rendering.renderer.RectRenderer; import core.rendering.renderer.RoundRectRenderer; import java.awt.*; diff --git a/src/main/java/objects/ships/Shell.java b/src/main/java/custom/objects/ships/Shell.java similarity index 96% rename from src/main/java/objects/ships/Shell.java rename to src/main/java/custom/objects/ships/Shell.java index 73879f0..7891cef 100644 --- a/src/main/java/objects/ships/Shell.java +++ b/src/main/java/custom/objects/ships/Shell.java @@ -1,4 +1,4 @@ -package objects.ships; +package custom.objects.ships; import core.math.Vector2D; import core.objects.core.CollGameObject; diff --git a/src/main/java/objects/ships/Submarine.java b/src/main/java/custom/objects/ships/Submarine.java similarity index 96% rename from src/main/java/objects/ships/Submarine.java rename to src/main/java/custom/objects/ships/Submarine.java index b1d9cf1..52b7378 100644 --- a/src/main/java/objects/ships/Submarine.java +++ b/src/main/java/custom/objects/ships/Submarine.java @@ -1,4 +1,4 @@ -package objects.ships; +package custom.objects.ships; import core.math.Coordinates; import core.math.Vector2D; diff --git a/src/main/java/objects/ships/Turret.java b/src/main/java/custom/objects/ships/Turret.java similarity index 97% rename from src/main/java/objects/ships/Turret.java rename to src/main/java/custom/objects/ships/Turret.java index 668f47d..e054172 100644 --- a/src/main/java/objects/ships/Turret.java +++ b/src/main/java/custom/objects/ships/Turret.java @@ -1,4 +1,4 @@ -package objects.ships; +package custom.objects.ships; import core.general.Input; import core.math.Coordinates; @@ -19,7 +19,7 @@ public class Turret extends GameObject { private static final int SHELL_SPEED = 1; public static final double SHELL_SIZE = 2; private static final double BARREL_THICKNESS = 1.7; - private int barrelAmount = 3; + private final int barrelAmount; private final Color mainColor; @@ -78,7 +78,7 @@ public class Turret extends GameObject { @Override public void update() { - //TODO fix with everything haha + //TODO fix everything haha Point msLoc = master.getMouseLocation(); Vector2D mouseRel = Coordinates.getMapCoordinatesFromWorld(Vector2D.fromPoint(msLoc)); //100 correct diff --git a/src/main/java/objects/world/Grid.java b/src/main/java/custom/objects/world/Grid.java similarity index 97% rename from src/main/java/objects/world/Grid.java rename to src/main/java/custom/objects/world/Grid.java index 80c63f8..b543fe0 100644 --- a/src/main/java/objects/world/Grid.java +++ b/src/main/java/custom/objects/world/Grid.java @@ -1,4 +1,4 @@ -package objects.world; +package custom.objects.world; import core.math.Vector2D; import core.objects.core.GameObject; diff --git a/src/main/java/objects/world/Wall.java b/src/main/java/custom/objects/world/Wall.java similarity index 96% rename from src/main/java/objects/world/Wall.java rename to src/main/java/custom/objects/world/Wall.java index 0b717d7..a4d559a 100644 --- a/src/main/java/objects/world/Wall.java +++ b/src/main/java/custom/objects/world/Wall.java @@ -1,4 +1,4 @@ -package objects.world; +package custom.objects.world; import core.math.Vector2D; import core.physics.hitboxes.Hitbox; diff --git a/target/classes/objects/ships/BattleShip.class b/target/classes/objects/ships/BattleShip.class deleted file mode 100644 index 9dd04a09e1a89dafd3b8dcb14767a4e98f85bd72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2085 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 l0S<5~7)SsB diff --git a/target/classes/objects/world/Grid.class b/target/classes/objects/world/Grid.class deleted file mode 100644 index 1c7718f7b0f9759c84333ad100ee19ba276ae5ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1280 zcmX^0Z`VEs1_o;eS1tx724;2!79Ivx1~x_pq2&CcRQ=q=`j0^%ksM6M43?dAo>ic?Dh5;OBk7#V~$ z5GH_ytU)f2VvuHMkl|sFWsqZJ5Q6!yJijO>Mc=(BGlh|XEjO{aB(;c7lQ(WB0GZ;4}&s;3L}FsIA~DSFfy>DrGB9gsdV-v-#>1e_puxz% zky4ac9+a9~!pOj`;pyq=sTl^6*5YB%hD-Zo=A|++@VEzgy2J+uI68a!xic~_dNMNb zI_KvVmn7zugeB&brZO`yFc^Vt2xDYman4UkWn|z7>GdnkO-d~aNleN~Wn>WY$xlwq z2}>->1o5GQEF~G4#f%IhKA66@W@KOixsj1U0x9$m0c@=q#>l`}$;iN%$;iN1!N|az zZj=HFDJ+p;&B(x5&d9)+!N|Z{mReMjnVgsda$qqd1Aj(-QD#+sUI|=;H@GA*Iomg} z0P04z(t?!4l2k?puHgLAqU2P!OptdtK{2EUvWr2HL5hKcfq{XML5e|#L6?D%L63of zfr&w%fti7kft$gAfsw(Gfq}si%x7TW*4n|qxPyUlI|KVhutFmS1_n^BVPFto;9?MD zFlJz2;9+27U|`^8FkvtS8*Rp54l#x?h=CPsU6J-C2HtH9!dhDxB)2ih+sX(CD_XOc@jy>=+aoJQ(B|{1{XiA{bN|5*gGOvKdqu3K=xPK1^faVz6W2Vz6M) zWngE}V^CnQWYA?`V@PD+Vz2^>1;WJ`7>b}F0b*G**f20M@G~Sc*fQucFfoWTL^Iei z=rS-fs51C6*fZ!durO#dxHC8~=rXV}I5IFW$T6_|XV7C{XJ?RNXAofo0S1O&4Dx>% um>7RC$TKi9IKiVy8ywyY42&S}GJ(Cz2969pu(Kf%!w7W_BZD(I3S9v0R{co;