better rotation mechanics

This commit is contained in:
nora 2020-12-11 22:33:18 +01:00
parent 3bf79290bb
commit 35c47c50b8
10 changed files with 98 additions and 8 deletions

View file

@ -0,0 +1,28 @@
package core;
/**
* Extended Math functions for the game engine
*/
public class ExMath {
private ExMath(){
}
/**
* Lerp an angle in radians
*
* @param from The start angle
* @param to The target angle
* @param t The value
* @return The new angle
*
* @see <a href="https://gist.github.com/shaunlebron/8832585"angleLerp</a>
*/
public static double angleLerp(double from, double to, double t) {
double max = Math.PI * 2;
double da = (to - from) % max;
double shortAngleDist = 2 * da % max - da;
return from + shortAngleDist * t;
}
}

View file

@ -133,6 +133,30 @@ public class Vector2D {
return new Vector2D(rotatedX + center.x, rotatedY + center.y);
}
/**
* Rotate a point around another point
*
* This method can now be trusted
*
* @param center The center of the rotation
* @param value The point to be rotated, absolut to the center
* @param rotation The rotation angle in radians
* @return The rotated point
*/
public static Vector2D rotateAround(Vector2D center, Vector2D value, double rotation){
return rotateAround(center, value, rotation, COUNTERCLOCKWISE);
}
/**
* Get a unit vector with magnitude 1 and the direction
* @param direction The direction of the vector
* @return The unit vector
*/
public static Vector2D getUnitVector(double direction){
return rotateAround(new Vector2D(), new Vector2D(0, 1), direction);
}
/**
* Copy this object
* @return A copy of this object
@ -165,4 +189,8 @@ 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);
}
}

View file

@ -18,8 +18,8 @@ public class BattleShip extends GameObject {
super(20, 20, 5, 40);
turrets = new ArrayList<>();
turrets.add(new Turret(this, 25, 25, 50, 3));
turrets.add(new Turret(this, 25, 10, 50, 2));
turrets.add(new Turret(this, 25, 70, 50, 2));
//turrets.add(new Turret(this, 25, 10, 50, 2));
//turrets.add(new Turret(this, 25, 70, 50, 2));
this.mainColor = mainColor;
}

View file

@ -0,0 +1,18 @@
package objects.ships;
import core.Master;
import objects.GameObject;
import java.awt.*;
public class Submarine extends GameObject {
@Override
public void draw(Graphics2D g2d, int w, Master master) {
}
@Override
public void update(Master master) {
}
}

View file

@ -1,5 +1,6 @@
package objects.ships;
import core.ExMath;
import core.Master;
import core.Vector2D;
import objects.GameObject;
@ -11,18 +12,21 @@ import java.awt.*;
*/
public class Turret extends GameObject {
private static final double ROTATION_SPEED = 2;
private static final double ROTATION_SPEED = 0.05;
private static final int SHOT_EFFECT_TIME = 300;
private static final int SHELL_SPEED = 10;
BattleShip battleShip;
private int barrelAmount = 3;
private double rotation;
private Color mainColor;
private long lastShot = 0;
private static int SHOT_EFFECT_TIME = 300;
private static int SHELL_SPEED = 10;
private double rotation;
//private double rotation;
public Turret(BattleShip battleShip, double x, double y, double size, int barrelAmount) {
super(x, y, size, size);
@ -58,6 +62,7 @@ public class Turret extends GameObject {
g2d.setPaint(Color.BLACK);
int barrelSpacing = sizeAbs / (barrelAmount + 1);
g2d.rotate(rotation, xCenterAbs, yCenterAbs);
for (int i = 0; i < barrelAmount; i++) {
int barrelX = xAbs + (i + 1) * barrelSpacing;
int frontPosY = yAbs - sizeAbs / 2;
@ -82,7 +87,10 @@ public class Turret extends GameObject {
int yCenterAbs = yAbs + sizeAbs / 2;
Point msLoc = master.getMouseLocation();
rotation = -Math.atan2(xCenterAbs - msLoc.x, yCenterAbs - msLoc.y);
double targetRotation = -Math.atan2(xCenterAbs - msLoc.x, yCenterAbs - msLoc.y);
rotation = ExMath.angleLerp(rotation, targetRotation, ROTATION_SPEED);
int barrelSpacing = sizeAbs / (barrelAmount + 1);
@ -93,7 +101,7 @@ public class Turret extends GameObject {
if (master.isMousePressed()) {
lastShot = System.currentTimeMillis();
Vector2D shellVel = new Vector2D(xCenterAbs - msLoc.x, yCenterAbs - msLoc.y).normalized().negative().multiply(SHELL_SPEED);
Vector2D shellVel = Vector2D.getUnitVector(rotation).negative().multiply(SHELL_SPEED);
Vector2D pos = Vector2D.rotateAround(new Vector2D(xCenterAbs, yCenterAbs), new Vector2D(barrelX, frontPosY), rotation, Vector2D.COUNTERCLOCKWISE);
master.create(new Shell(pos, new Vector2D(10, 10), shellVel));

View file

@ -67,7 +67,15 @@ class Vector2DTest {
assertEquals(round(expected), round(rotated));
}
public static Vector2D round(Vector2D a){
return new Vector2D(Math.round(a.x*10000d)/10000d, Math.round(a.y*10000d)/10000d);
}
@Test
void getUnitVectorSimple() {
double dir = Math.PI;
Vector2D expected = new Vector2D(0, -1);
assertEquals(round(expected), round(Vector2D.getUnitVector(dir)));
}
}