diff --git a/src/awlex/ospu/FakeGameObject.java b/src/awlex/ospu/FakeGameObject.java index f2ee29fc..7777baf9 100644 --- a/src/awlex/ospu/FakeGameObject.java +++ b/src/awlex/ospu/FakeGameObject.java @@ -27,30 +27,13 @@ public class FakeGameObject extends GameObject { } public FakeGameObject(GameObject start, GameObject end) { - halfTime = Math.abs(start.getEndTime() + (end.getTime() - start.getEndTime()) / 2); + halfTime = start.getEndTime() + (end.getTime() - start.getEndTime()) / 2; this.start = new Vec2f(); this.end = new Vec2f(); this.start.x = this.end.x = (start.end.x + end.start.x) / 2; this.start.y = this.end.y = (start.end.y + end.start.y) / 2; } - - @Override - public int getEndTime() { - return halfTime; - } - - @Override - public int getTime() { - return halfTime; - } - - public void setTime(int time) { - this.halfTime = time; - } - - /* - * Everything down here is unimportant - */ + @Override public void draw(Graphics g, int trackPosition, boolean mirrored) { @@ -70,7 +53,17 @@ public class FakeGameObject extends GameObject { public Vec2f getPointAt(int trackPosition) { return null; } - + + @Override + public int getEndTime() { + return halfTime; + } + + @Override + public int getTime() { + return halfTime; + } + @Override public void updatePosition() { @@ -105,4 +98,8 @@ public class FakeGameObject extends GameObject { return null; } + public void setTime(int time) { + this.halfTime = time; + } + } \ No newline at end of file diff --git a/src/awlex/ospu/movers/CentralSpiralMover.java b/src/awlex/ospu/movers/CentralSpiralMover.java index f447cec8..927c524d 100644 --- a/src/awlex/ospu/movers/CentralSpiralMover.java +++ b/src/awlex/ospu/movers/CentralSpiralMover.java @@ -1,36 +1,46 @@ package awlex.ospu.movers; +import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.objects.GameObject; import yugecin.opsudance.movers.Mover; /** * Created by Alex Wieser on 09.10.2016. * WHO DO YOU THINK I AM? - *

+ * * This {@link Mover} starts the spiral from the start object */ -public class CentralSpiralMover extends SpiralMover { - - public CentralSpiralMover(GameObject start, GameObject end, int dir) { - super(start, end, dir); - } - - @Override - public double[] getPointAt(int time) { - double rad = radius * getT(time); - double ang = angle + 2d * Math.PI * getT(time) * dir; - return new double[]{ - startX + rad * Math.cos(ang), - startY + rad * Math.sin(ang) - }; - } - - @Override - public boolean checkBounds() { - boolean ret = true; - int totalTime = endTime - startTime; - for (int i = 0; ret && i <= 20; i++) - ret = checkIfPointInBounds(getPointAt((int) (startTime + totalTime * (i / 20d)))); - return ret; - } +public class CentralSpiralMover extends Mover { + + /** + * How many times the cursor goes around the center + * For satisfying results this musn't be a multiple of 2 + */ + private final int CIRCLENAVIGATIONS = 1; + + double startAng; + double startRad; + + public CentralSpiralMover(GameObject start, GameObject end, int dir) { + super(start, end, dir); + startAng = Math.atan2(endY - startY, endX - startX); + startRad = Utils.distance(startX, startY, endX, endY); + if (startRad < 20) + startRad = 20 + startRad / 20d; + } + + @Override + public double[] getPointAt(int time) { + double rad = startRad * getT(time); + double ang = CIRCLENAVIGATIONS * (startAng + 2d * Math.PI * getT(time) * dir); + return new double[]{ + startX + rad * Math.cos(ang), + startY + rad * Math.sin(ang) + }; + } + + @Override + public String getName() { + return "Spiral2"; + } } diff --git a/src/awlex/ospu/movers/CombinedSpiralMover.java b/src/awlex/ospu/movers/CombinedSpiralMover.java index 74938d73..de0696d8 100644 --- a/src/awlex/ospu/movers/CombinedSpiralMover.java +++ b/src/awlex/ospu/movers/CombinedSpiralMover.java @@ -4,8 +4,6 @@ import awlex.ospu.FakeGameObject; import itdelatrisu.opsu.Options; import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.objects.GameObject; -import yugecin.opsudance.movers.CircleMover; -import yugecin.opsudance.movers.LinearMover; import yugecin.opsudance.movers.Mover; import yugecin.opsudance.movers.factories.AutoMoverFactory; @@ -18,100 +16,120 @@ import yugecin.opsudance.movers.factories.AutoMoverFactory; * 2 inner {@link Mover}s around it. This class works recursively and might lead to * high ram usage on very jumpy maps or even a StackOverFlow. */ -public class CombinedSpiralMover extends SpiralMover { - - private Mover[] movers; - private GameObject fakeObject; - private int halfTime; - private int startTime; - private int endTime; - - public CombinedSpiralMover(GameObject middle, GameObject start, GameObject end, int dir) { - this(true, middle, start, end, dir); - } - - public CombinedSpiralMover(boolean prefered, GameObject middle, GameObject start, GameObject end, int dir) { - super(start, end, dir); - fakeObject = middle != null ? middle : new FakeGameObject(start, end); - - halfTime = fakeObject.getEndTime(); - startTime = start.getEndTime(); - endTime = end.getTime(); - - movers = new Mover[2]; - movers[0] = bestPick(prefered ? 0 : 1, start, fakeObject, dir); - movers[1] = bestPick(prefered ? 1 : 0, fakeObject, end, dir); - } - - public CombinedSpiralMover(GameObject start, GameObject end, int dir) { - this(null, start, end, dir); - } - - @Override - public boolean checkBounds() { - /*Not needed in this case*/ - return true; - } - - - public CombinedSpiralMover(Mover mover1, Mover mover2, int startTime, int halfTime, int endTime) { - super(new FakeGameObject(), new FakeGameObject(), 0); //With this constructor you only care about the movers - this.startTime = startTime; - this.endTime = endTime; - this.halfTime = halfTime; - movers = new Mover[]{ - mover1, - mover2 - }; - } - - /** - * Method to pick the 2 inner {@link Mover}s. - * Tries to pick a {@link SpiralToMover} first position and a - * {@link CombinedSpiralMover} for second position for the sake of good looks - * - * @param pos index of - * @param start start object - * @param end end object - * @param dir direction - * @return best fitting Mover - */ - private Mover bestPick(int pos, GameObject start, GameObject end, int dir) { - - if (endTime - startTime < 40 || Utils.distance(start.end.x, start.end.y, end.start.x, end.start.y) < 40) - return new LinearMover(start, end, dir); - - SpiralToMover spiralTo = new SpiralToMover(start, end, dir); - CentralSpiralMover center = new CentralSpiralMover(start, end, dir); - - if (pos == 0) { - if (spiralTo.checkBounds() || (spiralTo = new SpiralToMover(start, end, -dir)).checkBounds()) - return spiralTo; - else if (center.checkBounds() || (center = new CentralSpiralMover(start, end, -dir)).checkBounds()) - return center; - } - else if (pos == 1) { - if (center.checkBounds() || (center = new CentralSpiralMover(start, end, -dir)).checkBounds()) - return center; - else if ((spiralTo = new SpiralToMover(start, end, -dir)).checkBounds() || (spiralTo = new SpiralToMover(start, end, dir)).checkBounds()) - return spiralTo; - } - else throw new IllegalStateException("Only 2 inner Movers allowed"); - - return new CombinedSpiralMover(start, end, dir); - } - - - @Override - public double[] getPointAt(int time) { - if (time < halfTime) - return movers[0].getPointAt(time); - else if (time > halfTime) - return movers[1].getPointAt(time); - else return new double[]{ - fakeObject.start.x, - fakeObject.start.y - }; - } - +public class CombinedSpiralMover extends Mover { + + private Mover[] movers; + private GameObject fakeObject; + private int halfTime; + private int startTime; + private int endTime; + + public CombinedSpiralMover(GameObject middle, GameObject start, GameObject end, int dir) { + super(start, end, dir); + fakeObject = middle != null ? middle : new FakeGameObject(start, end); + + halfTime = fakeObject.getEndTime(); + startTime = start.getEndTime(); + endTime = end.getTime(); + + movers = new Mover[2]; + movers[0] = bestPick(0, start, fakeObject, dir); + movers[1] = bestPick(1, fakeObject, end, dir); + } + + public CombinedSpiralMover(GameObject start, GameObject end, int dir) { + this(null, start, end, dir); + } + + /** + * Method to pick the 2 inner {@link Mover}s. + * Tries to pick a {@link SpiralToMover} first position and a + * {@link CombinedSpiralMover} for second position for the sake of good looks + * + * @param pos index of + * @param start start object + * @param end end object + * @param dir direction + * @return best fitting Mover + */ + private Mover bestPick(int pos, GameObject start, GameObject end, int dir) { + + if (endTime - startTime < 10 || Utils.distance(start.end.x, start.end.y, end.start.x, end.start.y) < 40) + return new AutoMoverFactory().create(start, end, dir); + + SpiralToMover spiralTo = new SpiralToMover(start, end, dir); + CentralSpiralMover center = new CentralSpiralMover(start, end, dir); + + if (pos == 0) { + if (inBounds1(spiralTo) || inBounds1(spiralTo = new SpiralToMover(start, end, -dir))) + return spiralTo; + else if (inBounds1(center) || inBounds1(center = new CentralSpiralMover(start, end, -dir))) + return center; + } else if (pos == 1) { + if (inBounds2(center) || inBounds2(center = new CentralSpiralMover(start, end, -dir))) + return center; + else if (inBounds2(spiralTo = new SpiralToMover(start, end, -dir)) || inBounds2(spiralTo = new SpiralToMover(start, end, dir))) + return spiralTo; + } else throw new IllegalStateException("Only 2 inner Movers allowed"); + + return new CombinedSpiralMover(start, end, dir); + } + + + @Override + public double[] getPointAt(int time) { + if (time < halfTime) + return movers[0].getPointAt(time); + else if (time > halfTime) + return movers[1].getPointAt(time); + else return new double[]{ + fakeObject.start.x, + fakeObject.start.y + }; + } + + @Override + public String getName() { + return "CombinedSpiralMover"; + } + + /** + * /** + * Check if the first object would be inbounds + * + * @param mover - the mover to check + * @return is mover always inbounds + */ + public boolean inBounds1(Mover mover) { + boolean ret = true; + int middle = halfTime - startTime; + for (int i = 1; ret && i < 15; i++) { + ret = checkBounds(mover.getPointAt(startTime + (middle * i) / 16)); + //System.out.println("i: " + i + " = " + ret); + } + + return ret; + } + + /** + * /** + * Check if the second object would be inbounds + * + * @param mover - the mover to check + * @return is mover always inbounds + */ + private boolean inBounds2(Mover mover) { + boolean ret = true; + int middle = endTime - halfTime; + for (int i = 1; ret && i < 15; i++) { + ret = checkBounds(mover.getPointAt(startTime + (middle * i) / 16)); + //System.out.println("i: " + i + " = " + ret); + } + + return ret; + } + + private boolean checkBounds(double[] pos) { + return 0 < pos[0] && pos[0] < Options.width && 0 < pos[1] && pos[1] < Options.height; + } } diff --git a/src/awlex/ospu/movers/SinusMover.java b/src/awlex/ospu/movers/SinusMover.java new file mode 100644 index 00000000..768c13d3 --- /dev/null +++ b/src/awlex/ospu/movers/SinusMover.java @@ -0,0 +1,38 @@ +package awlex.ospu.movers; + +import itdelatrisu.opsu.Utils; +import itdelatrisu.opsu.objects.GameObject; +import yugecin.opsudance.movers.Mover; + +/** + * Created by Awlex on 27.10.2016. + */ +public class SinusMover extends Mover { + + private double angle; + private double radius; + private double amplitude; + + public SinusMover(GameObject start, GameObject end, int dir) { + super(start, end, dir); + angle = Math.atan2(endY - startY, endX - startX); + radius = Utils.distance(startX, startY, endX, endY); + amplitude = radius / 4; + this.dir = angle < 180 ? dir : -dir; + } + + @Override + public double[] getPointAt(int time) { + double x = radius * getT(time); + double y = amplitude * Math.sin(2d * Math.PI * getT(time)) * dir; + return new double[]{ + startX + x * Math.cos(angle) - y * Math.sin(angle), + startY + x * Math.sin(angle) + y * Math.cos(angle) + }; + } + + @Override + public String getName() { + return "Sinustic"; + } +} diff --git a/src/awlex/ospu/movers/SpiralMover.java b/src/awlex/ospu/movers/SpiralMover.java deleted file mode 100644 index 6aa43195..00000000 --- a/src/awlex/ospu/movers/SpiralMover.java +++ /dev/null @@ -1,55 +0,0 @@ -package awlex.ospu.movers; - -import itdelatrisu.opsu.Options; -import itdelatrisu.opsu.Utils; -import itdelatrisu.opsu.objects.GameObject; -import org.newdawn.slick.util.pathfinding.Mover; - -/** - * Created by Alex Wieser on 22.10.2016. - */ -abstract class SpiralMover extends yugecin.opsudance.movers.Mover { - - protected double angle; - protected double radius; - - int startTime; - int endTime; - - SpiralMover(GameObject start, GameObject end, int dir) { - super(start, end, dir); - angle = Math.atan2(endY - startY, endX - startX); - radius = Utils.distance(startX, startY, endX, endY); - startTime = start.getEndTime(); - endTime = end.getTime(); - } - - public double getAngle() { - return angle; - } - - public double getRadius() { - return radius; - } - - public int getDir() { - return dir; - } - - public abstract boolean checkBounds(); - - @Override - public String getName() { - return getClass().getSimpleName(); - } - - /** - * checks if a point is in bounds - * - * @param pos x and y coordinations - * @return whether this point is within the screen - */ - boolean checkIfPointInBounds(double[] pos) { - return 0 < pos[0] && pos[0] < Options.width && 0 < pos[1] && pos[1] < Options.height; - } -} diff --git a/src/awlex/ospu/movers/SpiralToMover.java b/src/awlex/ospu/movers/SpiralToMover.java index 513253bf..179d132b 100644 --- a/src/awlex/ospu/movers/SpiralToMover.java +++ b/src/awlex/ospu/movers/SpiralToMover.java @@ -1,36 +1,46 @@ package awlex.ospu.movers; +import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.objects.GameObject; import yugecin.opsudance.movers.Mover; /** * Created by Alex Wieser on 09.10.2016. * WHO DO YOU THINK I AM? - *

+ * * This {@link Mover} ends the spiral from the start object */ -public class SpiralToMover extends SpiralMover { - - public SpiralToMover(GameObject start, GameObject end, int dir) { - super(start, end, dir); - } - - @Override - public double[] getPointAt(int time) { - double rad = radius * (1 - getT(time)); - double ang = angle + Math.PI + 2d * Math.PI * (1 - getT(time)) * dir; - return new double[]{ - endX + rad * Math.cos(ang), - endY + rad * Math.sin(ang) - }; - } - - @Override - public boolean checkBounds() { - boolean ret = true; - int totalTime = endTime - startTime; - for (int i = 0; ret && i <= 20; i++) - ret = checkIfPointInBounds(getPointAt((int) (startTime + totalTime * (1 - i / 20d)))); - return ret; - } +public class SpiralToMover extends Mover { + + /** + * How many times the cursor goes around the center + * For satisfying results this musn't be a multiple of 2 + */ + private final int CIRCLENAVIGATIONS = 1; + + double startAng; + double startRad; + + public SpiralToMover(GameObject start, GameObject end, int dir) { + super(start, end, dir); + startAng = Math.atan2(endY - startY, endX - startX) + Math.PI; + startRad = Utils.distance(startX, startY, endX, endY); + if (startRad < 20) + startRad = 20 + startRad / 20d; + } + + @Override + public double[] getPointAt(int time) { + double rad = startRad * (1 - getT(time)); + double ang = CIRCLENAVIGATIONS * (startAng + 2d * Math.PI * (1 - getT(time)) * dir); + return new double[]{ + endX + rad * Math.cos(ang), + endY + rad * Math.sin(ang) + }; + } + + @Override + public String getName() { + return "Spiral2"; + } } diff --git a/src/awlex/ospu/movers/factories/CenterSpiralMoverFactory.java b/src/awlex/ospu/movers/factories/CenterSpiralMoverFactory.java index d2fd7991..46e90730 100644 --- a/src/awlex/ospu/movers/factories/CenterSpiralMoverFactory.java +++ b/src/awlex/ospu/movers/factories/CenterSpiralMoverFactory.java @@ -8,20 +8,20 @@ import yugecin.opsudance.movers.factories.MoverFactory; /** * Created by Alex Wieser on 10.10.2016. - * Best With Only one direction (Left or Right) */ public class CenterSpiralMoverFactory implements MoverFactory { - private static FakeGameObject middle = new FakeGameObject(); + private static FakeGameObject middle; + @Override + public Mover create(GameObject start, GameObject end, int dir) { + if (middle == null) + middle = new FakeGameObject(); + middle.setTime(start.getEndTime() + (end.getTime() - start.getEndTime()) / 2); + return new CombinedSpiralMover(middle, start, end, dir); + } - @Override - public Mover create(GameObject start, GameObject end, int dir) { - middle.setTime(start.getEndTime() + (end.getTime() - start.getEndTime()) / 2); - return new CombinedSpiralMover(middle, start, end, dir); - } - - @Override - public String toString() { - return "CentralSpiralSpin"; - } + @Override + public String toString() { + return "CentralSpiralSpin"; + } } diff --git a/src/awlex/ospu/movers/factories/CombinedSpiralMoverFactory.java b/src/awlex/ospu/movers/factories/CombinedSpiralMoverFactory.java deleted file mode 100644 index b5fedaa1..00000000 --- a/src/awlex/ospu/movers/factories/CombinedSpiralMoverFactory.java +++ /dev/null @@ -1,22 +0,0 @@ -package awlex.ospu.movers.factories; - -import awlex.ospu.movers.CombinedSpiralMover; -import itdelatrisu.opsu.objects.GameObject; -import yugecin.opsudance.movers.Mover; -import yugecin.opsudance.movers.factories.MoverFactory; - -/** - * Created by Alex Wieser on 26.10.2016. - */ -public class CombinedSpiralMoverFactory implements MoverFactory { - - @Override - public Mover create(GameObject start, GameObject end, int dir) { - return new CombinedSpiralMover(start, end, dir); - } - - @Override - public String toString() { - return "Spiral even more"; - } -} diff --git a/src/awlex/ospu/spinners/SpiralSpinner.java b/src/awlex/ospu/spinners/SpiralSpinner.java index 1371668b..41d5935a 100644 --- a/src/awlex/ospu/spinners/SpiralSpinner.java +++ b/src/awlex/ospu/spinners/SpiralSpinner.java @@ -10,84 +10,86 @@ import yugecin.opsudance.spinners.Spinner; */ public class SpiralSpinner extends Spinner { - /** - * How many points the Spinner uses. - * if there are not enough points the spinner looks angular. - * if there are too many points the spinner doesn't operate smooth - */ - private final int SIZE = 100; + /** + * How many points the Spinner uses. + * if there are not enough points the spinner looks angular. + * if there are too many points the spinner doesn't operate smooth + */ + private final int SIZE = 100; - /** - * The density of the spinner - * Determines how many times the spinner will around the center. - * if the value is to high the spinner will become angular. - * if this value goes under 2 the spinner won't be complete - */ - private final int DENSITY = 10; + /** + * The density of the spinner + * Determines how many times the spinner will around the center. + * if the value is to high the spinner will become angular. + * if this value goes under 2 the spinner won't be complete + */ + private final int DENSITY = 10; - /** - * How much the spinner will be rotated. - * Negative = clockwise - * Positive = counter clockwise - */ - private final double DELTA = -Math.PI / 20; - private int MAX_RAD; - private int index; - private double[][] points; - private boolean down; + /** + * How much the spinner will be rotated. + * Negative = clockwise + * Positive = counter clockwise + */ + private final double DELTA = -Math.PI / 20; + private int MAX_RAD; + private int index; + double[][] points; + boolean down; - @Override - public void init() { - points = new double[SIZE][]; - double ang; - double rad; - for (int i = 0; i < SIZE / 2; i++) { - MAX_RAD = (int) (Options.height * .35); - ang = (DENSITY * (Math.PI / SIZE) * i); - rad = (MAX_RAD / (SIZE / 2)) * i; - int offsetX = Options.width / 2; - int offsetY = Options.height / 2; - points[SIZE / 2 - 1 - i] = new double[]{ - offsetX + rad * Math.cos(ang), - offsetY + rad * Math.sin(ang) - }; - points[SIZE / 2 + i] = new double[]{ - offsetX + rad * (Math.cos(ang) * Math.cos(Math.PI) - Math.sin(ang) * Math.sin(Math.PI)), - offsetY + rad * -Math.sin(ang) - }; - } - } + @Override + public void init() { + points = new double[SIZE][]; + double ang; + double rad; + for (int i = 0; i < SIZE / 2; i++) { + MAX_RAD = (int) (Options.height * .35); + ang = (DENSITY * (Math.PI / SIZE) * i); + rad = (MAX_RAD / (SIZE / 2)) * i; + int offsetX = Options.width / 2; + int offsetY = Options.height / 2; + points[SIZE / 2 - 1 - i] = new double[]{ + offsetX + rad * Math.cos(ang), + offsetY + rad * Math.sin(ang) + }; + points[SIZE / 2 + i] = new double[]{ + offsetX + rad * (Math.cos(ang) * Math.cos(Math.PI) - Math.sin(ang) * Math.sin(Math.PI)), + offsetY + rad * -Math.sin(ang) + }; + } + } - @Override - public String toString() { - return "Spiralspinner"; - } + @Override + public String toString() { + return "Spiralspinner"; + } - @Override - public double[] getPoint() { - if (down) { - if (--index == 0) - down = !down; - } else if (++index == SIZE - 1) - down = !down; + @Override + public double[] getPoint() { + //if (waitForDelay()) { + if (down) { + if (--index == 0) + down = !down; + } else if (++index == SIZE - 1) + down = !down; - if (!down && index == 1) { - rotatePointAroundCenter(points[0], DELTA); - } else if (down && index == SIZE - 2) { - rotatePointAroundCenter(points[SIZE - 1], DELTA); - } - rotatePointAroundCenter(points[index], DELTA); - return points[index]; - } + if (!down && index == 1) { + rotatePointAroundCenter(points[0], DELTA); + } else if (down && index == SIZE - 2) { + rotatePointAroundCenter(points[SIZE - 1], DELTA); + } + //} + rotatePointAroundCenter(points[index], DELTA); + return points[index]; + } - private void rotatePointAroundCenter(double[] point, double beta) { - double angle = Math.atan2(point[1] - Options.height / 2, point[0] - Options.width / 2); - double rad = Utils.distance(point[0], point[1], Options.width / 2, Options.height / 2); + private void rotatePointAroundCenter(double[] point, double beta) { + double angle = Math.atan2(point[1] - Options.height / 2, point[0] - Options.width / 2); + double rad = Utils.distance(point[0], point[1], Options.width / 2, Options.height / 2); - //rotationMatrix - point[0] = Options.width / 2 + rad * (Math.cos(angle) * Math.cos(beta) - Math.sin(angle) * Math.sin(beta)); - point[1] = Options.height / 2 + rad * (Math.cos(angle) * Math.sin(beta) + Math.sin(angle) * Math.cos(beta)); - } + //rotationMatrix + point[0] = Options.width / 2 + rad * (Math.cos(angle) * Math.cos(beta) - Math.sin(angle) * Math.sin(beta)); + point[1] = Options.height / 2 + rad * (Math.cos(angle) * Math.sin(beta) + Math.sin(angle) * Math.cos(beta)); + } } diff --git a/src/yugecin/opsudance/ui/SBOverlay.java b/src/yugecin/opsudance/ui/SBOverlay.java index c8a34991..b26dde05 100644 --- a/src/yugecin/opsudance/ui/SBOverlay.java +++ b/src/yugecin/opsudance/ui/SBOverlay.java @@ -184,6 +184,8 @@ public class SBOverlay { public void setGameObjects(GameObject[] gameObjects) { if (this.gameObjects.length != gameObjects.length) { optionsMap = new HashMap[gameObjects.length]; + } + if (optionsMap.length > 0) { // copy all current settings in first obj map optionsMap[0] = new HashMap<>(); for (Options.GameOption o : options.getSavedOptionList()) {