diff --git a/.idea/misc.xml b/.idea/misc.xml index 5f60ad7..0f9e86a 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/2DGame.iml b/2DGame.iml new file mode 100644 index 0000000..78b2cc5 --- /dev/null +++ b/2DGame.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 9f78e99..01c14d8 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,4 +1,4 @@ -import core.Master; +import core.general.Master; import javax.swing.*; import java.awt.*; @@ -24,7 +24,8 @@ class Main extends JFrame { add(master); setTitle("Points"); - setSize(1000, (int) (1000 / Master.SCREEN_RATIO)); + int w = 1500; + setSize(w, (int) (w / Master.SCREEN_RATIO)); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); diff --git a/src/main/java/core/Drawable.java b/src/main/java/core/general/Drawable.java similarity index 96% rename from src/main/java/core/Drawable.java rename to src/main/java/core/general/Drawable.java index 6658c96..7efc348 100644 --- a/src/main/java/core/Drawable.java +++ b/src/main/java/core/general/Drawable.java @@ -1,4 +1,4 @@ -package core; +package core.general; import java.awt.Graphics2D; diff --git a/src/main/java/core/Master.java b/src/main/java/core/general/Master.java similarity index 77% rename from src/main/java/core/Master.java rename to src/main/java/core/general/Master.java index 92dc4e4..d4d4429 100644 --- a/src/main/java/core/Master.java +++ b/src/main/java/core/general/Master.java @@ -1,12 +1,15 @@ -package core; +package core.general; import core.math.Vector2D; +import core.objects.core.CollGameObject; import core.physics.Collidable; import core.physics.Collision; import core.objects.base.DebugPos; +import core.physics.hitboxes.Hitbox; import objects.ships.BattleShip; import core.objects.core.GameObject; import objects.ships.Submarine; +import objects.ships.Turret; import objects.world.Grid; import objects.world.Wall; @@ -45,6 +48,7 @@ public class Master extends JPanel { */ private final ArrayList> drawables; + /** * All physics objects that exist */ @@ -55,6 +59,11 @@ public class Master extends JPanel { */ private final ArrayList objectBuffer; + /** + * All physics objects that exist + */ + private final ArrayList collidablesBuffer; + /** * Whether the left mouse button has been pressed since the last frame */ @@ -74,6 +83,7 @@ public class Master extends JPanel { objects = new ArrayList<>(); objectBuffer = new ArrayList<>(); collidables = new ArrayList<>(); + collidablesBuffer = new ArrayList<>(); drawables = new ArrayList<>(); drawables.add(new ArrayList<>()); @@ -82,9 +92,11 @@ public class Master extends JPanel { BattleShip battleShip = new BattleShip(Color.DARK_GRAY); BattleShip bs = new BattleShip(140, 10, 10, 80, Color.GREEN); - /*for (int i = 0; i < 10; i++) { - bs.addTurret(new Turret(bs, 25, 10 * i + 1, 50, i % 5)); - }*/ + + for (int i = 0; i < 8; i++) { + bs.addTurret(new Turret(bs, 2.5, 10 * i + 1, 5, (i % 5 )+ 1)); + + } create(bs); create(battleShip); @@ -143,11 +155,16 @@ public class Master extends JPanel { * This method is the entry method for each frame. It handles everything about the frame */ public void refresh() { + long time = System.currentTimeMillis(); + objects.clear(); objects.addAll(objectBuffer); - objectBuffer.clear(); - objects.forEach(GameObject::update); + collidables.clear(); + collidables.addAll(collidablesBuffer); + objects.forEach(GameObject::startUpdate); + long time2 = System.currentTimeMillis(); mousePressed = false; repaint(); + System.out.println("Frame took " + (System.currentTimeMillis() - time) + "ms, " + (time2 - time) + "ms for update, " + (System.currentTimeMillis() - time2) + "ms for draw"); } /** @@ -182,8 +199,8 @@ public class Master extends JPanel { */ public void create(GameObject obj, int renderLayer) { objectBuffer.add(obj); - if (obj instanceof Collidable) { - collidables.add((Collidable) obj); + if (obj instanceof CollGameObject) { + collidablesBuffer.add((Collidable) obj); } addDrawable(obj, renderLayer); @@ -221,15 +238,20 @@ public class Master extends JPanel { * @return True if it collides with something, false if it doesn't - Should return a Collision */ public Collision doesCollide(Collidable collidable) { + long time = System.nanoTime(); Collision collides = null; for (Collidable other : collidables) { - double distance = Vector2D.distance(other.getCenterPos(), collidable.getCenterPos()); - if (other != collidable && (distance < other.getHitbox().getSize() + collidable.getHitbox().getSize())) { + if (!collidable.getIgnores().contains(other.getClass()) && !other.isTrigger()) { //ONLY calculate when it's not ignored - if (other.getHitbox().collidesWith(collidable.getHitbox())) { - collides = new Collision(collidable, other); + double distance = Vector2D.distance(other.getCenterPos(), collidable.getCenterPos()); + if (other != collidable && (distance < other.getHitbox().getSize() + collidable.getHitbox().getSize())) { + + if (other.getHitbox().collidesWith(collidable.getHitbox())) { + collides = new Collision(collidable, other); + collidable.onCollision(); + } } } } @@ -245,11 +267,11 @@ public class Master extends JPanel { } public void destroy(GameObject gameObject) { - objects.remove(gameObject); objectBuffer.remove(gameObject); drawables.get(gameObject.getLayer()).remove(gameObject); if (gameObject instanceof Collidable) { - collidables.remove(gameObject); + collidablesBuffer.remove(gameObject); + drawables.get(Hitbox.HITBOX_RENDER_LAYER).remove(((CollGameObject) gameObject).getHitbox()); } } } diff --git a/src/main/java/core/math/Coords.java b/src/main/java/core/math/Coords.java index 858f04e..7a60ef1 100644 --- a/src/main/java/core/math/Coords.java +++ b/src/main/java/core/math/Coords.java @@ -1,7 +1,6 @@ package core.math; -import core.Master; -import core.math.Vector2D; +import core.general.Master; /** * This class provides everything about the local coordinate system the game uses @@ -24,6 +23,7 @@ public class Coords { /** * Get the world coordinates of a point in map coordinates + * * @param value A point in map coordinates * @return The point in world coordinates */ @@ -44,4 +44,10 @@ public class Coords { double y = (value.y / master.getH()) * Master.SCREEN_Y_COORDINATES; return new Vector2D(x, y); } + + public static boolean outOfBounds(Vector2D position, Vector2D size) { + + return (position.x + size.magnitude() < 0 || position.x - size.magnitude() > Master.SCREEN_Y_COORDINATES * Master.SCREEN_RATIO || + position.y + size.magnitude() < 0 || position.y - position.magnitude() > Master.SCREEN_Y_COORDINATES); + } } diff --git a/src/main/java/core/math/Vector2D.java b/src/main/java/core/math/Vector2D.java index fa8050c..caa05ab 100644 --- a/src/main/java/core/math/Vector2D.java +++ b/src/main/java/core/math/Vector2D.java @@ -4,7 +4,7 @@ package core.math; import java.awt.*; /** - * A 2-dimensional Vector that can be used to store position or velocity + * A 2-dimensional Vector that can be used to store position or velocity or size or whatever */ public class Vector2D { @@ -44,6 +44,7 @@ public class Vector2D { return new Vector2D(point.x, point.y); } + /** * Add another Vector to this vector, modifies this object * @@ -123,6 +124,17 @@ public class Vector2D { return new Vector2D(a.x - b.x, a.y - b.y); } + /** + * Divide a Vector by a scalar + * + * @param a Vector a + * @param b Scalar b + * @return The result + */ + public static Vector2D divideS(Vector2D a, double b) { + return new Vector2D(a.x / b, a.y / b); + } + /** * Rotate a point around another point *

diff --git a/src/main/java/core/objects/base/DebugPos.java b/src/main/java/core/objects/base/DebugPos.java index 3299c63..d13c840 100644 --- a/src/main/java/core/objects/base/DebugPos.java +++ b/src/main/java/core/objects/base/DebugPos.java @@ -1,5 +1,6 @@ package core.objects.base; +import core.math.Coords; import core.math.Vector2D; import core.objects.core.GameObject; diff --git a/src/main/java/core/objects/core/CollGameObject.java b/src/main/java/core/objects/core/CollGameObject.java index 4a1c161..3213694 100644 --- a/src/main/java/core/objects/core/CollGameObject.java +++ b/src/main/java/core/objects/core/CollGameObject.java @@ -5,12 +5,16 @@ import core.objects.core.GameObject; import core.physics.Collidable; import core.physics.hitboxes.Hitbox; +import java.util.ArrayList; + /** * A specialization of GameObject with Collidable properties */ public abstract class CollGameObject extends GameObject implements Collidable { protected Hitbox hitbox; + protected ArrayList> ignores = new ArrayList<>(); + protected boolean isTrigger = false; public CollGameObject(Vector2D position, Vector2D size, Hitbox hitbox) { super(position, size); @@ -54,4 +58,18 @@ public abstract class CollGameObject extends GameObject implements Collidable { public Vector2D getSize() { return size; } + + @Override + public void onCollision() { + } + + @Override + public ArrayList> getIgnores() { + return ignores; + } + + @Override + public boolean isTrigger() { + return isTrigger; + } } diff --git a/src/main/java/core/objects/core/GameObject.java b/src/main/java/core/objects/core/GameObject.java index 3ebe307..d0b7eb1 100644 --- a/src/main/java/core/objects/core/GameObject.java +++ b/src/main/java/core/objects/core/GameObject.java @@ -1,18 +1,20 @@ package core.objects.core; import core.math.Coords; -import core.Drawable; -import core.Master; +import core.general.Drawable; +import core.general.Master; import core.math.Vector2D; import java.awt.*; /** * The GameObject class is the superclass of every GameObject that can be displayed on screen. It has the 2 - * {@link #update()} and {@link #draw(Graphics2D)} methods that have to be + * {@link #update()} and {@link #draw(Graphics2D)} methods that have to be overridden */ public abstract class GameObject implements Drawable { + protected boolean doesDespawn = true; + protected Vector2D position; protected Vector2D size; @@ -37,6 +39,12 @@ public abstract class GameObject implements Drawable { this.layer = 0; } + public void startUpdate(){ + if(Coords.outOfBounds(position, size)){ + destroy(); + } + update(); + } /** *

The update method is called every frame before the {@link #draw(Graphics2D)} method by the master object on each object. Everything @@ -99,7 +107,12 @@ public abstract class GameObject implements Drawable { Vector2D abs; - abs = (arg.contains("center")) ? Coords.getWorldCoords(getCenterPosition()) : Coords.getWorldCoords(position); + if(arg.contains("center")){ + abs = Coords.getWorldCoords(new Vector2D(position.x - size.x / 2, position.y - size.y / 2)); + } else { + abs = Coords.getWorldCoords(position); + } + Vector2D sizeAbs = Coords.getWorldCoords(size); g2d.setPaint(mainColor); @@ -121,7 +134,6 @@ public abstract class GameObject implements Drawable { g2d.fillRoundRect((int) abs.x, (int) abs.y, (int) sizeAbs.x, (int) sizeAbs.y, arcW, arcH); } - @Deprecated public void destroy() { master.destroy(this); } diff --git a/src/main/java/core/physics/Collidable.java b/src/main/java/core/physics/Collidable.java index 91f153c..1091f6e 100644 --- a/src/main/java/core/physics/Collidable.java +++ b/src/main/java/core/physics/Collidable.java @@ -3,10 +3,14 @@ package core.physics; import core.math.Vector2D; import core.physics.hitboxes.Hitbox; +import java.util.ArrayList; + public interface Collidable { Hitbox getHitbox(); Vector2D getCenterPos(); Vector2D getSize(); - + void onCollision(); + ArrayList> getIgnores(); + boolean isTrigger(); } diff --git a/src/main/java/core/physics/hitboxes/Hitbox.java b/src/main/java/core/physics/hitboxes/Hitbox.java index 00eb65f..4f005fa 100644 --- a/src/main/java/core/physics/hitboxes/Hitbox.java +++ b/src/main/java/core/physics/hitboxes/Hitbox.java @@ -1,11 +1,12 @@ package core.physics.hitboxes; -import core.Drawable; +import core.general.Drawable; import core.math.Vector2D; -import core.physics.Collision; public abstract class Hitbox implements Drawable { + + public static final int HITBOX_RENDER_LAYER = 1; private final boolean isTrigger; protected Hitbox(boolean isTrigger) { diff --git a/src/main/java/core/physics/hitboxes/RectHitBox.java b/src/main/java/core/physics/hitboxes/RectHitBox.java index bab67d0..866c9ca 100644 --- a/src/main/java/core/physics/hitboxes/RectHitBox.java +++ b/src/main/java/core/physics/hitboxes/RectHitBox.java @@ -1,7 +1,7 @@ package core.physics.hitboxes; import core.math.Coords; -import core.Master; +import core.general.Master; import core.math.Vector2D; import java.awt.*; @@ -31,7 +31,7 @@ public class RectHitBox extends Hitbox { this.x2 = Vector2D.add(x1, new Vector2D(size.x, 0)); this.y1 = Vector2D.add(x1, new Vector2D(0, size.y)); this.y2 = Vector2D.add(x1, new Vector2D(size.x, size.y)); - Master.getMaster().addDrawable(this, 1); + Master.getMaster().addDrawable(this, HITBOX_RENDER_LAYER); } /** @@ -46,7 +46,6 @@ public class RectHitBox extends Hitbox { this.x2 = Vector2D.add(x1, new Vector2D(size.x, 0)); this.y1 = Vector2D.add(x1, new Vector2D(0, size.y)); this.y2 = Vector2D.add(x1, new Vector2D(size.x, size.y)); - Master.getMaster().addDrawable(this, 1); } /** @@ -166,10 +165,10 @@ public class RectHitBox extends Hitbox { return y2; } - @Override +/* @Override public String toString() { return "RectHitBox{" + x1 + " " + x2 + "\n" + y1 + " " + y2 + "}"; - } + }*/ @Override public void draw(Graphics2D g2d) { @@ -177,7 +176,7 @@ public class RectHitBox extends Hitbox { Vector2D abs = Coords.getWorldCoords(x1); Vector2D sizeAbs = Coords.getWorldCoords(Vector2D.subtract(y2, x1)); - g2d.drawRect((int)abs.x, (int)abs.y, (int)sizeAbs.x, (int)sizeAbs.y); g2d.setPaint(Color.MAGENTA); + g2d.drawRect((int)abs.x, (int)abs.y, (int)sizeAbs.x, (int)sizeAbs.y); } } diff --git a/src/main/java/objects/GameObject.java b/src/main/java/objects/GameObject.java new file mode 100644 index 0000000..6234486 --- /dev/null +++ b/src/main/java/objects/GameObject.java @@ -0,0 +1,67 @@ +package objects; + +import core.general.Master; +import core.math.Vector2D; + +import java.awt.*; + +/** + * The GameObject class is the superclass of every GameObject that can be displayed on screen. It has the 2 + * {@link #update(Master)} and {@link #draw(Graphics2D, int, Master)} methods that have to be + */ +public abstract class GameObject { + + protected int w; + protected int h; + + protected Vector2D position; + protected Vector2D size; + + protected Vector2D velocity; + + public GameObject(double x, double y, double xSize, double ySize) { + this(new Vector2D(x, y), new Vector2D(xSize, ySize)); + } + + public GameObject(Vector2D position, Vector2D size) { + this.position = position; + this.size = size; + this.velocity = new Vector2D(); + } + + public abstract void draw(Graphics2D g2d, int w, Master master); + public abstract void update(Master master); + + + public double getMapCoords(double value, boolean isX){ + if (isX){ + return (position.x + value / 100 * size.x); + } else { + return (position.y + value / 100 * size.y); + } + } + + public double getMapCoordsSize(double value, boolean useX){ + if (useX){ + return (value / 100 * size.x); + } else { + return (value / 100 * size.y); + } + } + + public double getWorldCoords(double value, boolean isX){ + if (isX){ + return (value / 100 * w); + } else { + return (value / 100 * h); + } + } + + public int getWorldCoordsFromLocal(double value, boolean isX){ + return (int) getWorldCoords(getMapCoords(value, isX), isX); + } + + public int getWorldCoordsFromLocalSize(double value, boolean useX){ + return (int) getWorldCoords(getMapCoordsSize(value, useX), useX); + } +} diff --git a/src/main/java/objects/ships/BattleShip.java b/src/main/java/objects/ships/BattleShip.java index 6a036dd..999d06f 100644 --- a/src/main/java/objects/ships/BattleShip.java +++ b/src/main/java/objects/ships/BattleShip.java @@ -14,10 +14,9 @@ public class BattleShip extends GameObject { public BattleShip(Color mainColor) { this(20, 20, 10, 40, mainColor); - //TODO turret size should use w and h but correct just like with world coords - turrets.add(new Turret(this, 2.5, 10, 5, 3)); - //turrets.add(new Turret(this, 25, 10, 50, 2)); - //turrets.add(new Turret(this, 25, 70, 50, 2)); + turrets.add(new Turret(this, 2.5, 7, 5, 3)); + turrets.add(new Turret(this, 2.5, 15, 5, 3)); + turrets.add(new Turret(this, 2.5, 25, 5, 3)); } public BattleShip(double x, double y, double xSize, double ySize, Color mainColor) { diff --git a/src/main/java/objects/ships/Shell.java b/src/main/java/objects/ships/Shell.java index 991cf83..3c82ae7 100644 --- a/src/main/java/objects/ships/Shell.java +++ b/src/main/java/objects/ships/Shell.java @@ -1,20 +1,23 @@ package objects.ships; import core.math.Vector2D; -import core.objects.core.GameObject; +import core.objects.core.CollGameObject; +import core.physics.hitboxes.RectHitBox; import java.awt.*; /** * A shell fired by a cannon */ -public class Shell extends GameObject { +public class Shell extends CollGameObject { public Shell(Vector2D position, Vector2D size, Vector2D velocity) { - super(position, size/*, new RectHitBox(position, size)*/); + super(position, size, new RectHitBox(position, size)); this.velocity = velocity; this.mainColor = Color.ORANGE; + this.ignores.add(Shell.class); + this.isTrigger = true; } @Override @@ -26,4 +29,10 @@ public class Shell extends GameObject { public void update() { moveTo(Vector2D.add(position, velocity)); } + + @Override + public void onCollision() { + destroy(); + //master.debugPos(position); + } } diff --git a/src/main/java/objects/ships/Submarine.java b/src/main/java/objects/ships/Submarine.java index b9cfb6c..2b6dc4a 100644 --- a/src/main/java/objects/ships/Submarine.java +++ b/src/main/java/objects/ships/Submarine.java @@ -27,5 +27,4 @@ public class Submarine extends CollGameObject { Vector2D centerRelPos = new Vector2D(relPos.x - size.x/2, relPos.y - size.y/2); moveTo(centerRelPos); } - } diff --git a/src/main/java/objects/ships/Turret.java b/src/main/java/objects/ships/Turret.java index 86e480d..6ca7943 100644 --- a/src/main/java/objects/ships/Turret.java +++ b/src/main/java/objects/ships/Turret.java @@ -81,8 +81,8 @@ public class Turret extends GameObject { Point msLoc = master.getMouseLocation(); Vector2D mouseRel = Coords.getMapCoordsFromWorld(Vector2D.fromPoint(msLoc)); //100 correct - Vector2D center = battleShip.getMapCoords(getCenterPosition()); - double targetRotation = -Math.atan2(center.x - mouseRel.x, center.y - mouseRel.y); + Vector2D centerMap = battleShip.getMapCoords(getCenterPosition()); + double targetRotation = -Math.atan2(centerMap.x - mouseRel.x, centerMap.y - mouseRel.y); rotation = ExMath.angleLerp(rotation, targetRotation, ROTATION_SPEED); @@ -98,14 +98,13 @@ public class Turret extends GameObject { lastShot = System.currentTimeMillis(); Vector2D shellVel = Vector2D.getUnitVector(rotation).negative().multiply(SHELL_SPEED); - master.debugPos(battleShip.getMapCoords(center)); - master.debugPos(center); + //master.debugPos(centerMap); Vector2D pos = Vector2D.rotateAround( - battleShip.getMapCoords(center), + centerMap, spawnPosNR, rotation); - master.debugPos(pos); + //master.debugPos(pos); master.create(new Shell(pos, new Vector2D(SHELL_SIZE, SHELL_SIZE), shellVel)); } } diff --git a/target/classes/BasicEx$1.class b/target/classes/BasicEx$1.class deleted file mode 100644 index fd3f4b9..0000000 Binary files a/target/classes/BasicEx$1.class and /dev/null differ diff --git a/target/classes/BasicEx.class b/target/classes/BasicEx.class deleted file mode 100644 index 296712b..0000000 Binary files a/target/classes/BasicEx.class and /dev/null differ diff --git a/target/classes/core/Master.class b/target/classes/core/Master.class index e0c9a96..1d8e907 100644 Binary files a/target/classes/core/Master.class and b/target/classes/core/Master.class differ diff --git a/target/classes/objects/DebugPos.class b/target/classes/objects/DebugPos.class deleted file mode 100644 index 1dfedb2..0000000 Binary files a/target/classes/objects/DebugPos.class and /dev/null differ diff --git a/target/classes/objects/ships/BattleShip.class b/target/classes/objects/ships/BattleShip.class index 4318895..66e57a4 100644 Binary files a/target/classes/objects/ships/BattleShip.class and b/target/classes/objects/ships/BattleShip.class differ diff --git a/target/classes/objects/ships/Shell.class b/target/classes/objects/ships/Shell.class index 5c94f50..a6e08ca 100644 Binary files a/target/classes/objects/ships/Shell.class and b/target/classes/objects/ships/Shell.class differ diff --git a/target/classes/objects/ships/Turret.class b/target/classes/objects/ships/Turret.class index 47a3d55..bc981b0 100644 Binary files a/target/classes/objects/ships/Turret.class and b/target/classes/objects/ships/Turret.class differ diff --git a/target/classes/objects/world/Grid.class b/target/classes/objects/world/Grid.class index c26fd1e..488ac1a 100644 Binary files a/target/classes/objects/world/Grid.class and b/target/classes/objects/world/Grid.class differ