big update, stonks

This commit is contained in:
nora 2020-12-18 18:40:59 +01:00
parent 9f460d499a
commit 8e15ad3ac8
26 changed files with 200 additions and 49 deletions

2
.idea/misc.xml generated
View file

@ -8,7 +8,7 @@
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_15" default="false" project-jdk-name="15" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_14" project-jdk-name="14" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

2
2DGame.iml Normal file
View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4" />

View file

@ -1,4 +1,4 @@
import core.Master; import core.general.Master;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
@ -24,7 +24,8 @@ class Main extends JFrame {
add(master); add(master);
setTitle("Points"); setTitle("Points");
setSize(1000, (int) (1000 / Master.SCREEN_RATIO)); int w = 1500;
setSize(w, (int) (w / Master.SCREEN_RATIO));
setLocationRelativeTo(null); setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

View file

@ -1,4 +1,4 @@
package core; package core.general;
import java.awt.Graphics2D; import java.awt.Graphics2D;

View file

@ -1,12 +1,15 @@
package core; package core.general;
import core.math.Vector2D; import core.math.Vector2D;
import core.objects.core.CollGameObject;
import core.physics.Collidable; import core.physics.Collidable;
import core.physics.Collision; import core.physics.Collision;
import core.objects.base.DebugPos; import core.objects.base.DebugPos;
import core.physics.hitboxes.Hitbox;
import objects.ships.BattleShip; import objects.ships.BattleShip;
import core.objects.core.GameObject; import core.objects.core.GameObject;
import objects.ships.Submarine; import objects.ships.Submarine;
import objects.ships.Turret;
import objects.world.Grid; import objects.world.Grid;
import objects.world.Wall; import objects.world.Wall;
@ -45,6 +48,7 @@ public class Master extends JPanel {
*/ */
private final ArrayList<ArrayList<Drawable>> drawables; private final ArrayList<ArrayList<Drawable>> drawables;
/** /**
* All physics objects that exist * All physics objects that exist
*/ */
@ -55,6 +59,11 @@ public class Master extends JPanel {
*/ */
private final ArrayList<GameObject> objectBuffer; private final ArrayList<GameObject> objectBuffer;
/**
* All physics objects that exist
*/
private final ArrayList<Collidable> collidablesBuffer;
/** /**
* Whether the left mouse button has been pressed since the last frame * Whether the left mouse button has been pressed since the last frame
*/ */
@ -74,6 +83,7 @@ public class Master extends JPanel {
objects = new ArrayList<>(); objects = new ArrayList<>();
objectBuffer = new ArrayList<>(); objectBuffer = new ArrayList<>();
collidables = new ArrayList<>(); collidables = new ArrayList<>();
collidablesBuffer = new ArrayList<>();
drawables = new ArrayList<>(); drawables = new ArrayList<>();
drawables.add(new ArrayList<>()); drawables.add(new ArrayList<>());
@ -82,9 +92,11 @@ public class Master extends JPanel {
BattleShip battleShip = new BattleShip(Color.DARK_GRAY); BattleShip battleShip = new BattleShip(Color.DARK_GRAY);
BattleShip bs = new BattleShip(140, 10, 10, 80, Color.GREEN); 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(bs);
create(battleShip); 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 * This method is the entry method for each frame. It handles everything about the frame
*/ */
public void refresh() { public void refresh() {
long time = System.currentTimeMillis();
objects.clear();
objects.addAll(objectBuffer); objects.addAll(objectBuffer);
objectBuffer.clear(); collidables.clear();
objects.forEach(GameObject::update); collidables.addAll(collidablesBuffer);
objects.forEach(GameObject::startUpdate);
long time2 = System.currentTimeMillis();
mousePressed = false; mousePressed = false;
repaint(); 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) { public void create(GameObject obj, int renderLayer) {
objectBuffer.add(obj); objectBuffer.add(obj);
if (obj instanceof Collidable) { if (obj instanceof CollGameObject) {
collidables.add((Collidable) obj); collidablesBuffer.add((Collidable) obj);
} }
addDrawable(obj, renderLayer); 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 * @return True if it collides with something, false if it doesn't - Should return a Collision
*/ */
public Collision doesCollide(Collidable collidable) { public Collision doesCollide(Collidable collidable) {
long time = System.nanoTime();
Collision collides = null; Collision collides = null;
for (Collidable other : collidables) { 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())) { double distance = Vector2D.distance(other.getCenterPos(), collidable.getCenterPos());
collides = new Collision(collidable, other); 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) { public void destroy(GameObject gameObject) {
objects.remove(gameObject);
objectBuffer.remove(gameObject); objectBuffer.remove(gameObject);
drawables.get(gameObject.getLayer()).remove(gameObject); drawables.get(gameObject.getLayer()).remove(gameObject);
if (gameObject instanceof Collidable) { if (gameObject instanceof Collidable) {
collidables.remove(gameObject); collidablesBuffer.remove(gameObject);
drawables.get(Hitbox.HITBOX_RENDER_LAYER).remove(((CollGameObject) gameObject).getHitbox());
} }
} }
} }

View file

@ -1,7 +1,6 @@
package core.math; package core.math;
import core.Master; import core.general.Master;
import core.math.Vector2D;
/** /**
* This class provides everything about the local coordinate system the game uses * 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 * Get the world coordinates of a point in map coordinates
*
* @param value A point in map coordinates * @param value A point in map coordinates
* @return The point in world coordinates * @return The point in world coordinates
*/ */
@ -44,4 +44,10 @@ public class Coords {
double y = (value.y / master.getH()) * Master.SCREEN_Y_COORDINATES; double y = (value.y / master.getH()) * Master.SCREEN_Y_COORDINATES;
return new Vector2D(x, y); 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);
}
} }

View file

@ -4,7 +4,7 @@ package core.math;
import java.awt.*; 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 { public class Vector2D {
@ -44,6 +44,7 @@ public class Vector2D {
return new Vector2D(point.x, point.y); return new Vector2D(point.x, point.y);
} }
/** /**
* Add another Vector to this vector, modifies this object * 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); 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 * Rotate a point around another point
* <p> * <p>

View file

@ -1,5 +1,6 @@
package core.objects.base; package core.objects.base;
import core.math.Coords;
import core.math.Vector2D; import core.math.Vector2D;
import core.objects.core.GameObject; import core.objects.core.GameObject;

View file

@ -5,12 +5,16 @@ import core.objects.core.GameObject;
import core.physics.Collidable; import core.physics.Collidable;
import core.physics.hitboxes.Hitbox; import core.physics.hitboxes.Hitbox;
import java.util.ArrayList;
/** /**
* A specialization of GameObject with Collidable properties * A specialization of GameObject with Collidable properties
*/ */
public abstract class CollGameObject extends GameObject implements Collidable { public abstract class CollGameObject extends GameObject implements Collidable {
protected Hitbox hitbox; protected Hitbox hitbox;
protected ArrayList<Class<?>> ignores = new ArrayList<>();
protected boolean isTrigger = false;
public CollGameObject(Vector2D position, Vector2D size, Hitbox hitbox) { public CollGameObject(Vector2D position, Vector2D size, Hitbox hitbox) {
super(position, size); super(position, size);
@ -54,4 +58,18 @@ public abstract class CollGameObject extends GameObject implements Collidable {
public Vector2D getSize() { public Vector2D getSize() {
return size; return size;
} }
@Override
public void onCollision() {
}
@Override
public ArrayList<Class<?>> getIgnores() {
return ignores;
}
@Override
public boolean isTrigger() {
return isTrigger;
}
} }

View file

@ -1,18 +1,20 @@
package core.objects.core; package core.objects.core;
import core.math.Coords; import core.math.Coords;
import core.Drawable; import core.general.Drawable;
import core.Master; import core.general.Master;
import core.math.Vector2D; import core.math.Vector2D;
import java.awt.*; import java.awt.*;
/** /**
* The GameObject class is the superclass of every GameObject that can be displayed on screen. It has the 2 * 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 { public abstract class GameObject implements Drawable {
protected boolean doesDespawn = true;
protected Vector2D position; protected Vector2D position;
protected Vector2D size; protected Vector2D size;
@ -37,6 +39,12 @@ public abstract class GameObject implements Drawable {
this.layer = 0; this.layer = 0;
} }
public void startUpdate(){
if(Coords.outOfBounds(position, size)){
destroy();
}
update();
}
/** /**
* <p>The update method is called every frame before the {@link #draw(Graphics2D)} method by the master object on each object. Everything * <p>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; 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); Vector2D sizeAbs = Coords.getWorldCoords(size);
g2d.setPaint(mainColor); 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); g2d.fillRoundRect((int) abs.x, (int) abs.y, (int) sizeAbs.x, (int) sizeAbs.y, arcW, arcH);
} }
@Deprecated
public void destroy() { public void destroy() {
master.destroy(this); master.destroy(this);
} }

View file

@ -3,10 +3,14 @@ package core.physics;
import core.math.Vector2D; import core.math.Vector2D;
import core.physics.hitboxes.Hitbox; import core.physics.hitboxes.Hitbox;
import java.util.ArrayList;
public interface Collidable { public interface Collidable {
Hitbox getHitbox(); Hitbox getHitbox();
Vector2D getCenterPos(); Vector2D getCenterPos();
Vector2D getSize(); Vector2D getSize();
void onCollision();
ArrayList<Class<?>> getIgnores();
boolean isTrigger();
} }

View file

@ -1,11 +1,12 @@
package core.physics.hitboxes; package core.physics.hitboxes;
import core.Drawable; import core.general.Drawable;
import core.math.Vector2D; import core.math.Vector2D;
import core.physics.Collision;
public abstract class Hitbox implements Drawable { public abstract class Hitbox implements Drawable {
public static final int HITBOX_RENDER_LAYER = 1;
private final boolean isTrigger; private final boolean isTrigger;
protected Hitbox(boolean isTrigger) { protected Hitbox(boolean isTrigger) {

View file

@ -1,7 +1,7 @@
package core.physics.hitboxes; package core.physics.hitboxes;
import core.math.Coords; import core.math.Coords;
import core.Master; import core.general.Master;
import core.math.Vector2D; import core.math.Vector2D;
import java.awt.*; import java.awt.*;
@ -31,7 +31,7 @@ public class RectHitBox extends Hitbox {
this.x2 = Vector2D.add(x1, new Vector2D(size.x, 0)); this.x2 = Vector2D.add(x1, new Vector2D(size.x, 0));
this.y1 = Vector2D.add(x1, new Vector2D(0, size.y)); this.y1 = Vector2D.add(x1, new Vector2D(0, size.y));
this.y2 = Vector2D.add(x1, new Vector2D(size.x, 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.x2 = Vector2D.add(x1, new Vector2D(size.x, 0));
this.y1 = Vector2D.add(x1, new Vector2D(0, size.y)); this.y1 = Vector2D.add(x1, new Vector2D(0, size.y));
this.y2 = Vector2D.add(x1, new Vector2D(size.x, 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; return y2;
} }
@Override /* @Override
public String toString() { public String toString() {
return "RectHitBox{" + x1 + " " + x2 + "\n" + y1 + " " + y2 + "}"; return "RectHitBox{" + x1 + " " + x2 + "\n" + y1 + " " + y2 + "}";
} }*/
@Override @Override
public void draw(Graphics2D g2d) { public void draw(Graphics2D g2d) {
@ -177,7 +176,7 @@ public class RectHitBox extends Hitbox {
Vector2D abs = Coords.getWorldCoords(x1); Vector2D abs = Coords.getWorldCoords(x1);
Vector2D sizeAbs = Coords.getWorldCoords(Vector2D.subtract(y2, 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.setPaint(Color.MAGENTA);
g2d.drawRect((int)abs.x, (int)abs.y, (int)sizeAbs.x, (int)sizeAbs.y);
} }
} }

View file

@ -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);
}
}

View file

@ -14,10 +14,9 @@ public class BattleShip extends GameObject {
public BattleShip(Color mainColor) { public BattleShip(Color mainColor) {
this(20, 20, 10, 40, 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, 7, 5, 3));
turrets.add(new Turret(this, 2.5, 10, 5, 3)); turrets.add(new Turret(this, 2.5, 15, 5, 3));
//turrets.add(new Turret(this, 25, 10, 50, 2)); turrets.add(new Turret(this, 2.5, 25, 5, 3));
//turrets.add(new Turret(this, 25, 70, 50, 2));
} }
public BattleShip(double x, double y, double xSize, double ySize, Color mainColor) { public BattleShip(double x, double y, double xSize, double ySize, Color mainColor) {

View file

@ -1,20 +1,23 @@
package objects.ships; package objects.ships;
import core.math.Vector2D; import core.math.Vector2D;
import core.objects.core.GameObject; import core.objects.core.CollGameObject;
import core.physics.hitboxes.RectHitBox;
import java.awt.*; import java.awt.*;
/** /**
* A shell fired by a cannon * A shell fired by a cannon
*/ */
public class Shell extends GameObject { public class Shell extends CollGameObject {
public Shell(Vector2D position, Vector2D size, Vector2D velocity) { 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.velocity = velocity;
this.mainColor = Color.ORANGE; this.mainColor = Color.ORANGE;
this.ignores.add(Shell.class);
this.isTrigger = true;
} }
@Override @Override
@ -26,4 +29,10 @@ public class Shell extends GameObject {
public void update() { public void update() {
moveTo(Vector2D.add(position, velocity)); moveTo(Vector2D.add(position, velocity));
} }
@Override
public void onCollision() {
destroy();
//master.debugPos(position);
}
} }

View file

@ -27,5 +27,4 @@ public class Submarine extends CollGameObject {
Vector2D centerRelPos = new Vector2D(relPos.x - size.x/2, relPos.y - size.y/2); Vector2D centerRelPos = new Vector2D(relPos.x - size.x/2, relPos.y - size.y/2);
moveTo(centerRelPos); moveTo(centerRelPos);
} }
} }

View file

@ -81,8 +81,8 @@ public class Turret extends GameObject {
Point msLoc = master.getMouseLocation(); Point msLoc = master.getMouseLocation();
Vector2D mouseRel = Coords.getMapCoordsFromWorld(Vector2D.fromPoint(msLoc)); //100 correct Vector2D mouseRel = Coords.getMapCoordsFromWorld(Vector2D.fromPoint(msLoc)); //100 correct
Vector2D center = battleShip.getMapCoords(getCenterPosition()); Vector2D centerMap = battleShip.getMapCoords(getCenterPosition());
double targetRotation = -Math.atan2(center.x - mouseRel.x, center.y - mouseRel.y); double targetRotation = -Math.atan2(centerMap.x - mouseRel.x, centerMap.y - mouseRel.y);
rotation = ExMath.angleLerp(rotation, targetRotation, ROTATION_SPEED); rotation = ExMath.angleLerp(rotation, targetRotation, ROTATION_SPEED);
@ -98,14 +98,13 @@ public class Turret extends GameObject {
lastShot = System.currentTimeMillis(); lastShot = System.currentTimeMillis();
Vector2D shellVel = Vector2D.getUnitVector(rotation).negative().multiply(SHELL_SPEED); Vector2D shellVel = Vector2D.getUnitVector(rotation).negative().multiply(SHELL_SPEED);
master.debugPos(battleShip.getMapCoords(center)); //master.debugPos(centerMap);
master.debugPos(center);
Vector2D pos = Vector2D.rotateAround( Vector2D pos = Vector2D.rotateAround(
battleShip.getMapCoords(center), centerMap,
spawnPosNR, spawnPosNR,
rotation); rotation);
master.debugPos(pos); //master.debugPos(pos);
master.create(new Shell(pos, new Vector2D(SHELL_SIZE, SHELL_SIZE), shellVel)); master.create(new Shell(pos, new Vector2D(SHELL_SIZE, SHELL_SIZE), shellVel));
} }
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.