diff --git a/src/awlex/ospu/FakeGameObject.java b/src/awlex/ospu/FakeGameObject.java index 7777baf9..f2ee29fc 100644 --- a/src/awlex/ospu/FakeGameObject.java +++ b/src/awlex/ospu/FakeGameObject.java @@ -27,13 +27,30 @@ public class FakeGameObject extends GameObject { } public FakeGameObject(GameObject start, GameObject end) { - halfTime = start.getEndTime() + (end.getTime() - start.getEndTime()) / 2; + halfTime = Math.abs(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) { @@ -53,17 +70,7 @@ 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() { @@ -98,8 +105,4 @@ 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 927c524d..f447cec8 100644 --- a/src/awlex/ospu/movers/CentralSpiralMover.java +++ b/src/awlex/ospu/movers/CentralSpiralMover.java @@ -1,46 +1,36 @@ 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 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"; - } +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; + } } diff --git a/src/awlex/ospu/movers/CombinedSpiralMover.java b/src/awlex/ospu/movers/CombinedSpiralMover.java index de0696d8..74938d73 100644 --- a/src/awlex/ospu/movers/CombinedSpiralMover.java +++ b/src/awlex/ospu/movers/CombinedSpiralMover.java @@ -4,6 +4,8 @@ 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; @@ -16,120 +18,100 @@ 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 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; - } +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 + }; + } + } diff --git a/src/awlex/ospu/movers/SpiralMover.java b/src/awlex/ospu/movers/SpiralMover.java new file mode 100644 index 00000000..6aa43195 --- /dev/null +++ b/src/awlex/ospu/movers/SpiralMover.java @@ -0,0 +1,55 @@ +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 179d132b..513253bf 100644 --- a/src/awlex/ospu/movers/SpiralToMover.java +++ b/src/awlex/ospu/movers/SpiralToMover.java @@ -1,46 +1,36 @@ 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 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"; - } +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; + } } diff --git a/src/awlex/ospu/movers/factories/CenterSpiralMoverFactory.java b/src/awlex/ospu/movers/factories/CenterSpiralMoverFactory.java index 46e90730..d2fd7991 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; - @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); - } + private static FakeGameObject middle = new FakeGameObject(); - @Override - public String toString() { - return "CentralSpiralSpin"; - } + @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"; + } } diff --git a/src/awlex/ospu/movers/factories/CombinedSpiralMoverFactory.java b/src/awlex/ospu/movers/factories/CombinedSpiralMoverFactory.java new file mode 100644 index 00000000..b5fedaa1 --- /dev/null +++ b/src/awlex/ospu/movers/factories/CombinedSpiralMoverFactory.java @@ -0,0 +1,22 @@ +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 41d5935a..1371668b 100644 --- a/src/awlex/ospu/spinners/SpiralSpinner.java +++ b/src/awlex/ospu/spinners/SpiralSpinner.java @@ -10,86 +10,84 @@ 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; - double[][] points; - 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; + private double[][] points; + private 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 (waitForDelay()) { - if (down) { - if (--index == 0) - down = !down; - } else if (++index == SIZE - 1) - down = !down; + @Override + public double[] getPoint() { + 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)); + } }